2012-07-23 17 views
6

Tengo un montón de commits, digamos A, B, C, D, y quiero mantener B, C y D, y hacer un commit que sea (BCD) ⁻¹. ¿Cuál es la forma más fácil de hacer esto, si tengo muchas confirmaciones que deseo deshacer al mismo tiempo?¿Cómo puedo revertir varias confirmaciones en Mercurial?

(me parece recordar viendo una pregunta StackOverflow sobre esto que me sugirió que hg update a A, y luego llamar a hg commit con algunos argumentos, pero me parece que no puede encontrar esa pregunta ahora.)

Respuesta

1

Usted' ha respondido su propia pregunta, actualice nuevamente a A y continúe desde allí. Si necesita crear una nueva cabecera en ese punto, deberá realizar un cambio en algún archivo u otro como se describe aquí: How can I force mercurial to accept an empty commit. Un mail thread vinculado desde esa publicación describe una forma de usar MqExtension para eliminar BCD (a menos que los haya insertado):

+0

Esto, pero solo si D es una CABEZA. No hay recolección de basura en hg, por lo que B, C y D no se perderán. D seguirá siendo una CABEZA que puedes empujar o no, depende de ti. – DanMan

4

Parece que está buscando backout. Ver:

hg help backout 

no creo que pueda retirarse múltiples confirmaciones de una sola vez, así que hay que apoyarlos de forma individual:

hg backout D 
hg backout C 
hg backout B 

Esto creará tres confirmaciones en la parte superior de la D que son al revés de D, y C, y B. Si desea combinar estos commits en un solo conjunto de cambios, puede doblarlos usando rebase --collapse o una de una serie de otras extensiones (por ejemplo, las extensiones histedit o mq o collapse).

Si no desea realizar una copia a cabo los cambios individuales, sino hacerlo de una sola vez, se puede hacer lo siguiente:

hg update A 
hg debugsetparents D 
hg commit -m "revert B-D" 

Es feo, pero funciona. Sin embargo, esto no registra el cambio de nombre en reversa. Sin embargo, para ser sincero, no recomendaría hacer esto, si necesitas dar marcha atrás tanto que los comandos de retroceso individuales son demasiado problemáticos para escribirlo, me pregunto si retroceder es lo que realmente deberías estar haciendo para ese particular caso.

Alternativamente, podría hacer lo que Jim y Rafael sugirieron, y decidir que B, C y D están en una rama, actualizar a A y continuar cometiendo allí (dividiendo el historial en ese punto). Esto puede ser más apropiado.

+0

Esto hará lo que yo quiera (si aplasto los tres commits juntos en mq), pero se volverá difícil si hay, digamos, 50 commits que deseo deshacer. Estoy buscando algo más cercano a la segunda parte de la respuesta aceptada en http://stackoverflow.com/questions/1463340/revert-multiple-git-commits (pero para hg), es decir, el equivalente hg de 'git reset --hard A && git reset --soft @ {1} && git commit -a ' –

+0

Actualicé la respuesta con una forma de hacerlo en Mercurial. Sin embargo, al igual que la respuesta git a la que se vinculó, en realidad no revierte los conjuntos de cambios. Realmente me hace preguntarme por qué querrías revertir una secuencia tan grande de conjuntos de cambios. Parece mejor simplemente colocarlos en una sucursal inactiva, y continuar desde el cambio anterior a eso. Si describe un poco su caso de uso en su pregunta, puede ayudar a darle una mejor solución a su problema. –

+0

Además, es posible que desee considerar enviar una solicitud de función a Mercurial para que el comando de retroceso acepte un conjunto de revisiones en lugar de solo revisiones únicas. –

4

La forma más sencilla:

Estas en conjunto de cambios D y desea terminar esa rama

hg commit --close-branch -m "Branch closed" 

Ahora, sólo tiene que ir al conjunto de cambios A y continuar con su trabajo commiting cosas nuevas

hg up -r A 
... change stuff ... 
hg ci -m "New stuff" 

La rama que tiene B, C y D estará allí, pero se terminará, no se mostrará en hg heads. Será una rama inactiva.

Eso es fácil de hacer y expresivo también. Si miras el gráfico, verás una rama separada que se cerró y la rama "oficial" continuará. Mucho mejor que tener esos conjuntos de reversión y retroceso haciendo ruido en su sucursal.

+1

Como se explica en [otra pregunta] (http://stackoverflow.com/questions/3688263/mercurial-beheading- a-head), cuando intenta empujar la cabeza cerrada a otro repositorio, recibirá una advertencia sobre la creación de varias cabezas. Entonces, usa 'hg push --force' la primera vez que presionas. Las personas que tiran de la cabeza cerrada no recibirán ninguna advertencia. – mernst

Cuestiones relacionadas