Cómo agregar un archivo modificado a una confirmación anterior (no la última) en Git

Resuelto leen asked hace 14 años • 7 respuestas

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?

leen avatar Apr 27 '10 14:04 leen
Aceptado

Usar git rebase. Específicamente:

  1. Úselo git stashpara almacenar los cambios que desea agregar.
  2. Úselo git rebase -i HEAD~10(o cuantas confirmaciones desee ver).
  3. Marque la confirmación en cuestión ( a0865...) para editarla cambiando la palabra pickal comienzo de la línea a edit. No elimine las otras líneas, ya que eso eliminaría las confirmaciones.[^vimnote]
  4. Guarde el archivo de rebase y git volverá al shell y esperará a que arregle esa confirmación.
  5. Explota el alijo usando git stash pop.
  6. Añade tu archivo con git add <file>.
  7. Modifique el compromiso con git commit --amend --no-edit.
  8. Haga algo git rebase --continueque reescribirá el resto de sus confirmaciones con la nueva.
  9. Repita desde el paso 2 en adelante si ha marcado más de una confirmación para editar.
  10. Si anteriormente envió las confirmaciones modificadas a otro lugar, tendrá que presionar --forcenuevamente para actualizarlas en el control remoto. Sin embargo, se aplican las advertencias habituales sobre el uso --forcey 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 :wqpara 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".

Greg Hewgill avatar Apr 27 '2010 08:04 Greg Hewgill

Para "arreglar" una confirmación anterior con un pequeño cambio, sin cambiar el mensaje de confirmación de la confirmación anterior, donde OLDCOMMIThay algo como 091b73a:

git add <my fixed files>
git commit --fixup=OLDCOMMIT
git rebase --interactive --autosquash OLDCOMMIT^

También puede utilizarlo git commit --squash=OLDCOMMITpara 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=OLDCOMMITcopia el OLDCOMMITmensaje de confirmación y le pone un prefijo automáticamente fixup!para que pueda colocarse en el orden correcto durante la rebase interactiva. ( --squash=OLDCOMMIThace lo mismo pero con prefijos squash!).
  • git rebase --interactiveAparecerá 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 ( :wqenvim ) para continuar con la rebase.
  • --autosquashpondrá automáticamente cualquier --fixup=OLDCOMMITconfirmación en el orden correcto. Tenga en cuenta que --autosquashsólo es válido cuando --interactivese utiliza la opción.
  • El ^inOLDCOMMIT^ significa que es una referencia a la confirmación justo antes OLDCOMMIT. ( OLDCOMMIT^es el primer padre de OLDCOMMIT).

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_EDITORde 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.
Joel Purra avatar Dec 31 '2014 12:12 Joel Purra

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 --autosquashpara arreglar tu compromiso

knittl avatar Apr 27 '2010 08:04 knittl

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

aljabadi avatar Apr 20 '2021 05:04 aljabadi