¿Hay alguna forma de eliminar confirmaciones locales en Mercurial?


209

Así que sigo cometiendo un error tonto en Mercurial. Muchas veces, empiezo a trabajar sin hacer un "hg pull" y una "actualización hg". Cuando trato de impulsar mis cambios, aparece un error.

¿Hay alguna forma de eliminar mis confirmaciones locales para evitar crear múltiples encabezados, ramas, etc.? Solo quiero eliminar mis confirmaciones locales, fusionar mis cambios con la sugerencia y luego volver a confirmar. Suena simple, ¿verdad? Parece que no puedo encontrar ninguna manera de eliminar fácilmente las confirmaciones locales, así que puedo fusionarme limpiamente con la sugerencia.

Una vez más, solo estoy tratando de eliminar las confirmaciones locales realizadas con "hg ci". No quiero modificar archivos, revertir, etc.



12
No es un error tonto, es un flujo de trabajo normal cuando varias personas trabajan con el mismo repositorio simultáneamente.
Juozas Kontvainis

Respuestas:


247

Habilite la extensión " strip " y escriba lo siguiente:

hg strip #changeset# --keep

¿Dónde #changeset#está el hash para el conjunto de cambios que desea eliminar? Esto eliminará dicho conjunto de cambios, incluidos los conjuntos de cambios que descienden de él, y dejará intacto su directorio de trabajo . Si desea revertir también los cambios de código comprometidos, elimine la --keepopción.

Para obtener más información, consulte la Extensión de la tira .

Si obtiene "comando desconocido" tira ", es posible que deba habilitarlo. Para hacerlo encontrar el .hgrco Mercurial.iniarchivo y añadir la siguiente a la misma:

[extensions]
strip =

Tenga en cuenta que (como mencionó Juozas en su comentario) tener múltiples cabezas es un flujo de trabajo normal en Mercurial. No deberías usar el comando strip para luchar contra eso. En cambio, debe fusionar su cabeza con la cabeza entrante, resolver cualquier conflicto, probar y luego empujar.

El stripcomando es útil cuando realmente desea deshacerse de los conjuntos de cambios que contaminan la rama. De hecho, si está en la situación de esta pregunta y desea eliminar por completo todos los conjuntos de cambios "borrador" de forma permanente, consulte la respuesta principal , que básicamente sugiere hacer:

hg strip 'roots(outgoing())'

8
@Bharath: Necesitas habilitar la extensión
Samaursa

1
Desde mercurial 2.8, strip es una extensión independiente, por lo que strip = está bien. WhatsNew para Mercurial 2.8
Chih-Hsuan Yen

104

Si está utilizando Hg Tortoise, simplemente active la extensión " strip " en:

  1. Archivo / Configuración / Extensiones /
  2. Seleccione tira

Luego seleccione la revisión inferior desde donde desea comenzar a dividir, haciendo right clicken ella y seleccionando:

  1. Modificar historial
  2. Tira

Así como así:

ingrese la descripción de la imagen aquí

En este ejemplo, se borrará de la 19a revisión a la última comprometida (22).


2
File/Settings/Extensions/Desearía poder agregar más votos. ¡Muchas gracias!
dyatchenko

Argh! Intenté esto pero parecía volcar todos mis cambios a pesar de no marcar "sin respaldo" o "descartar cambios locales". Quería mantener esos cambios, ¡pero no comprometerlos! ¿Hay alguna forma de recuperarlos ahora?
Tim Tisdall

2
Parece que no puedo encontrar una manera de hacerlo correctamente, pero parece que se debe mantener el contenido que necesita pasar --keepy TortoiseHg no da esa opción. Entonces ... necesitas hacerlo en la línea de comando con hg strip -r . --keep.
Tim Tisdall

3
from strip help: 'Todos los conjuntos de cambios eliminados se almacenan en ".hg / strip-backup" como un paquete (consulte "hg help bundle" y "hg help unbundle"). Se pueden restaurar ejecutando "hg unbundle .hg / strip-backup / BUNDLE", donde BUNDLE es el archivo de paquete creado por la tira ".
Tim Tisdall

En SourceTree también fue útil. ¡Gracias!
Ponomarenko Oleh

22

Respuesta moderna (solo relevante después de Mercurial 2.1):

Use Fases y marque las revisiones que no desea compartir como secretas (privadas). De esa manera, cuando empujes, no serán enviados.

En TortoiseHG puede hacer clic derecho en un compromiso para cambiar su fase.

