Puede ejecutar git rebase --interactive
y reordenar D antes de B y aplastar D en A.
Git abrirá un editor, y verá un archivo como este, por ejemplo: git rebase --interactive HEAD~4
pick aaaaaaa Commit A
pick bbbbbbb Commit B
pick ccccccc Commit C
pick ddddddd Commit D
# Rebase aaaaaaa..ddddddd onto 1234567 (4 command(s))
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
Ahora cambia el archivo que se ve así:
pick aaaaaaa Commit A
squash ddddddd Commit D
pick bbbbbbb Commit B
pick ccccccc Commit C
Y git ahora fusionará los cambios de A y D en un solo commit, y pondrá B y C después. Cuando no desee mantener el mensaje de confirmación de D, en lugar de squash
usar la fixup
palabra clave. Para más información fixup
, puede consultar los git rebase
documentos o consultar esta pregunta que tiene algunas buenas respuestas.
There is no tracking information for the current branch
error al volver a crear una nueva versión. En este caso es necesario especificar el número de confirmaciones que desea trabajar con, por ejemplo:git rebase -i HEAD~4
. Mira esta respuesta .Nota: No debe cambiar las confirmaciones que se han enviado a otro repositorio de ninguna manera a menos que conozca las consecuencias .
git log --oneline -4
git rebase --interactive
Tipo
i
(poner VIM en modo de inserción)Cambie la lista para que se vea así (no tiene que eliminar ni incluir el mensaje de confirmación). ¡No escribas mal
squash
! :Escriba Escluego
ZZ
(Guardar y salir de VIM)Tipo
i
Cambie el texto a cómo desea que se vea el nuevo mensaje de confirmación. Recomiendo que esta sea una descripción de los cambios en commit
A
yD
:Escribe Escentonces
ZZ
git log --oneline -4
git show E
Ahora ha creado una nueva confirmación
E
. Se comprometeA
yD
ya no está en su historia, pero no se ha ido. Todavía puede recuperarlos en este momento y durante un tiempogit rebase --hard D
(¡git rebase --hard
destruirá cualquier cambio local! ).fuente
Para aquellos que usan SourceTree :
Asegúrate de no haber empujado los commits.
Squash with previous
fuente
El rebase interactivo funciona bien hasta que tenga una rama de características grandes con 20-30 confirmaciones y / o un par de fusiones del maestro o / y arregle conflictos mientras se comprometía en su rama. Incluso con la búsqueda de mis compromete a través de la historia y su sustitución
pick
consquash
no trabajado aquí. Así que estaba buscando otra forma y encontré este artículo . Hice mis cambios para trabajar esto en una rama separada:Antes de esto recibí mi solicitud de extracción con aproximadamente ~ 30 confirmaciones con 2-3 fusiones de maestro + solución de conflictos. Y después de esto obtuve relaciones públicas claras con una confirmación.
PS aquí es un script bash para hacer estos pasos en automode.
fuente
$ git checkout master
$ git log --en línea
$ git rebase --onto HEAD ^^^ HEAD ^
$ git log --en línea
fuente
--oneline
? Y parece que has caídoC
yB
, que no es lo que pretendía el OP.git show A
) y D, C y B se perdieron en mi registro de referencia. Tenía quegit rebase D
volver.