Mercurial: ¿cómo modificar la última confirmación?

Estoy buscando una contraparte de git commit --amend en Mercurial, es decir, una forma de modificar la confirmación a la que está vinculada mi copia de trabajo. Solo me interesa la última confirmación, no una confirmación anterior arbitraria.

Los requisitos para este procedimiento de modificación son:

  • si es posible, no debería requerir ninguna extensión. Debería no requiere extensiones no predeterminadas, es decir, extensiones que no vienen con una instalación oficial de Mercurial.

  • si el compromiso de enmendar es un jefe de mi rama actual, sin cabeza nueva debe ser creado. Si la confirmación no es de cabecera, se puede crear una nueva cabecera.

  • el procedimiento debe ser seguro de tal manera que si por alguna razón falla la enmienda, quiero que se restaure la misma copia de trabajo y el mismo estado de repositorio que antes de la enmienda. En otras palabras, si la modificación en sí misma puede fallar, debe haber un procedimiento a prueba de fallas para restaurar la copia de trabajo y el estado del repositorio. Me refiero a "fallas" que se encuentran en la naturaleza del procedimiento de modificación (como, por ejemplo, conflictos), no a problemas relacionados con el sistema de archivos (como restricciones de acceso, no poder bloquear un archivo para escritura, ... )

Actualización (1):

  • el procedimiento debe ser automatizable, por lo que puede ser realizado por un cliente GUI sin que se requiera la interacción del usuario.

Actualización (2):

  • los archivos en el directorio de trabajo no deben tocarse (puede haber bloqueos del sistema de archivos en ciertos archivos modificados). Esto significa especialmente que un posible enfoque en ningún momento puede requerir un directorio de trabajo limpio.

preguntado el 18 de noviembre de 11 a las 09:11

8 Respuestas

Con el lanzamiento de Mercurial 2.2, puedes usar el --amend opción con hg commit para actualizar la última confirmación con el directorio de trabajo actual

Desde el referencia de línea de comando:

El indicador --amend se puede utilizar para modificar el padre del directorio de trabajo con una nueva confirmación que contiene los cambios en el padre además de los que se informa actualmente por hg status, si los hay. La confirmación anterior se almacena en un paquete de copia de seguridad en .hg / strip-backup (consulte el paquete de ayuda de hg y el paquete de ayuda de hg sobre cómo restaurarlo).

El mensaje, el usuario y la fecha se toman de la confirmación modificada a menos que se especifique. Cuando no se especifica un mensaje en la línea de comando, el editor se abrirá con el mensaje de la confirmación modificada.

Lo bueno es que este mecanismo es "seguro", porque se basa en la característica relativamente nueva de "Fases" para evitar actualizaciones que cambiarían el historial que ya está disponible fuera del repositorio local.

contestado el 06 de mayo de 21 a las 08:05

¡Buena respuesta! El experimental evolucionar extensión le permite enmendar de forma segura no cabeza se compromete. La confirmación anterior se marcará como obsoleta y oculta. Con un servidor sin publicación, incluso puede hacer esto de forma segura después de haber introducido los conjuntos de cambios. - Martín Geisler

Para actualizar el mensaje en la última confirmación: hg commit --amend -m "este es mi nuevo mensaje" - jay sheth

Tienes 3 opciones para editar confirmaciones en Mercurial:

  1. hg strip --keep --rev -1 deshaga las últimas (1) confirmaciones, para que pueda hacerlo de nuevo (consulte esta respuesta ).

  2. Usando el patrón de velas del Extensión MQ, que se envía con Mercurial

  3. Incluso si no se envía con Mercurial, el Histedit vale la pena mencionar la extensión

También puede echar un vistazo a la Editar historial página de la wiki de Mercurial.

En resumen, editar el historial es muy difícil y desanimado. Y si ya ha impulsado sus cambios, apenas hay nada que pueda hacer, excepto si tiene el control total de todos los demás clones.

No estoy realmente familiarizado con el git commit --amend comando, pero AFAIK, Histedit es lo que parece ser el enfoque más cercano, pero lamentablemente no se envía con Mercurial. MQ es realmente complicado de usar, pero puede hacer casi cualquier cosa con él.

Respondido 22 Feb 18, 10:02

