Con Mercurial, ¿cómo puedo "comprimir" una serie de conjuntos de cambios en uno antes de presionar?

96

Digamos que tengo un repositorio Mercurial local y otro remoto. Ahora empiezo a trabajar en una función. Trabajo en él, y cuando creo que está hecho, confirmo el conjunto de cambios. Probándolo un poco más, descubrí que podría mejorar aún más esta función modificando algo en el código. Hago el cambio y me comprometo. 20 minutos después, encuentro que hay un error en esta nueva función, así que lo soluciono y también lo cometo.

Ahora tengo 3 conjuntos de cambios que realmente me gustaría enviar al repositorio remoto como un conjunto de cambios con el mensaje "Implementando la característica X", por ejemplo.

¿Cómo puedo hacer esto sin muchos problemas? Creo que podría hacerlo con parches, pero parece mucho trabajo.

Lucas
fuente
40
Claramente, no me corresponde a mí convencerlo de que no intente comprimir sus conjuntos de cambios, pero es posible que desee considerar que la mitad del valor del control de versiones es responder "por qué" no solo "qué" meses y años después. Una representación precisa de cómo surgió una característica y en qué etapas podría ser de valor futuro. Descartarlo parece tan ... incontrolablemente.
Ry4an Brase
Esto nos lleva a otra pregunta ... ¿Cuál es la diferencia entre 'histedit' y 'collapse'
sylvanaar
1
collapse proporciona un subconjunto de las características de histedit, e histedit tiene una UX mucho más intuitiva.
Stefan Rusek
1
También proporciona un mecanismo para editar el mensaje de conjunto de cambios combinado.
Stefan Rusek
1
@ Ry4an: En realidad, aplastar / colapsar agrega relevancia al control de versiones en algunos casos. Sin aplastar, tendría dos confirmaciones todos los días que no tienen nada que ver con funciones o correcciones de errores, pero son para mover el código de la computadora portátil al escritorio y viceversa. Simplemente agregan ruido al historial de versiones.
John Reynolds

Respuestas:

39

¿Qué tal la extensión Collapse ?

Steve Losh
fuente
20
¡Saludos desde el futuro! Busqué en Google la misma funcionalidad y aparentemente hoy en día hg admite esto de fábrica con hg rebase --collapse. Consulte la wiki de hg sobre el comando rebase. Dado que esta pregunta es el tercer resultado de búsqueda general y el primero en stackoverflow, pensé que la información podría ser útil.
a.peganz
1
Saludo desde aún más lejos en el futuro !! La extensión de rebase parece estar dirigida únicamente a mover conjuntos de cambios de una rama a otra. Sí, hay una opción --collapse, pero aún parece ser aplicable solo cuando se mueve un conjunto de conjuntos de cambios a través de ramas. Ver < mercurial-scm.org/wiki/… >
Brad Oestreicher
3
Se puede utilizar hg rebasecon --collapsedentro de una sola rama.
UuDdLrLrSs
52

La extensión histedit es exactamente lo que está buscando.

hg histedit -o

o

hg histedit --outgoing

mostrará una lista de los conjuntos de cambios salientes. De la lista puedes

  • Doble 2 o más conjuntos de cambios creando un solo conjunto de cambios
  • Eliminar conjuntos de cambios eliminándolos del historial
  • Reordene los conjuntos de cambios como desee.

histedit le solicitará el nuevo mensaje de confirmación de los conjuntos de cambios plegados, que por defecto son los dos mensajes con "\ n *** \ n" separándolos.

También puede obtener resultados similares con la extensión mq, pero es mucho más difícil.

También puede usar la extensión de colapso para simplemente plegar, pero no proporciona una interfaz de usuario tan agradable y no proporciona una forma de editar el mensaje de confirmación resultante. La edición del mensaje de confirmación resultante también permite limpiar el mensaje final, que es algo que siempre termino utilizando.

Stefan Rusek
fuente
gracias, eso es exactamente lo que necesitaba. Sería bueno si pudiera hacerlo desde TortoiseHg, pero la línea de comandos es bastante simple.
sylvanaar
21

