2009-11-03 18 views
66

En Mercurial/TortoiseHg, dado el siguiente ejemplo, ¿cuál es la forma más fácil de combinar la revisión "G" en el repositorio A sin tomar D, E y F (suponiendo que G no tiene dependencia de D, E o F).¿Cómo selecciono una única revisión en Mercurial?

Repo A: A - B - C 

Repo B (Clone of A) A - B - C - D - E - F - G 

¿Es un parche la mejor apuesta?

+32

No es fusionar en realidad cherry picking, la mejor herramienta para eso es que creo trasplante. Pero el parche también funcionaría. – tonfa

+9

tonfa, debe hacer que sus comentarios respondan. Siempre tienes la razón y nadie puede votarte. –

+5

@ Ry4n a veces no tengo tiempo, no me importa no estar upvoted si ayuda a la siguiente persona para responder :) – tonfa

Respuesta

74

Tonfa tiene razón. Lo que estás describiendo no es 'fusionar' (o 'empujar' o 'tirar'); es 'cherry-picking'. Un push o un pull mueve todos los conjuntos de cambios de un repositorio a otro que aún no están en ese repositorio. Una 'fusión' toma dos 'cabezas' y las combina con un nuevo conjunto de cambios que es la combinación de ambos.

Si realmente necesita mover G pero no puede soportar tener D, E, F, debe 'exportar' G del repositorio A, y luego 'hg importarlo' en el repositorio A. El Transplant extension es un contenedor alrededor de exportación/importación con algunas sutilezas para ayudar a evitar mover el mismo conjunto de cambios varias veces.

Sin embargo, el inconveniente de utilizar la importación/exportación, trasplante, y la cereza-cosecha, en general, es que realmente no se puede mover más de G sin sus antepasados, porque en Mercurial el nombre de un conjunto de cambios es su 'Hashid 'que incluye los hashidos de sus padres. Diferentes padres (el nuevo padre de G sería C y no F) significa un hashid diferente, por lo que ya no es G; es el trabajo de G pero un nuevo conjunto de cambios por su nombre.

Moverse sobre G como algo nuevo, llamémosle G '(Gee prime), no es un gran problema para algunos usos, pero para otros es una gran pita. Cuando pronto repo B obtenga un nuevo conjunto de cambios, H, y quiera moverlo sobre su padre, cambiará de G a G ', que tienen hashes diferentes. Eso significa que H se moverá como H '- 100 conjuntos de cambios en la línea y tendrá diferentes hashids para todo porque no podría soportar tener D, E, F en el repositorio A.

Las cosas se igualarán más fuera de control si/cuando quieres mover cosas del Repo A al Repo B (la dirección opuesta a tu movimiento anterior). Si intenta hacer un simple 'hg push' desde A hasta B, obtendrá G '(y H' y descendientes posteriores) que serán duplicados de los conjuntos de cambios que ya tiene en Repo B.

¿Qué ocurre entonces? , son tus opciones?

  1. Do not care. Sus datos aún están allí, acaba con los mismos conjuntos de cambios con diferentes nombres y más trabajo en futuros intercambios entre los dos repositorios. No está mal, es un poco torpe tal vez, y a algunas personas no les importa.
  2. Mueva todos los D, E y F a Repo A. Puede mover todos los conjuntos de cambios si son inofensivos y evitar todas las molestias. Si no son tan inofensivos, puede moverlos y luego hacer un 'retroceso hg' para deshacer los efectos de D, E y F en un nuevo conjunto de cambios H.
  3. Para empezar, G le da un mejor parentesco. Es malo para mí mencionar esto porque es demasiado tarde para seguir esta ruta (sin editing history). Lo que debería haber hecho antes de trabajar en el conjunto de cambios G era hg update C. Si G no confía ni requiere conjuntos de cambios D, E y F, entonces no debería ser su hijo.

Si en lugar de actualizar a C primero que tendrá un gráfico como este:

A - B - C - D - E - F 
      \ 
      G 

a continuación, toda la respuesta a esta pregunta sería más que hg push -r G ../repoA y G se movería más limpia, manteniendo su mismo hashid, y D, E y F no irían con eso.

ACTUALIZACIÓN:

Como se señaló en los comentarios. Con los Mercuriales modernos, el comando hg graft es la manera perfecta de hacerlo.

+2

En realidad, supongo que la extensión 'rebase' funcionaría. –

+4

Usar rebase es una forma de 'historial de edición'. Cambia los hashids, que si aún no los has lanzado al mundo es absolutamente genial. Si lo ha hecho entonces todo el mundo va a ver los mismos conjuntos de cambios dos veces y etc. –

+7

me gustaría señalar que desde Mercurial 2.0, el injerto se debe utilizar en lugar de trasplante siempre que sea posible, ya que utiliza la maquinaria de fusión interna en lugar de rechazar los conflictos. Ver también http://stackoverflow.com/a/8010738/67988. – Helgi

36

Refiriéndose al título, que se ocupa de cherry picking en general, me dan el ejemplo de trabajo en una cesión temporal, como los motores de búsqueda en Internet podría llevar a la gente aquí para cherry picking en general. Trabajar en un repositorio, se haría con hg graft:

hg update C 
hg graft G 

El resultado es:

  G' 
     /
A - B - C - D - E - F - G 

advertencia adicional: Los dos conjuntos de cambios serán tratados como confirmaciones independientes, paralelos en los mismos archivos y podría hacer que se encuentre con conflictos de fusión, que es la razón por la cual se debe evitar la selección de cerezas en general para la administración de la sucursal. Por ejemplo, si G es una corrección de errores aplicado a una rama versión estable marcada como 1.0.1, usted debe en lugar de combinación la rama freeze con ella, y de vez en cuando fusionar la rama master con corrección de errores del freeze de sucursales.

+0

'hg injerto G' trae en muchos de los cambios en D, E y F. exportación parche, parche funciona de importación como uno esperaría de injerto funcione. – LovesTha

+0

'hg injerto G' en C crea una nueva cabeza/rama. ¿Por qué crees que puede traer algún cambio en la rama D ... G? – Iodnas

Cuestiones relacionadas