2009-05-12 9 views
55

Digamos que hice muchos cambios en mi código y solo necesito confirmar algunos de esos cambios. ¿Hay alguna manera de hacerlo en mercurial? Sé que darcs tiene una función como esta.Cambios Mercurial Cherry Picking para commit

Sé que hg transplant puede hacer esto entre ramas, pero necesito algo como esto para confirmar el código en la rama actual y no cuando agregue conjuntos de cambios desde alguna otra rama.

+2

Hace poco pedí esto como un duplicado. No conocía la terminología, así que no encontré esto cuando busqué. Ver la respuesta aceptada en mi pregunta que implica hg injerto, nuevo en Mercurial 2.0. http://stackoverflow.com/questions/10288482/workflow-to-backport-change-into-different-mercucial-branch – oob

Respuesta

33

MQ como Chad se menciona son de una manera. También hay soluciones más livianas:

  • Record extension que funciona aproximadamente de la misma manera que el registro de darcs. Se distribuye con mercurial.
  • Shelve extension que le permite "dejar de lado" ciertos cambios, lo que le permite comprometerse sólo un subconjunto de los cambios (los que no son dejados de lado)
+0

ver información adicional en esta respuesta: http://stackoverflow.com/a/7768682/411282 –

3

Creo que Mercurial Queues cumple esta función para Mercurial. Hay a pretty good tutorial vinculado allí.

+0

Esto parece hacer lo que quiero, sin embargo hubiera sido genial si el proceso fuera más interactivo como el hg trasplante comando. – mansu

16

El tutorial Colas de Mercurial es terrible para este caso de uso. Todos los ejemplos que he visto suponen que todavía tiene que hacer una confirmación y está actualizando un solo parche. La mayoría de las veces este no es el caso, y usted tiene 2 o 3 commits que desea aplastar juntos o cambiar de alguna otra manera.

Digamos que tiene este tipo de historia:

---O---O---A---B---C 

El primer ejemplo es que la calabaza se compromete A, B y C. En primer lugar mq init:

$ hg qinit 

Ahora necesitamos " importe "commits A, B y C en la cola de parches. Supongamos que son los últimos 3 commits. Podemos utilizar la sintaxis "N" revisión de importarlos de este modo:

$ hg qimport -r -3:-1 

Eso significa importación como parches de 3 parches de nuevo hasta la última confirmación. Puede verificar el estado de estos parches con hg qseries. Debe mostrar algo como esto:

$ hg qseries 
101.diff 
102.diff 
103.diff 

donde los números 101, 102 y 103 corresponden a los números de revisión locales de los commit A, B y C. Ahora bien, estos parches son aplica, lo que significa que los cambios ellos describen ya están en la copia de trabajo. Puede deshacerse de los cambios de la copia de trabajo y eliminarlos del historial de confirmaciones, guardándolos solo en forma de parche, utilizando hg qpop. Puede decir hg qpop; hg qpop para sacar los cambios C y B de la pila, o especificar un parche para "pop to". En este caso, sería algo como esto:

$ hg qpop 101.diff 
now at: 101.diff 

Ahora tiene los parches para las confirmaciones B y C en la cola de parche, pero no se aplican (los cambios se han "perdido" - que sólo existen en el área de la cola de parches). Ahora puede plegar estos parches en el último, es decir, creamos un nuevo compromiso que es el equivalente a la suma de los cambios A + B + C.

$ hg qfold -e 102.diff 103.diff 

Esto mostrará su editor para que pueda cambiar el mensaje de confirmación.Por defecto, el mensaje será la concatenación de los mensajes de confirmación para los cambios A, B y C, separados por asteriscos. Lo bueno aquí es que hg qfold completará con pestañas los parches si está utilizando bash y tiene el script hg-completion sourced. Esto deja a la historia como esta, en la que A + B + C es una única confirmación de que es la combinación de los 3 parches que nos interesan:

---O---O---A+B+C 

Otro caso de uso es si tenemos el mismo tipo de historia como antes , pero queremos dejar el parche B y fusionar A + C. Esto es bastante similar a lo de arriba en realidad. Cuando se llega a la etapa de qfold, sólo tendría que doblar por la última confirmación en lugar de los 2 últimos se compromete:

$ hg qfold -e 103.diff 

Esto deja el cambio para B en la cola de parches, pero no se aplica a la copia de trabajo y su compromiso no está en la historia. Se puede ver esto ejecutando:

$ hg qunapplied 
102.diff 

La historia ahora se ve así, en la que A + C es una única confirmación que combina cambios A y C:

---O---O---A+C 

Un caso de uso final podría ser que es necesario aplicar solamente cometer C. se podría hacer esto mediante la ejecución del qimport que el anterior, y que le sobresalen de todos los parches que no quería:

$ hg qpop -a 

el medio indicador -a sobresalen de todos los parches. Ahora puede aplicar solamente desde el que quieres:

$ hg qpush 103.diff 

Esto le deja con esta historia:

---O---O---C 

Una vez que haya terminado con todo esto, es necesario acabar con el trasteo cola. Esto se puede hacer con:

$ hg qfinish -a 

Así que ahí estamos. Ahora puede ejecutar hg push y solo cometer exactamente lo que quiere, o hg email un parche coherente a la lista de correo.

+0

Muy buena publicación, gracias! – jv42

2

Pruebe qct (Qt Commit Tool). Tiene una función de "seleccionar cambios" que inicia una herramienta de combinación de 3 vías para deshacer cambios individuales. Después de comprometerte, esos cambios que "deshiciste" vuelven.

+0

