tag - git rebase
¿Combina los primeros dos commits de un repositorio de Git? (7)
Supongamos que tiene un historial que contiene los tres commits A, B y C :
A-B-C
Me gustaría combinar los dos commits A y B para un commit AB :
AB-C
Lo intenté
git rebase -i A
que abre mi editor con los siguientes contenidos:
pick e97a17b B
pick asd314f C
Yo cambio esto a
squash e97a17b B
pick asd314f C
Entonces Git 1.6.0.4 dice:
Cannot ''squash'' without a previous commit
¿Hay alguna forma o esto es simplemente imposible?
En el caso de la rebase interactiva, debe hacerlo antes de A para que la lista sea:
pick A
pick B
pick C
convertirse:
pick A
squash B
pick C
Si A es la confirmación inicial, debe tener una confirmación inicial diferente antes de que A. Git piense en las diferencias, funcionará en la diferencia entre (A y B) y (B y C). Por lo tanto, la calabaza no funciona en tu ejemplo.
En el caso de que tengas cientos o miles de commits, usando la respuesta de kostmo
git rebase -i --root
puede ser poco práctico y lento, solo por la gran cantidad de confirmaciones que el script de rebase debe procesar dos veces , una para generar la lista de editores de rebase interactiva (donde se selecciona qué acción tomar para cada confirmación) y una para ejecutar realmente el re-aplicación de confirmaciones
Aquí hay una solución alternativa que evitará el costo de tiempo de generar la lista interactiva del editor de rebase al no usar una rebase interactiva en primer lugar. De esta manera, es similar a la solución de Charles Bailey . Simplemente crea una rama huérfana a partir de la segunda confirmación, y luego rebase todas las asignaciones de descendientes sobre la misma:
git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master
Documentación
En una pregunta relacionada, me las arreglé para llegar a un enfoque diferente a la necesidad de aplastar contra el primer compromiso, que es, bueno, para que sea el segundo.
Si te interesa: git: ¿cómo insertar un compromiso como el primero, cambiando todos los demás?
Intentaste:
git rebase -i A
Es posible comenzar así si continúa con edit
lugar de squash
:
edit e97a17b B
pick asd314f C
entonces corre
git reset --soft HEAD^
git commit --amend
git rebase --continue
Hecho.
Tienes que realizar un poco de magia de línea de comandos.
git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a
Eso debería dejarte con una rama que tiene AB y C como confirmaciones.
Utilice git rebase -i --root
partir de la versión 1.7.12 de Git.
En el archivo de rebase interactivo, cambie la segunda línea de confirmación B para aplastar y deje las otras líneas en la selección :
pick f4202da A
squash bea708e B
pick a8c6abc C
Esto combinará los dos commits A y B para un commit AB .
Encontrado en esta respuesta .
A
fue la confirmación inicial, pero ahora quieres que B
sea la confirmación inicial. Los commit de git son árboles completos, no diffs incluso si normalmente se describen y se ven en términos de la diferencia que introducen.
Esta receta funciona incluso si hay varias confirmaciones entre A y B, y B y C.
# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>
# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>
# amend the initial tree using the tree from ''B''
git commit --amend
# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp
# go back to the original branch (assume master for this example)
git checkout master
# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>
# remove the temporary tag
git tag -d tmp