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.

o0 '.
fuente
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.

Niall C.
fuente
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
Nick Pierpoint
fuente
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  <[email protected]>
date:        Mon Jun 09 02:24:23 2014 +0200
summary:     commit description #3

changeset:   123:91c5402959z3
user:        Your name <[email protected]>
date:        Sat Dec 23 16:05:38 2013 +0200
summary:     commit description #2

changeset:   59:81b9804156a8
user:        Your name <[email protected]>
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.

Artur Barseghyan
fuente
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

msarchet
fuente
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.

jjst
fuente
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.

UuDdLrLrSs
fuente
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.

Faheem Mitha
fuente
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
kjam
fuente
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.

sonjz
fuente
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