Cómo agregar un archivo modificado a una confirmación anterior (no la última) en Git
Cambié varias cosas durante la última hora y las comprometí paso a paso, pero me acabo de dar cuenta de que olvidé agregar un archivo modificado hace algunas confirmaciones.
El registro se ve así:
GIT TidyUpRequests u:1 d:0> git log
commit fc6734b6351f6c36a587dba6dbd9d5efa30c09ce
Author: David Klein <>
Date: Tue Apr 27 09:43:55 2010 +0200
The Main program now tests both Webservices at once
commit 8a2c6014c2b035e37aebd310a6393a1ecb39f463
Author: David Klein <>
Date: Tue Apr 27 09:43:27 2010 +0200
ISBNDBQueryHandler now uses the XPath functions from XPath.fs too
commit 06a504e277fd98d97eed4dad22dfa5933d81451f
Author: David Klein <>
Date: Tue Apr 27 09:30:34 2010 +0200
AmazonQueryHandler now uses the XPath Helper functions defined in XPath.fs
commit a0865e28be35a3011d0b6091819ec32922dd2dd8 <--- changed file should go here
Author: David Klein <>
Date: Tue Apr 27 09:29:53 2010 +0200
Factored out some common XPath Operations
¿Algunas ideas?
Usar git rebase
. Específicamente:
- Úselo
git stash
para almacenar los cambios que desea agregar. - Úselo
git rebase -i HEAD~10
(o cuantas confirmaciones desee ver). - Marque la confirmación en cuestión (
a0865...
) para editarla cambiando la palabrapick
al comienzo de la línea aedit
. No elimine las otras líneas, ya que eso eliminaría las confirmaciones.[^vimnote] - Guarde el archivo de rebase y git volverá al shell y esperará a que arregle esa confirmación.
- Explota el alijo usando
git stash pop
. - Añade tu archivo con
git add <file>
. - Modifique el compromiso con
git commit --amend --no-edit
. - Haga algo
git rebase --continue
que reescribirá el resto de sus confirmaciones con la nueva. - Repita desde el paso 2 en adelante si ha marcado más de una confirmación para editar.
- Si anteriormente envió las confirmaciones modificadas a otro lugar, tendrá que presionar
--force
nuevamente para actualizarlas en el control remoto. Sin embargo, se aplican las advertencias habituales sobre el uso--force
y puedes perder fácilmente el trabajo de otras personas si no tienes cuidado y no te coordinas con ellas de antemano.
[^vimnote]: Si lo está utilizando vim
, tendrá que presionar la Inserttecla para editar, luego Escescribir :wq
para guardar el archivo, salir del editor y aplicar los cambios. Alternativamente, puedes configurar un editor de confirmación de git fácil de usar con git config --global core.editor "nano"
.
Para "arreglar" una confirmación anterior con un pequeño cambio, sin cambiar el mensaje de confirmación de la confirmación anterior, donde OLDCOMMIT
hay algo como 091b73a
:
git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^
También puede utilizarlo git commit --squash=OLDCOMMIT
para editar el mensaje de confirmación anterior durante la rebase.
Consulte la documentación para git commit y git rebase . Como siempre, al reescribir el historial de git , solo debes corregir o eliminar las confirmaciones que aún no hayas publicado para nadie más (incluidos los usuarios aleatorios de Internet y los servidores de compilación).
Explicación detallada
git commit --fixup=OLDCOMMIT
copia elOLDCOMMIT
mensaje de confirmación y le pone un prefijo automáticamentefixup!
para que pueda colocarse en el orden correcto durante la rebase interactiva. (--squash=OLDCOMMIT
hace lo mismo pero con prefijossquash!
).git rebase --interactive
Aparecerá un editor de texto (que se puede configurar ) para confirmar (o editar) la secuencia de instrucciones de rebase . Hay información para cambios de instrucciones de rebase en el archivo; simplemente guarde y salga del editor (:wq
envim
) para continuar con la rebase.--autosquash
pondrá automáticamente cualquier--fixup=OLDCOMMIT
confirmación en el orden correcto. Tenga en cuenta que--autosquash
sólo es válido cuando--interactive
se utiliza la opción.- El
^
inOLDCOMMIT^
significa que es una referencia a la confirmación justo antesOLDCOMMIT
. (OLDCOMMIT^
es el primer padre deOLDCOMMIT
).
Automatización opcional
Los pasos anteriores son buenos para verificar y/o modificar la secuencia de instrucciones de rebase , pero también es posible omitir/automatizar el editor de texto de rebase interactivo mediante:
- Configuración
GIT_SEQUENCE_EDITOR
de un script . - Crear un alias de git para eliminar automáticamente todas las correcciones en cola.
- Crear un alias de git para arreglar automáticamente una única confirmación.
con git 1.7, hay una manera realmente fácil de usar git rebase
:
organiza tus archivos:
git add $files
cree una nueva confirmación y reutilice el mensaje de confirmación de su confirmación "rota"
git commit -c master~4
anteponga fixup!
en la línea de asunto (o squash!
si desea editar la confirmación (mensaje)):
fixup! Factored out some common XPath Operations
úsalo git rebase -i --autosquash
para arreglar tu compromiso
Aquí hay una función que implementa la respuesta de @Greg:
function gitamendoldcommit() {
printf "\n\nPress any key if you have no changes other than those you want to add to $1."
printf "(You can commit your unwanted changes and undo later.):\n\n"
read foo
printf "\n\nChange 'pick' to 'edit' in front of $1 (top one), save, close the editor & press any key..."
printf "Resolve any possible conflicts, if any. then: git add .; git rebase --continue\n\n"
git rebase -i $1^
git stash pop
git add .
git commit --amend --no-edit
git rebase --continue
}
Uso: (teniendo solo los cambios previstos en la puesta en escena)gitamendoldcommit $OLDCOMMIT