No estoy seguro de por qué me perdí la reversión, pero parece hacer (casi) lo que quiero. El único problema es que, cuando se ha eliminado un archivo para mi confirmación original y se ha resucitado para mi confirmación modificada: antes de la reversión no se convertirá, después de la reversión, se programará para su eliminación (pero el archivo todavía existe en el directorio de trabajo) - mstrap

@Marc No estoy seguro de entender su problema, pero eche un vistazo al comando de olvido, creo que es lo que está buscando. - pequeño

No creo que "olvidar" sea útil aquí. Aquí está el problema con más detalle: (1) Estoy en la revisión 2 (2) Elimino el "archivo" y tengo algunos otros cambios (3) Confirmo los cambios, lo que resulta en la revisión 3 (4) Ahora cambiaré de opinión y decidiré "archivo" no debe eliminarse de la confirmación, por lo que quiero modificar la revisión 3. Por lo tanto, volveré a agregar "archivo" que ahora no está versionado (5) Ahora realizo una reversión: restablecerá el estado de directorio y marcaré " archivo "como eliminado. (6) Al ejecutar "hg commit" nuevamente ahora, "file" permanecerá como eliminado, aunque ya no debería serlo. ¿Cómo podría verse una solución automática para eso? - mstrap

Para la parte automatizada, no lo sé, pero puedes hacerlo. hg revert myfile para deshacer la eliminación. Quizás volver a agregar con hg add el archivo después del rollback también funciona. - pequeño

Estoy de acuerdo en que se debe evitar editar el historial de cambios publicados, pero editar mi locales la historia es uno de los aspectos más destacados de un DVCS. MQ con su qimport es pura edición de historial, AFAICT. - mstrap

Equivalente de GUI para hg commit --amend:

Esto también funciona desde la GUI de TortoiseHG (estoy usando v2.5):

Cambie a la vista 'Confirmar' o, en la vista del banco de trabajo, seleccione la entrada 'directorio de trabajo'. El botón 'Confirmar' tiene una opción llamada 'Modificar revisión actual' (haga clic en la flecha desplegable del botón para encontrarla).

enter image description here

          ||
          ||
          \/

enter image description here

Caveat emptor:

Esta opción adicional solo estará habilitada si la versión mercurial es al menos 2.2.0, y si la revisión actual no es pública, no es un parche y no tiene hijos. [...]

Al hacer clic en el botón, se llamará "confirmar - enmendar" para "modificar" la revisión.

Más información sobre esto en el canal de desarrollo de THG

Respondido el 04 de enero de 13 a las 11:01

Muy útil, gracias. THG es lo suficientemente inteligente como para predeterminar el mensaje de confirmación (enmienda) al mensaje de la confirmación anterior, justo lo que quería. - Permanecer en el objetivo

Estoy sintonizando lo que ha escrito krtek. Más específicamente la solución 1:

Supuestos:

  • ha cometido un conjunto de cambios (!) pero aún no lo ha introducido
  • desea modificar este conjunto de cambios (por ejemplo, agregar, eliminar o cambiar archivos y / o el mensaje de confirmación)

Solución:

  • utilizado hg rollback para deshacer el último compromiso
  • comprometerse de nuevo con los nuevos cambios en su lugar

La reversión realmente deshace la última operación. Su forma de trabajar es bastante simple: las operaciones normales en HG solo se agregarán a los archivos; esto incluye un compromiso. Mercurial realiza un seguimiento de las longitudes de los archivos de la última transacción y, por lo tanto, puede deshacer completamente un paso truncando los archivos a sus longitudes anteriores.

respondido 18 nov., 11:13

Gracias por ajustar la solución (1); Solo queda un pequeño problema con la reversión, consulte mi comentario en la solución de krtek. - mstrap

Una cosa que se debe enfatizar en la reversión, porque atrapa a la gente, es que es la última transaccional en el repositorio que se deshace, no en la última confirmación. Entonces, si algo más ha causado una escritura en el repositorio, la reversión no ayudará. Es algo sutil pero importante para recordar. MQ e histedit pueden ayudar una vez que se ha cerrado la ventana de reversión, pero solo hasta cierto punto. - Paul S

Suponiendo que aún no ha propagado sus cambios, esto es lo que puede hacer.

  • Agregue a su .hgrc:

    [extensions]
    mq =
    
  • En tu repositorio:

    hg qimport -r0:tip
    hg qpop -a
    

    Por supuesto, no es necesario comenzar con la revisión cero o sacar todos los parches, para el último solo un pop (hg qpop) es suficiente (ver más abajo).

  • eliminar la última entrada en el .hg/patches/series archivo, o los parches que no le gustan. También es posible reordenar.

  • hg qpush -a; hg qfinish -a
  • eliminar el .diff archivos (parches no aplicados) todavía en .hg / parches (debería ser uno en su caso).

