Abandonar cambios sin borrar del historial


180

Hay una confirmación que simplemente no funcionó, por lo que quiero abandonarla sin eliminarla de la historia .

He actualizado desde una revisión anterior y me he comprometido, creando así una nueva cabeza.


No tengo sucursales, no quiero sucursales, solo quiero seguir con la nueva cabeza exactamente como está, nada lujoso, sin fusión, sin preocupaciones, simplemente olvidando la anterior.

Parece que no puedo encontrar cómo hacer eso, y estoy empezando a creer que no se puede hacer. Todo lo que encuentro es cosas sobre ramas, o cosas sobre fusión.


1
Está en su repositorio, por lo que no se ha eliminado del historial. Ha creado una nueva cabeza, por lo que puede continuar haciendo revisiones sin el error. ¿Qué te impide seguir con la nueva cabeza?
ataylor

¿Qué pasa con tu aversión a las ramas?
Andres Jaan Tack

@ Andreas No es exactamente aversión a las ramas. Solo necesitaba que funcionara sin un estúpido paso adicional de crear uno solo para cerrarlo.
o0 '.

Cualquiera que lea: tenga en cuenta que ya se ha creado una rama en este escenario; tenga en cuenta la explicación dada en esta respuesta: stackoverflow.com/a/3692607/3195477
UuDdLrLrSs

Respuestas:


181

Actualice su repositorio a la cabeza con la revisión que desea olvidar, luego use hg commit --close-branchpara marcar esa rama (anónima) como cerrada. A continuación, actualice a la cabeza de la rama que no quiere, y seguir trabajando.

Aún puede ver la rama cerrada si usa la -copción hg heads, pero no se mostrará de manera predeterminada y hg mergesabrá que no intentará fusionarse con la cabeza cerrada.

Tendrá que usar hg push --forcela primera vez que empuje este cabezal cerrado a otro repositorio ya que en realidad está creando cabezales adicionales en el repositorio remoto cuando empuja. Entonces dile a Mercurial que esto está bien --force. Las personas que tiran de la cabeza cerrada no se molestarán por ninguna advertencia.


3
@Niall C. ¿no funcionará eso solo si lo ha marcado como una rama con nombre? Supongo por lo que dice que hizo que está en incumplimiento
msarchet

pero ... eso no es cierto, todavía tengo ambas cabezas en la lista cuando llamo hg heads... Estoy usando mercurial 1.4.3, ¿es una característica más nueva?
o0 '.

2
@msarchet: AFAIK, probándolo hoy, --close-branch NO funciona para ramas anónimas. Debería, pero no lo hace. Espero que esto cambie en alguna versión futura de Mercurial. Las ramas anónimas son muy agradables, pero deberían ser tan de primera clase como las ramas con nombre.
Krazy Glew

44
@KrazyGlew: El problema es que una rama "anónima" es realmente una segunda rama con el mismo nombre que la rama en la que se basó. Realmente no estás tratando de cerrar la rama (con nombre): estás tratando de descartar los cambios que has estado haciendo. En otras palabras, hg branchesaún debe mostrar el nombre de la sucursal en la que está. En lugar de intentar cerrar la rama, combine su rama anónima de nuevo en la rama original, descartando todos los cambios.
StriplingWarrior

2
En mi caso, tengo una rama llamada default (esto es estándar) y otra llamada default / master (creo que debido al hecho de que el depósito remoto es realmente git). actualización de hg predeterminada / maestra; hg commit --close-branch; La actualización predeterminada de hg funcionó para mí.
MattD

68

Sé que no quieres trabajar con sucursales en esta etapa, pero eso es exactamente lo que has hecho. Cuando volviste a una versión anterior y cometiste algo que funcionó, creaste una rama, una rama sin nombre, pero una rama de todos modos.


No hay problema con continuar como está y no preocuparse por tener varias cabezas, pero si desea ordenar las cosas para no recoger accidentalmente la cabeza equivocada una vez, puede matar la rama vieja.

Hay una buena sección en la documentación de Mercurial que lo lleva a través de una serie de opciones en torno a Podar ramas muertas .

Creo que la mejor opción para usted es marcar la rama anterior como "cerrada". Si su antigua cabeza es la revisión "123", entonces:

hg update -r 123
hg commit --close-branch -m 'Closing old branch'
hg update -C default

