oneline - ¿Cómo enmendar Git commit anterior?
git rebase (6)
En caso de que el OP desee aplastar los 2 commits especificados en 1, aquí hay una manera alternativa de hacerlo sin rebasar
git checkout HEAD^ # go to the first commit you want squashed
git reset --soft HEAD^ # go to the second one but keep the tree and index the same
git commit --amend -C HEAD@{1} # use the message from first commit (omit this to change)
git checkout HEAD@{3} -- . # get the tree from the commit you did not want to touch
git add -A # add everything
git commit -C HEAD@{3} # commit again using the message from that commit
La sintaxis @{N)
es útil para saber, ya que le permitirá hacer referencia al historial de dónde se encontraban sus referencias. En este caso, HEAD representa tu compromiso actual.
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo modificar una confirmación especificada en git? 11 respuestas
He hecho 3 commit de git, pero no me han empujado. ¿Cómo puedo modificar el anterior (ddc6859af44) y (47175e84c) que no es el más reciente?
$git log
commit f4074f289b8a49250b15a4f25ca4b46017454781
Date: Tue Jan 10 10:57:27 2012 -0800
commit ddc6859af448b8fd2e86dd0437c47b6014380a7f
Date: Mon Jan 9 16:29:30 2012 -0800
commit 47175e84c2cb7e47520f7dde824718eae3624550
Date: Mon Jan 9 13:13:22 2012 -0800
He usado otra forma por algunas veces. De hecho, es una git rebase -i
manual git rebase -i
y es útil cuando quieres reorganizar varias confirmaciones, incluyendo aplastar o dividir algunas de ellas. La principal ventaja es que no tienes que decidir sobre el destino de cada misión en un solo momento. También tendrá todas las funciones de Git disponibles durante el proceso a diferencia de una rebase. Por ejemplo, puede mostrar el registro del historial original y reescrito en cualquier momento, o incluso hacer otra rebase.
Me referiré a los commits de la siguiente manera, por lo que es fácil de leer:
C # good commit after a bad one
B # bad commit
A # good commit before a bad one
Tu historia al principio tiene este aspecto:
x - A - B - C
| |
| master
|
origin/master
Vamos a recrearlo de esta manera:
x - A - B*- C''
| |
| master
|
origin/master
Este es el procedimiento:
git checkout B # get working-tree to the state of commit B
git reset --soft A # tell git that we are working before commit B
git checkout -b rewrite-history # switch to a new branch for our alternative history
Mejora tu compromiso anterior usando git add
(ahora git add -i
, git stash
etc.). Incluso puedes dividir tu antiguo compromiso en dos o más.
git commit # recreate commit B (result = B*)
git cherry-pick C # copy C to our new branch (result = C'')
Resultado intermedio:
x - A - B - C
| / |
| / master
| /
| B*- C''
| |
| rewrite-history
|
origin/master
Terminemos:
git checkout master
git reset --hard rewrite-history # make this branch master
Eso es todo, puedes push
tu progreso ahora.
Podrías usar git rebase
para reescribir el historial de commit. Esto puede ser potencialmente destructivo para sus cambios, por lo tanto, use con cuidado.
Primero cometa su cambio de "enmienda" como una confirmación normal. A continuación, realice una rebase interactiva comenzando en el padre de su compromiso más antiguo
git rebase -i 47175e84c2cb7e47520f7dde824718eae3624550^
Esto activará tu editor con todos los commits. Reordenarlos para que su confirmación de "enmienda" sea inferior a la que desea modificar. Luego reemplace la primera palabra en la línea con la confirmación "modificar" con s
que combinará ( s quash) con la confirmación anterior. Guarde y salga de su editor y siga las instrucciones.
Preparé mi compromiso que quería modificar con uno anterior y me sorprendí al ver que rebase -i se quejó de que no había realizado ningún cambio. Pero no quería volver a hacer los cambios para especificar la opción de edición de la confirmación anterior. Entonces la solución fue bastante fácil y directa:
- prepara tu actualización para la confirmación anterior, agrégala y confirma
-
git rebase -i <commit you want to amend>^
- observe el^
para que vea dicho commit en el editor de texto Obtendrás algo así:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies pick e23d23a fix indentation of jgroups.xml
ahora para combinar e23d23a con 8c83e24 puede cambiar el orden de las líneas y usar squash de esta manera:
pick 8c83e24 use substitution instead of separate subsystems file to avoid jgroups.xml and jgroups-e2.xml going out of sync squash e23d23a fix indentation of jgroups.xml pick 799ce28 generate ec2 configuration out of subsystems-ha.xml and subsystems-full-ha.xml to avoid discrepancies
escribe y sale del archivo, estarás presente con un editor para fusionar los mensajes de confirmación. Hazlo y guarda / sal del documento de texto
- Has terminado, tus commits son enmendados
el crédito va a: http://git-scm.com/book/en/Git-Tools-Rewriting-History También hay otra magia git demostrada útil.
Puedes usar git rebase --interactive
, usando el comando de edit
en la confirmación que deseas modificar.
git rebase -i HEAD^^^
Ahora marque los que desee modificar con edit
o e
(reemplace pick
). Ahora guarda y sal.
Ahora haga sus cambios, luego
git add -A
git commit --amend --no-edit
git rebase --continue
Si desea agregar una eliminación adicional, elimine las opciones del comando de confirmación. Si quiere ajustar el mensaje, omita solo la --no-edit
.