Si no quiero a recuperar todo de su parche, puede editarlo usando hg qimport -r0:tip (o similar), luego edita cosas y usa hg qrefresh para fusionar los cambios en el parche más alto de su pila. Leer hg help qrefresh.

Editando .hg/patches/series, incluso puede eliminar varios parches o reordenar algunos. Si su última revisión es 99, puede usar hg qimport -r98:tip; hg qpop; [edit series file]; hg qpush -a; hg qfinish -a.

Por supuesto, este procedimiento está muy desanimado y es arriesgado. Hacer una copia de seguridad de todo antes de hacer esto!

Como nota al margen, lo he hecho miles de veces en repositorios privados.

respondido 18 nov., 11:14

También había considerado usar mq-extension, sin embargo, requiere bastantes operaciones para las cuales algunas de ellas pueden fallar (por ejemplo, si hay archivos binarios involucrados). Además, tener que editar .hg / patch / series no será aceptable, ya que este procedimiento debe usarse dentro de un cliente GUI (he actualizado los requisitos anteriores): mstrap

Hmmm, siento que esto no sea para ti, en un repositorio privado esto realmente patea traseros (con copias de seguridad, ya he destruido un representante con él ^^). Es genial combinar parches en uno antes de impulsar los cambios locales usando hg qfold, por cierto - hochl

+1 por usar MQ, pero creo que te has excedido. Solo pregunta por enmendar la última confirmación. Además, esa importación se derrumbará tan pronto como se fusione. 'qimport -r tip; ; qrefresh -e; qfin -a 'hará el trabajo (-e para editar el mensaje de confirmación) - Paul S

cierto, las fusiones son un problema, por lo general solo coloco un parche y uso hg import -r<prev>:tip. Lástima que no haya atajos para la versión anterior, como en la subversión. - hochl

Las versiones recientes de Mercurial incluyen el evolve extensión que proporciona la hg amend mando. Esto permite enmendar una confirmación sin perder el historial de pre-enmiendas en su control de versiones.

hg enmendar [OPCIÓN] ... [ARCHIVO] ...

alias: actualizar

combinar un conjunto de cambios con actualizaciones y reemplazarlo por uno nuevo

Commits a new changeset incorporating both the changes to the given files
and all the changes from the current parent changeset into the repository.

See 'hg commit' for details about committing changes.

If you don't specify -m, the parent's message will be reused.

Behind the scenes, Mercurial first commits the update as a regular child
of the current parent. Then it creates a new commit on the parent's
parents with the updated contents. Then it changes the working copy parent
to this new combined changeset. Finally, the old changeset and its update
are hidden from 'hg log' (unless you use --hidden with log).

Vea https://www.mercurial-scm.org/doc/evolution/user-guide.html#example-3-amend-a-changeset-with-evolve para una descripción completa de la evolve extensión.

respondido 06 mar '18, 12:03

¡Reutilizar el mismo mensaje de confirmación es una buena característica! - mpen

Es posible que no resuelva todos los problemas en la pregunta original, pero dado que esta parece ser la publicación de facto sobre cómo Mercurial puede enmendar la confirmación anterior, agregaré mis 2 centavos de información.

Si es como yo y solo desea modificar el mensaje de confirmación anterior (corregir un error tipográfico, etc.) sin agregar ningún archivo, esto funcionará

hg commit -X 'glob:**' --amend

Sin ningún patrón de inclusión o exclusión hg commit incluirá por defecto todos los archivos en el directorio de trabajo. Aplicando patrón -X 'glob:**' excluirá todos los archivos posibles, permitiendo solo modificar el mensaje de confirmación.

Funcionalmente es lo mismo que git commit --amend cuando no hay archivos en index / stage.

Respondido 03 Jul 19, 19:07

Otra solución podría ser utilizar el uncommit comando para excluir un archivo específico de la confirmación actual.

hg uncommit [file/directory]

Esto es muy útil cuando desea mantener la confirmación actual y anular la selección de algunos archivos de la confirmación (especialmente útil para files/directories han sido eliminados).

Respondido el 07 de enero de 20 a las 13:01

Uncommit es una extensión experimental. darw

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.