3
Blurgh: acabo de ver la respuesta de @ Niall después de haber entrado. Votará a favor de Niall y el mío puede languidecer en el grupo de puntos cero. :)
Nick Pierpoint

1
Me gusta su respuesta mejor, se requiere menos groking de la terminología de merucrial (que lo más cerca que puedo decir parece ser escogido para confundir a los usuarios TGI)
tacaswell

8
jajaja es todo lo contrario! La terminología de mercurial fue elegida para que suene natural para los usuarios de svn, mientras que la de git es confusa como el infierno. de todos modos, votando esta respuesta porque incluye la última actualización -C
Tobia

2
¿Por qué necesita -Cen hg update? Parece que ningún archivo se habría modificado, por lo que debería funcionar sin él.
máximo

1
Por lo que puedo decir, no necesitas un -C en ningún lado. sin embargo, si tiene cambios pendientes cuando intenta actualizar, obtendrá un aborto.
Eli Albert

21

En primer lugar, escriba:

hg heads

Imagina, tienes tres cabezas en la lista:

changeset:   223:d1c3deae6297
user:        Your name  <your@email.com>
date:        Mon Jun 09 02:24:23 2014 +0200
summary:     commit description #3

changeset:   123:91c5402959z3
user:        Your name <your@email.com>
date:        Sat Dec 23 16:05:38 2013 +0200
summary:     commit description #2

changeset:   59:81b9804156a8
user:        Your name <your@email.com>
date:        Sat Sep 14 13:14:40 2013 +0200
summary:     commit description #1

Digamos que desea mantener activa la última cabeza (223) y cerrar el resto.

Entonces harías lo siguiente:

Cerrar la cabeza # 59

hg up -r 59
hg ci --close-branch -m "clean up heads; approach abandoned"

Cerrar la cabeza # 123

hg up -r 123
hg ci --close-branch -m "clean up heads; approach abandoned"

Cometer los cambios

hg push

No olvides cambiar a la cabeza derecha al final

hg up -r 223

Y tu estas listo.


Este es un buen tutorial, pero los mensajes de confirmación de ejemplo son un poco meta. Incluiría mejores ejemplos para que aquellos que aprenden de usted puedan proporcionar mejores mensajes de confirmación. Algo así como --close-branch -m "Closing branch - technique #2 abandoned in favor of technique #3".
Jason R. Coombs

55
Además, habrá terminado al final, excepto que su copia de trabajo todavía está en la cabeza que acaba de cerrar. Cometer otro cambio sucedería en la cabeza cerrada, reabrirlo. Querrás hacerlo hg up -r 223antes de hacer cualquier cambio.
Jason R. Coombs

@Jason R. Coombs: ¡Correcto!
Artur Barseghyan

De acuerdo con @Niall, y mi propia experiencia en este momento, necesitará hg push --force, no solo hg pushpara superar la advertencia sobre empujar varias cabezas.
craq

1
@Artur Estoy de acuerdo en general. En este caso, hg pushpor sí solo no funcionó para mí. ¿Cómo recomienda empujar los cambios a un repositorio externo si se niega debido a múltiples cabezas?
craq

12

Que desea utilizar hg backout. Esto elimina los cambios realizados por el conjunto de cambios de cualquier conjunto de cambios secundario.

Mira esto para una buena explicación. Retroceso mercurial


2
Esta es exactamente la respuesta correcta. Backout agrega el inverso de un conjunto de cambios, deshace el trabajo y le da un mensaje de confirmación para recordar por qué no le gustó la idea.
Ry4an Brase

77
De hecho, no estoy de acuerdo: abandonar el trabajo con una sola cabeza y comenzar de nuevo desde un buen punto de partida parece un patrón de trabajo más limpio que usar retrocesos. Especialmente porque no puede anular más de un conjunto de cambios a la vez.
Martin Geisler

1
@ Martin Geisler, así estoy de acuerdo con esto en general, pero el PO indiqué que quería abandonar los cambios sin ramas
msarchet

2
@Martin Geisler, sí, estoy a favor de ramificar, solo a veces atacar un mal cambio es lo mejor
msarchet

1
A veces puede ser útil, pero eso no era realmente lo que quería. Gracias de todos modos :)
o0 '.

2

Las respuestas de Niall y Nick son directas. Como me encuentro creando muchas cabezas colgantes, terminé escribiendo un alias para cerrar las cabezas más fácilmente. Al agregar esto a su .hgrc:

