Pregunta

Suponga que tiene un historial que contiene las tres confirmaciones 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

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 es simplemente imposible?

¿Fue útil?

Solución

Utilice git rebase -i --root a partir de Git versión 1.7.12 .

En el archivo de rebase interactivo, cambie la segunda línea de commit B a squash y deje las otras líneas en pick :

pick f4202da A
squash bea708e B
pick a8c6abc C

Esto combinará los dos commits A y B en un commit AB .

Encontrado en esta respuesta .

Otros consejos

Intentaste:

git rebase -i A

Es posible comenzar así si continúa con edit en lugar de squash :

edit e97a17b B
pick asd314f C

luego ejecuta

git reset --soft HEAD^
git commit --amend
git rebase --continue

Listo.

A fue la confirmación inicial, pero ahora desea que B sea la confirmación inicial. las confirmaciones de git son árboles completos, no diferenciales, incluso si normalmente se describen y ven en términos de la diferencia que introducen.

Esta receta funciona incluso si hay múltiples 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

En el caso de un rebase interactivo, debe hacerlo antes de A para que la lista sea:

pick A
pick B
pick C

convertirse en:

pick A
squash B
pick C

Si A es la confirmación inicial, debe tener una confirmación inicial diferente antes de A. Git piensa 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 tenga cientos o miles de confirmaciones, use respuesta de kostmo de

git rebase -i --root

puede ser poco práctico y lento, solo debido a la gran cantidad de confirmaciones que el script de rebase tiene que procesar dos veces , una vez para generar la lista interactiva del editor de rebase (donde selecciona qué acción tomar para cada confirmación), y una vez para ejecutar realmente la nueva aplicación de confirmaciones.

Aquí hay una solución alternativa que evitará el costo de tiempo de generar la lista de editor de rebase interactiva al no usar una rebase interactiva en primer lugar. De esta manera, es similar a la solución de Charles Bailey . Simplemente cree una rama huérfana a partir de la segunda confirmación y luego vuelva a crear una base para todas las confirmaciones descendientes:

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, logré idear un enfoque diferente sobre la necesidad de aplastar el primer commit, que es, bueno, hacerlo el segundo.

Si está interesado: git: ¿cómo insertar un commit como el primero, desplazando a todos los demás?

Comando Git para escuadrón: git rebase -i HEAD ~ [número de confirmaciones]

Digamos que tienes debajo el historial de git commit:


pick 5152061 feat: Se agregó soporte para guardar la imagen. (UNA)
pick 39c5a04 Corrección: corrección de errores. (SEGUNDO)
pick 839c6b3 fix: conflicto resuelto. (C)

Ahora desea aplastar A y B a AB, realice los siguientes pasos:


pick 5152061 feat: Se agregó soporte para guardar la imagen. (UNA)
s 39c5a04 Corrección: corrección de errores. (SEGUNDO)
pick 839c6b3 fix: conflicto resuelto. (C)

Nota: para la confirmación de squash podemos usar squash o s. El resultado final será:
pick 5152061 feat: Se agregó soporte para guardar la imagen. (AB)
pick 839c6b3 fix: conflicto resuelto. (C)

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 dejarlo con una rama que tiene AB y C como commits.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top