Sí, puede hacerlo con parches: supongamos que su trabajo está en los conjuntos de cambios del 100 al 110, inclusive

  1. Crea un parche:

    % hg export -o mypatch 100:110 --git

  2. Actualizar a 99:

    % hg update 99

  3. Aplique el parche con --no-commit (de lo contrario, recuperará todos sus conjuntos de cambios):

    % hg import --no-commit mypatch

  4. Confirme todos los cambios a la vez:

    % hg commit

  5. Ahora tiene dos cabezas (110 y 111) que deberían ser equivalentes en términos de archivos que producen en su directorio de trabajo, tal vez diferenciarlos por cordura antes de eliminar los anteriores:

    % hg strip 100

Bien, ahora que lo he deletreado todo, parece largo, pero habiéndolo hecho un montón de veces, no lo encuentro demasiado complicado ...

Arkady
fuente
1
Excelente respuesta, pero hay un requisito previo: la extensión MQ debe estar habilitada .
Chris Kelly
Para incluir cambios también en archivos binarios, asegúrese de utilizar la opción --git: por ejemplo: "hg export -o mypatch 100: 110 --git" Para obtener más información, consulte: stackoverflow.com/a/12537738/ 367663 Me he tomado la libertad de modificar la respuesta.
Kharlos Dominguez
1
Parece demasiado complicado, ¿por qué no hg strip --keepy luego compromete todo en una sola confirmación?
G. Demecki
@ G.Demecki Porque es una operación potencialmente con muchas pérdidas ...? Aunque MQ es excesivo (e incluso a menudo no se recomienda), excepto cuando se desea un flujo de trabajo de este tipo.
user2864740
@ user2864740 Puede que tengas razón, porque no soy un experto en Mercurial. Pero de forma predeterminada, hg stripcolocará una copia de seguridad en el .hg/strip-backup/directorio. Supongo que no es tan seguro, git reflogpero todavía proporciona algún tipo de rescate.
G. Demecki
19

Si está utilizando TortoiseHg, puede seleccionar dos revisiones (use CTRL para seleccionar las que no sean posteriores), haga clic derecho y seleccione "Comprimir historial" .

Después de eso, obtendrá una nueva lista de cambios en un nuevo encabezado a partir del primer cambio que seleccionó antes, contendrá todas las listas de cambios descendientes entre las que seleccionó.

Simplemente puede eliminar las listas de cambios antiguas si ya no las necesita: use extensiones MQ para ello. Nuevamente, en TortoiseHg: haga clic derecho en la primera lista de cambios que necesita ser eliminada con todos sus descendientes, "Modificar historial -> Eliminar" .

George Marian
fuente
18

Mi método preferido de usar mq para este plegado es usar TortoiseHg como se describe aquí . Sin embargo, se puede hacer fácilmente desde la línea de comando así:

hg qimport -r <first>:<last> 
    -- where <first> and <last> are the first and last changesets 
    -- in the range of revisions you want to collapse

hg qpop <first>.diff
    -- remove all except for the first patch from the queue
    -- note: mq names patches <#>.diff when it imports them, so we're using that here

hg qfold <next>.diff
    -- where <next> is <first>+1, then <first>+2, until you've reached <last>

hg qfinish -a
    -- apply the folded changeset back into the repository

(Puede haber una mejor manera de hacer el paso qfold, pero no soy consciente de ello, ya que normalmente uso TortoiseHg para esa operación).

Parece un poco complicado al principio, pero una vez que ha comenzado a usar mq, es bastante sencillo y natural, además, ¡puede hacer todo tipo de cosas con mq que pueden ser bastante útiles!

Chris Phillips
fuente
4

hg collapsey hg histeditson las mejores formas. O, mejor dicho, serían las mejores formas, si funcionaran de manera confiable ... Me histeditcolgué con un volcado de pila en tres minutos.Collapseno es mucho mejor.

Pensé que podría compartir otros dos BKM:

  1. hg rebase --collapse

    Esta extensión se distribuye con Mercurial. Todavía no he tenido problemas con eso. Es posible que tenga que jugar algunos juegos para evitar las hg rebaselimitaciones; básicamente, no le gusta rebasar a un ancestro en la misma rama, con nombre o por defecto, aunque lo permite si se cambia entre ramas (con nombre).

  2. Mueva el repositorio ( foo/.hg) al directorio de trabajo ( bar) y sus archivos. No de la otra manera.