[alias]
behead = !REV=$($HG id -i); $HG update $@ -q && $HG ci --close-branch -m "Closing dead head" && $HG update $REV -q

(si ya tiene una [alias]sección, puede agregarla en su lugar)

Ahora puede cerrar una cabeza en un solo comando (y sin tener que actualizar manualmente a un conjunto de cambios diferente) de esta manera:

$ hg behead 123

Nota: el alias aprovecha el hecho de que los alias Mercuriales pueden ser comandos de shell . Esto significa que esto probablemente solo funcionará en UNIX, no en Windows.


2

Una alternativa para cerrar o despojar la rama no deseada sería fusionarla de una manera que descarte totalmente sus efectos, pero la deje en la historia. Este enfoque permitirá que esos cambios no deseados se propaguen en un impulso, así que solo use esto si ese es el efecto deseado.

Digamos que el historial del conjunto de cambios se ve así:

1-2-3-4-5-6    
       \    
        7-8-*

y es 5y 6que ya no se quieren.

Puedes hacerlo:

hg up 8
hg merge -r 6 -t :local
hg commit ...

que creará esto:

1-2-3-4-5-6    
       \   \
        7-8-9-*

La actualización 8asegura que está trabajando en la cabeza deseada en la historia, que desea mantener.

El le -t :localindica a hg que use la "herramienta" de fusión llamada local que le dice que ignore los cambios de la otra rama, es decir, la que NO está representada por el estado actual de la carpeta de trabajo. Más información .

Por lo tanto, los cambios no deseados 5y 6se conservan en la historia, pero no afectan a nada más reciente.


2

Este es un caso de uso para la extensión Evolve . Actualmente no está incluido con Mercurial, por lo que técnicamente es una extensión de terceros. Pero está siendo muy utilizado por muchas personas, incluidos los desarrolladores de Mercurial, se está desarrollando de manera muy activa y no va a ninguna parte.

Con la extensión Evolve, simplemente lo haces

hg prune -r revname

y sigue con tu vida. El cset todavía estará allí, pero obsoleto. No será visible a menos que pase la --hiddenopción a los comandos de Mercurial, y por defecto no se enviará a repositorios remotos. Aunque creo que puedes forzarlo si realmente quieres.

Si el cset que está podando tiene ancestros que desea conservar, entonces deberá ejecutar hg evolvepara volver a crear los conjuntos de cambios. hg evolvelo hará de forma automática. De lo contrario, no tienes que hacer nada.


1

Puede clonar su repositorio corrupto en uno nuevo sin clonar esa cabeza no deseada. Luego, elimine el repositorio antiguo, mueva el clon recién creado al lugar original y continúe trabajando con él. Esto llevará algún tiempo, pero obtendrá un repositorio perfectamente limpio sin una señal de esa revisión no deseada.

hg clone --rev myGoodResition myDirtyRepo myCleanRepo

1
Esto no es totalmente lo que pregunté, lo siento.
o0 '.

44
@ Kristof: ¿es una broma? Vuelva a leer la primera línea de mi publicación: "abandónelo sin eliminarlo del historial "
o0 '.

-1

Me he encontrado con este problema muchas veces cuando quiero decapitar una cabeza que se creó por error. Siempre quiero verlo desaparecer de la faz de la Tierra.

En su copia local, obtenga la última versión y luego:

  1. Encuentre el comienzo de una cabeza que desea quitar (donde un nuevo cuello comienza a ramificarse), obtenga el número de revisión

  2. Desnúdalo.


Fuente: TipsAndTricks .

Fuente: PruningDeadBranches # Using_strip .

hg --config extensions.hgext.mq= strip -n <rev>
  1. Realice una actualización trivial del archivo (agregue un espacio en blanco a un archivo), confirme y presione.

Su repositorio ahora debería tener la cabeza desnuda. El último paso es importante ya que la eliminación no crea ningún cambio que pueda empujar a su repositorio central. Sin el último paso, solo ha despojado la cabeza localmente.


1
Pero, presionar nunca elimina nada del repositorio remoto. Solo agrega información alguna vez . Si el conjunto de cambios ya está en el repositorio central, debe usar la extensión evolve o, de alguna manera, eliminarla en el servidor central. Si el conjunto de cambios aún no se encuentra en el repositorio central, bastará con quitarlo localmente sin necesidad de ningún empuje.
Ben
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.