2009-07-29 11 views
92

Digamos que tengo un repositorio local y remoto de Mercurial. Ahora, empiezo a trabajar en una característica. Trabajo en eso, y cuando pienso que ya está hecho, me comprometo con el conjunto de cambios. Probándolo un poco más, me parece que podría mejorar aún más esta característica ajustando algo en el código. Hago el cambio y me comprometo. 20 minutos después, descubro que hay un error en esta nueva función, así que lo soluciono y lo confirmo también.Con Mercurial, ¿cómo puedo "comprimir" una serie de conjuntos de cambios en uno antes de presionar?

Ahora tengo 3 changesets que realmente me gustaría enviar al repositorio remoto como un conjunto de cambios con el mensaje "Implementing feature X", por ejemplo.

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

+39

Claramente no es mi lugar para 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 ... descontroladoramente controlado. –

+0

Esto 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, y histedit tiene un UX mucho más intuitivo. –

Respuesta

38
+15

¡Saludos del futuro! Acabo de buscar 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 en el comando rebase.] (Https://www.mercurial-scm.org/wiki/RebaseExtension#Collapsing) Dado que esta pregunta es el resultado de búsqueda general tercero y el primero en stackoverflow, pensé que la información podría sé útil. –

+0

Saludo de incluso más en el futuro !! La extensión de rebase parece ser el único objetivo para mover conjuntos de cambios de una rama a otra. Sí, hay una opción --collapse, pero todavía parece ser aplicable solo cuando se mueve un conjunto de conjuntos de cambios entre sucursales. Consulte

+3

Puede usar 'hg rebase' con' --collapse' dentro de una única rama. – DaveInCaz

2

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

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

+0

Eso parece más que un poco complicado, pero gracias por el enlace. Sinceramente, espero una extensión mágica que haga exactamente lo que quiero, como buscar y trasplantar con tirones y recortes de cereza. – Lucas

19

Sí, puede hacerlo con parches: Supongamos que su trabajo está en conjuntos de cambios del 100 hasta el 110, ambos inclusive

  1. Crear un parche:

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

  2. actualización a 99 :

    % hg update 99

  3. Aplicar el parche con --no-commit (de lo contrario obtendrá todos sus conjuntos de cambios hacia atrás):

    % hg import --no-commit mypatch

  4. confirmar todos los cambios a la vez:

    % hg commit

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

    % hg strip 100

OK, ahora que he explicado todo esto a cabo, parece largo, pero después de haber hecho un montón de veces a mí mismo, no me parece que sea demasiado de una tarea ...

+1

Gran respuesta, pero hay un requisito previo: la [extensión MQ debe estar habilitada] (http://mercurial.selenic.com/wiki/MqExtension#line-17). –

+0

Para incluir también los cambios en los archivos binarios, asegúrese de usar la opción --git: por ejemplo: "hg export -o mypatch 100: 110 --git" Para obtener más información, consulte: http://stackoverflow.com/a/12537738/367663 Me he tomado la libertad de enmendar la respuesta. –

+1

Parece demasiado complicado, ¿por qué no 'hg strip --keep' y luego confirma todo en una confirmación? –

49

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

hg histedit -o 

o

hg histedit --outgoing 

hará aparecer una lista de los conjuntos de cambios salientes.En la lista se puede

  • Fold 2 o más conjuntos de cambios crear un único conjunto de cambios
  • conjuntos de cambios gota y los sacan del historial de cambios
  • Reordenar como usted quiera.

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

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

También puede usar la extensión de colapsar para doblar, pero no proporciona una interfaz de usuario tan bonita y no proporciona una forma de editar el mensaje de confirmación resultante. Editar el mensaje de confirmación resultante también permite limpiar el mensaje final, que es algo que siempre termino utilizando.

+0

gracias, eso es exactamente lo que necesitaba. Sería bueno si pudieras hacerlo desde TortoiseHg, pero la línea de comando es bastante simple. – sylvanaar

0

HistEdit hará lo que quiera, pero es probable que sea excesivo. Si lo único que necesita es doblar algunos conjuntos de cambios, el Collapse Extension hará el trabajo.

+1

aunque proporciona una interfaz de usuario mucho más fácil de usar y comprender, que es más que suficiente razón para usarlo, pero también proporciona un mecanismo para editar el mensaje de conjunto de cambios fusionado, que es otra cosa que siempre quiero hacer cuando Me fusiono changesets. –

+0

Y el problema de solo entender la UI es que uno realmente no entiende ... De todos modos, en el pasado, mientras que histedit permite cambiar los 'desordenes', así como cambiar los mensajes cuando se 'fold'ing. El histedit es perfecto; en todo caso, la extensión del colapso no es útil. – user2864740

18

Mi método preferido de usar mq para este plegado es usar TortoiseHg as described here. Sin embargo, se puede hacer fácilmente desde la línea de comandos, 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 forma mejor de hacer el paso qfold, pero no soy consciente de ello, ya que suelen utilizar para ese TortoiseHg operación.)

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

20

Si está utilizando TortoiseHg, uso solo puede seleccionar dos revisiones (utilizar CTRL para seleccionar las no posteriores), haga clic derecho y seleccione "Historia Comprimir".

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

Simplemente puede quitar listas de cambios antiguas si ya no las necesita: use extensiones MQ para ello. Nuevamente, en TortoiseHg: haga clic con el botón derecho en la primera lista de cambios que se debe quitar con todos sus descendientes, "Modificar historial -> Franja".

4

hg collapse y hg histedit son las mejores maneras. O, mejor dicho, serían las mejores maneras, si funcionaran de manera confiable ... Obtuve histedit para bloquear con un volcado de pila en tres minutos. Collapse no es mucho mejor.

Pensamiento

podría compartir otros dos BKMs:

  1. hg rebase --collapse

    Esta extensión se distribuye con Mercurial. No he tenido problemas con eso todavía.Puede que tenga que jugar algunos juegos para evitar las limitaciones de hg rebase; básicamente, no le gusta volver a establecer una base de datos para un ancestro en la misma rama, nombrado o predeterminado, aunque sí lo permite si se rebases 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 sobre la creación de dos árboles de clonación y la copia de archivos entre ellos. O parcheando entre ellos. En cambio, es más fácil mover los directorios .hg.

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 y cuando los verdaderos depositarios, los .hg árboles, son independientes del directorio de trabajo y sus archivos.

Si ellos no son independientes ...

+0

En 2015, 'histedit' es una muy buena opción para esta tarea. Todavía no confío en él, como hago un git rebase -i, pero no se cuelga ... al menos las versiones más recientes te dejarán en una rama temporal si algo sale mal, así que el único momento en que los conjuntos de cambios serán eliminados es después de que la nueva rama está comprometida. – user2864740

0

¿Por qué no hg strip --keep mando?

Luego puede confirmar todos los cambios como un compromiso.

+0

@Strawberry no proporciona una respuesta? Piensa que responde perfectamente la pregunta del autor. ¿Puedes elaborar tu punto? –

+0

Es historia antigua, así que me retracté de la observación, pero la respuesta aprobada parece una referencia más autorizada. – Strawberry

+0

@Strawberry De hecho, es un hilo antiguo. Pero la respuesta aceptada está desactualizada, porque Mercurial ya no necesita una extensión independiente de terceros para este trabajo. –

0

Suponga que tiene dos inéditos THIS y THAT comete en Mercurial y como ellos a unirse en un solo punto de comprometerse a THIS ::

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

Comprobar que sus confirmaciones no se publican ::

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

Actualizar a LAST commit ::

$ hg up 

e importación se compromete hasta THIS en MQ ::

$ hg qimport $THIS::. 

Un aplicar todos los parches y se aplican únicamente primero THIS ::

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

Ingreso con THAT ::

$ hg qfold $THATNAME 

NOTA Para encontrar el nombre THATNAME use ::

$ hg qseries 

Aplicar todos los parches y moverlos al repositorio historia ::

$ hg qpush -a 
$ hg qfinish -a 

Mi blog el tema es Joining two commits in Mercurial.

Cuestiones relacionadas