example commits all git merge interactive rebase squash

commits - git squash command example



git rebase interactive: squash merge se compromete junto (4)

Quería tener una solución simple para aplastar dos commits de fusión juntos durante una rebase interactiva.

Mi repositorio se ve así:

X --- Y --------- M1 -------- M2 (my-feature) / / / / / / a --- b --- c --- d --- e --- f (stable)

Es decir, tengo una rama my-feature que se ha fusionado dos veces recientemente, sin compromisos reales en el medio. No solo quiero volver a establecer la base de la rama my-feature ya que es una rama propia publicada, solo quiero aplastar los dos últimos commits de fusión en uno (aún no se han publicado los commits)

X --- Y ---- M (my-feature) / / / / a --- ... -- f (stable)

Lo intenté:

git rebase -p -i M1^

Pero tengo:

Refusing to squash a merge: M2

Lo que finalmente hice fue:

git checkout my-feature git reset --soft HEAD^ # remove the last commit (M2) but keep the changes in the index git commit -m toto # redo the commit M2, this time it is not a merge commit git rebase -p -i M1^ # do the rebase and squash the last commit git diff M2 HEAD # test the commits are the same

Ahora, la nueva confirmación de fusión ya no se considera una combinación de fusión (solo mantuvo el primer padre). Asi que:

git reset --soft HEAD^ # get ready to modify the commit git stash # put away the index git merge -s ours --no-commit stable # regenerate merge information (the second parent) git stash apply # get the index back with the real merge in it git commit -a # commit your merge git diff M2 HEAD # test that you have the same commit again

Pero esto puede complicarse si tengo muchos compromisos, ¿tienes una mejor solución? Gracias.

Mildred


Este es un tema antiguo, pero lo encontré buscando información similar.

Un truco similar al descrito en Subtree Octopus Merge es una muy buena solución para este tipo de problema:

git checkout my-feature git reset --soft Y git rev-parse f > .git/MERGE_HEAD git commit

Eso tomará el índice tal como existe en la punta de mi característica, y lo usará para crear un nuevo compromiso fuera de Y, con ''f'' como segundo padre. El resultado es el mismo que si nunca hubieras ejecutado M1, pero pasaste directamente a realizar M2.


Llegué a este tema que quería aplastar una sola fusión de compromiso; entonces mi respuesta no es tan útil para la pregunta original.

X / / a --- b --- c --- M1 (subtree merge)

Lo que quería era volver a establecer la fusión de M1 y aplastar todo como una confirmación única sobre b.

a --- b --- S (include the changes from c, X and M1)

Probé todo tipo de combinaciones diferentes, pero esto es lo que funcionó:

git checkout -b rebase b (checkout a working branch at point b) git merge --squash M1

Esto aplicará los cambios en el índice donde se pueden comprometer git commit


Ninguno de los métodos mencionados funciona para mí con una versión reciente de Git. En mi caso, el siguiente hizo el truco:

git reset --soft Y git reset --hard $(git commit-tree $(git write-tree) -p HEAD -p stable < commit_msg)

Sin embargo, primero tendrá que escribir el mensaje de confirmación en el archivo commit_msg.


si no ha publicado las últimas dos asignaciones de fusión, puede hacer un restablecimiento y una fusión simple.

git reset --hard Y git merge stable