Además: también puede usar la extensión "rebase" para mover sus confirmaciones locales al encabezado del repositorio compartido después de extraer.


Privado == secreto ahora
Dmitry Osinovskiy

15

Como todos los demás están señalando, probablemente solo debas tirar y luego fusionar las cabezas, pero si realmente quieres deshacerte de tus commits sin ninguna de las herramientas EditingHistory , entonces puedes simplemente hg clone -rtu repositorio para obtener todos menos esos cambios.

Esto no los elimina del repositorio original, pero crea un nuevo clon que no los tiene. Luego, puede eliminar el repositorio que modificó (si lo desea).


¿"Hg clone -r" elimina los cambios locales? Solo quiero eliminar los commits locales para mantener las cosas simples.
user191535

44
No los elimina del repositorio clonado, pero crea un nuevo clon que no los tiene. Luego, puede eliminar el repositorio que modificó si lo desea.
Ry4an Brase

9

Me encontré con este problema también. Hice 2 commity quería revertir y eliminar ambas confirmaciones.

$ hg rollback

Pero hg rollbacksolo regresa a la última confirmación, no a las 2 confirmaciones. En ese momento no me di cuenta de esto y cambié el código.

Cuando descubrí que hg rollbackacababa de deshacer una confirmación, descubrí que podía usar hg strip #changeset#. Entonces, solía hg log -l 10encontrar los últimos 10 commits y obtener el conjunto de cambios correcto que quería strip.

$ hg log -l 10
changeset:   2499:81a7a8f7a5cd
branch:      component_engine
tag:         tip
user:        myname<myname@email.com>
date:        Fri Aug 14 12:22:02 2015 +0800
summary:     get runs from sandbox

changeset:   2498:9e3e1de76127
branch:      component_engine
user:        other_user_name<name@email.com>
date:        Mon Aug 03 09:50:18 2015 +0800
summary:     Set current destination to a copy incoming exchange

......

$ hg strip 2499
abort: local changes found

Que abort: local changes foundsignifica Significa que se hgencontraron cambios en el código que aún no se han confirmado. Entonces, para resolver esto, debe hg diffguardar el código que ha cambiado y hg reverty hg strip #changeset#. Así como así:

$ hg diff > /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff
$ hg revert file_you_have_changed
$ hg strip #changeset#

Después de haber hecho lo anterior, puede patchel archivo diff y su código puede agregarse nuevamente a su proyecto.

$ patch -p1 < /PATH/TO/SAVE/YOUR/DIFF/FILE/my.diff

9

Puede solucionar esto aún más fácilmente con la extensión Rebase , solo use hg pull --rebasey sus confirmaciones se vuelven a comprometer automáticamente en la revisión extraída, evitando el problema de ramificación.


1
A expensas de tener un historial inexacto y posible corrupción si hace las cosas mal.
Ry4an Brase el

5

Si está familiarizado con git, estará encantado de usar histedit que funciona de la misma manera git rebase -i.


4

hg stripes lo que buscas. Es análogo a git resetsi estás familiarizado con git.

Use la consola:

  1. Necesita saber el número de revisión. hg log -l 10. Este comando muestra los últimos 10 commits. Encuentra commit que estás buscando. Necesita un número de 4 dígitos de la línea de conjunto de cambioschangeset: 5888:ba6205914681

  2. Entonces hg strip -r 5888 --keep. Esto elimina el registro de la confirmación pero mantiene todos los archivos modificados y luego puede volver a comprometerlos. (si desea eliminar archivos para simplemente eliminarlos --keephg strip -r 5888


1

[Hg Tortoise 4.6.1] Si se trata de una acción reciente, puede utilizar la acción "Deshacer / Deshacer" (Ctrl + U).

Imagen de tortuga HG


Verifique la inclusión de una imagen.
Bill Keller

0

Además de la excelente respuesta de Samaursa, puede usar la evolveextensión prunecomo una versión segura y recuperable stripque le permitirá regresar en caso de que haga algo mal.

Tengo este alias en mi .hgrc:

 # Prunes all draft changesets on the current repository
 reset-tree = prune -r "outgoing() and not obsolete()"
 # *STRIPS* all draft changesets on current repository. This deletes history.
 force-reset-tree = strip 'roots(outgoing())'

Tenga en cuenta que prunetambién tiene --keep, al igual que strip, mantener el directorio de trabajo intacto, lo que le permite volver a comprometer los archivos.

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.