¿Cómo modificar la última confirmación para eliminar un archivo?

108

He modificado dos archivos a, ben el último commit. Pero el archivo bno debe confirmarse, ¿cuál es el flujo de trabajo para modificar esto?

Xiè Jìléi
fuente

Respuestas:

109

Actualización (un par de años después)

Jan Hudec

Es trivial eliminarlo solo del índice.

Verdadero: puede restablecer un archivo a su contenido de índice con bastante facilidad, como sugiere la respuesta más reciente (escrita por Matt Connolly ):

git reset HEAD^ path/to/file/to/revert

HEAD^permite que el archivo acceda a su contenido en la confirmación anterior antes de la última.

Entonces puedes git commit --amend, como originalmente escribí a continuación.


Con Git 2.23 (agosto de 2019), puede usar el nuevo git restorecomando

 git restore --source=HEAD^ --staged  -- path/to/file/to/revert

más corta:

 git restore -s@^ -S -- path/to/file/to/revert

De nuevo, puedes hacerlo git commit --amend, como originalmente escribí a continuación.


Respuesta original (enero de 2011)

Si esta es su última confirmación (y no la ha empujado a ninguna parte), puede modificarla :
(primer escondite o guardar b)

 git commit --amend

Luego elimine b, vuelva a confirmar. Restaura b y listo.

--amend

Se utiliza para modificar la punta de la rama actual.
Prepare el objeto de árbol en el que desea reemplazar la última confirmación como de costumbre (esto incluye las rutas habituales -i / -o y explícitas), y el editor de registro de confirmación se siembra con el mensaje de confirmación desde la punta de la rama actual.
La confirmación que crea reemplaza la sugerencia actual; si se trata de una fusión, tendrá los padres de la sugerencia actual como padres, por lo que se descarta la confirmación principal actual.

VonC
fuente
... Then stash/delete b, re-commit.., Aquí no debe la palabra Thenser after? - --amendafter stach / delete b, ...
Xiè Jìléi
@ 谢 继 雷: en otras palabras, guarde b primero, luego confirme --amend, luego restaure. Cierto. He actualizado la respuesta.
VonC
Con el poder del índice git, decirle a cualquiera que guarde / guarde el archivo es simplemente una tontería (-1). Es trivial eliminarlo solo del índice.
Jan Hudec
1
@ JanHudec Es cierto, he editado la respuesta en consecuencia. No seguí esa vieja respuesta tan de cerca como lo hago en Stack Overflow. El 99% de las preguntas de git en SU ​​deben migrarse en SO de todos modos.
VonC
66
  1. git diff --name-only HEAD^ - (opcional) se usa para enumerar los archivos que cambiaron en la última confirmación.
  2. git reset HEAD^ path/to/file/to/revert- para restablecer el índice a esa última versión, dejando la copia de trabajo intacta.
  3. git commit --amend- para modificar ese último compromiso para incluir los cambios del índice
Matt Connolly
fuente
99
En mi opinión, es una respuesta mucho mejor que la aceptada.
mik01aj
1
Tenga en cuenta que no debe usar git commit -a --amend(es decir, no agregar archivos) para el paso 3, o confirmará los cambios de la copia de trabajo, que son las ediciones que está tratando de eliminar. Un paso opcional 2.5 podría ser también git checkout path/to/file/to/revertlimpiar su copia de trabajo.
dmnd
1
Alternativamente, git rm --cached path/to/file/to/revertpuede eliminar el archivo sin eliminarlo del árbol.
Jan Hudec
13

Alternativamente, si está utilizando git gui, simplemente seleccione la opción "Modificar la última confirmación", el archivo agregado aparece en la lista "En etapas", haga clic en su icono para moverlo a la lista "No en escena" y confirme.

Jan Hudec
fuente
1
@VonC: la edición y división de parches es una operación bastante común para usuarios pesados ​​de git, por lo que la interfaz gráfica de usuario fue diseñada para facilitarlo y es la mejor herramienta de la OMI para ello.
Jan Hudec
Ese funciona! No tuve éxito con otras opciones para esa tarea en particular. ¡Gracias por el consejo!
Serguzest
10

Si quieres eliminar b de tu último commit

git rm --cached b (will preserve the file in the working tree but remove it from the index)
git commit --amend

Si desea eliminar todos los cambios a b en su última confirmación

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)
pingo
fuente
git rm --cachedy eliminar el baile de copia de seguridad / restauración (-1).
Jan Hudec
Gracias por señalar eso. Quería compartir cómo hice esto porque este fue el enfoque con el que me sentí más cómodo incluso después de leer todo el hilo.
pingo
4

Una alternativa que no requiere piratería de índices, pero que conserva el antiguo mensaje de confirmación:

$ git reset HEAD^
$ git add <all the files you want, excluding the one you don't want>
$ git commit -C HEAD@{1}

Me gusta esto porque (a) usa comandos que uso regularmente y (b) puedo hacer git add -ppara averiguar exactamente qué es lo que quiero comprometer.

Justin L.
fuente