No lo sabía. Gracias. – mansu

36

Si está usando TortoiseHg 1.x para Windows, this feature is implemented beautifully nada más sacarlo de la caja (no se requieren extensiones).

  1. Ejecute la herramienta TortoiseHg Commit.
  2. Elija un archivo para el cual solo desea confirmar un subconjunto de sus cambios .
  3. Haga clic en la ficha Selección de Hunk en el panel de vista previa.
  4. Haga doble clic o use la barra espaciadora en alternar qué cambio debe ser incluido en la confirmación.

Para TortoiseHg 2.x, la pestaña del trozo de selección se ha ido. En su lugar, es el Shelve tool. Tiene algunas características más que la antigua selección de trozos. Esas nuevas características tienen el costo de una complejidad adicional.

enter image description here

Tenga en cuenta que no hay necesidad de activar de forma explícita la extensión Mercurial deja de lado al utilizar esta función. Según Steve Borho (desarrollador principal de TortoiseHg) en response to a different TortoiseHg question: "Tenemos una copia local de la extensión de estantería y llamamos directamente a ella".


Para TortoiseHg 2.7+, esta funcionalidad se ha mejorado y re-introducido. En la actualidad se construye directamente en la herramienta Commit:

example of change selection in the commit tool

se comprueba Aviso en la lista de archivos en el que el archivo de la parte superior izquierda para indicar que se incluirá, el segundo archivo no está marcada, ya que no será incluido, y el tercer archivo, Sample.txt, está lleno (el indicador de casilla de verificación Nulo) porque solo se incluirán cambios seleccionados de ese archivo en la confirmación.

El cambio a Sample.txt que se incluirá se verifica en la parte inferior derecha de la selección de cambios de la imagen. El cambio que se excluirá no está marcado y la vista de diferencia está atenuada. También observe que el ícono para la herramienta de archivado aún está disponible.

+1

Aha, así que es por eso que no entendí por qué esto era una pregunta. Esto no se hace fácilmente si no estás usando TortoiseHg. No lo sabía. –

+0

¿Qué pasa con aquellos de nosotros que estamos usando la versión 2? http://tortoisehg.bitbucket.org/manual/2.0/commit.html no tiene una pestaña de selección de trozos que pueda ver. – alsuren

+0

@alsuren: Ver respuesta actualizada para TortoiseHg versión 2.x – mwolfe02

2

Yo uso commit-patch. Es un script que te permite editar el diff antes de cometerlo. Es realmente agradable con diff-mode y vc-mode de Emacs.

En el pasado usé crecord, pero tiene errores relacionados con Unicode (en realidad, la extensión de registro tiene los errores, de los que depende crecord).

15

Siento que me falta algo porque nadie ha sugerido esto ya.

El comando normal "hg commit" se puede usar para elegir selectivamente lo que se va a comprometer (no es necesario que se comprometan todos los cambios pendientes en el directorio de trabajo local).

Si usted tiene un conjunto de cambios de este modo:

M ext-web/docroot/WEB-INF/liferay-display.xml 
M ext-web/docroot/WEB-INF/liferay-portlet-ext.xml 
M ext-web/docroot/WEB-INF/portlet-ext.xml 

puede comprometerse sólo dos de esos cambios con ...

hg commit -m "partial commit of working dir changes" ext-web/docroot/WEB-INF/liferay-display.xml ext-web/docroot/WEB-INF/liferay-portlet-ext.xml 

No es muy conveniente desde la línea de comandos porque tiene para escribir a mano los archivos para confirmar selectivamente (frente a un proceso de casilla de verificación de la GUI como la tortuga) pero es lo más sencillo posible y no requiere extensiones. Y el agrupamiento de archivos probablemente pueda ayudar a reducir el tipeo (como ocurriría anteriormente, ambos archivos comprometidos comparten "liferay" de forma única en sus rutas.

+6

Muchas de las otras respuestas se refieren solo a los cambios seleccionados dentro de cada archivo (aunque no está claro si esto es necesario a partir de la pregunta, por lo tanto, tener un voto positivo) –

7

Puede usar el record extension, que se distribuye con Mercurial.

es necesario tener en su archivo ~/.hgrc en primer lugar, mediante la adición a la sección [extensions]:

[extensions] 
record= 

A continuación, sólo tiene que escribir hg record en lugar de hg commit, y usted será capaz de seleccionar lo que cambia al cual archivos que quieres comprometer

También puede usar el crecord extension que proporciona una interfaz más agradable para revisar y seleccionar los cambios. (No se distribuye con Mercurial, y lo he visto ocasionalmente estropear una confirmación por lo que no está completamente libre de errores.)

+1

crecord tiene una ventaja sobre el registro ya que puede seleccionar * partes * de un pedazo. Y la interfaz es mucho más agradable también: D –

+1

Página de extensión de registro dice * Esta extensión está en desuso, la función ahora es parte del núcleo de Mercurial como hg commit --interactive *. Ver [esta respuesta] (http://stackoverflow.com/a/7768682/2072035). – saaj

-1

Primero debe olvidar todo lo que sabía sobre GUI y regresar a la línea de comandos. A continuación de la línea de comandos hacer esto:

stat hg> filelist.txt

Este tuberías de todos los archivos modificados en un archivo de texto llamado filelist.txt

próxima edición de su lista de archivos para incluir sólo los archivos deseas comprometerte

Finalmente se comprometen con el conjunto de archivos sytnax:

cometer hg "set: 'listfile: test.txt'"

3

ha pasado algún tiempo. Parece que la mejor opción ahora es hg commit --interactive

Cuestiones relacionadas