Algunas personas han hablado de crear dos árboles de clonación y copiar archivos entre ellos. O parchear entre ellos. En cambio, es más fácil mover los .hgdirectorios.

hg clone project work
... lots of edits
... hg pull, merge, resolve
hg clone project, clean
mv work/.hg .hg.work
mv clean/.hg work/.hg
cd work
... if necessary, pull, nerge, reconcile - but that would only happen because of a race
hg push

Esto funciona siempre que los verdaderos repositorios, los .hgárboles, sean independientes del directorio de trabajo y sus archivos.

Si no son independientes ...

Krazy Glew
fuente
En 2015, histedites una muy buena opción para esta tarea. Todavía no confío en él, ya que hago un git rebase -i, pero no falla ... al menos las versiones más nuevas lo dejarán en una rama temporal si algo sale terriblemente mal, por lo que la única vez que se eliminarán los conjuntos de cambios es después de que se confirme la nueva rama.
user2864740
2

Nunca he usado Mercurial, pero esto se parece mucho a lo que Martin Fowler estaba hablando en su blog no hace mucho:

http://martinfowler.com/bliki/MercurialSquashCommit.html

Joseph
fuente
Eso parece más que complicado, pero gracias por el enlace. Honestamente, espero una extensión mágica que haga exactamente lo que quiero, como lo hizo la búsqueda y el trasplante con los changsets de extracción y selección.
Lucas
0

¿Por qué no simplemente hg strip --keepmandar?

Entonces puede confirmar todos los cambios como una confirmación.

G. Demecki
fuente
@Strawberry no da una respuesta ?? Piensa que responde perfectamente a la pregunta del autor. ¿Puede desarrollar su punto?
G. Demecki
Es historia antigua, así que retractaré el comentario, pero la respuesta Aprobada parece una referencia más autorizada.
Fresa
1
@Strawberry De hecho, es un hilo antiguo. Pero la respuesta aceptada está desactualizada, porque Mercurial ya no necesita una extensión de terceros separada para este trabajo.
G. Demecki
0

HistEdit hará lo que quieras, pero probablemente sea excesivo. Si lo único que necesita es plegar algunos conjuntos de cambios, Collapse Extension hará el trabajo.

Steve Losh
fuente
1
aunque proporciona una interfaz de usuario mucho más fácil de usar y comprender, que es una razón más que suficiente para usarla, pero también proporciona un mecanismo para editar el mensaje del conjunto de cambios combinado, que es otra cosa que siempre quiero hacer cuando fusionar conjuntos de cambios.
Stefan Rusek
Y el problema de solo entender la interfaz de usuario es que realmente no se comprende ... De todos modos, para el pasado, mientras que histedit permite cambiar los 'mensajes', así como cambiar los mensajes al 'plegar'. El histedit es perfecto; en todo caso, la extensión del colapso es poco útil.
user2864740
0

Suponga que tiene dos confirmaciones THISy no publicadas THATen Mercurial y le gusta que se unan en una única confirmación en el THISpunto ::

... --> THIS --> ... --> THAT --> ... --> LAST

Compruebe que sus confirmaciones no estén publicadas:

$ hg glog -r "draft() & ($THIS | $THAT)"

Actualización para LASTconfirmar:

$ hg up

y la importación se confirma hasta THISen MQ:

$ hg qimport $THIS::.

Desaplique todos los parches y aplique solo primero THIS:

$ hg qpop -a
$ hg qpush
$ hg qapplied
... THIS ...

Únete con THAT::

$ hg qfold $THATNAME

NOTA Para encontrar el nombre, THATNAMEuse:

$ hg qseries

Aplicar todos los parches y moverlos al historial del repositorio:

$ hg qpush -a
$ hg qfinish -a

La publicación de mi blog sobre el tema es Unir dos confirmaciones en Mercurial .

Gavenkoa
fuente
0

Sí, strip --keepfunciona para la pregunta del autor. Pero era ligeramente diferente a los demás, por ejemplo, si tiene la versión 1 a 30 pero solo quiere colapsar la versión 12-15. Otras soluciones funcionan pero no strip --keep.

Frank Tao
fuente