Come modificare l'ultimo commit per annullare l'aggiunta di un file?


108

Ho modificato due file a, bnell'ultimo commit. Ma il file bnon deve essere sottoposto a commit, qual è il flusso di lavoro per modificarlo?

Risposte:


109

Aggiornamento (un paio d'anni dopo)

Jan Hudec

È banale rimuoverlo solo dall'indice.

Vero: puoi reimpostare un file sul contenuto dell'indice abbastanza facilmente, come suggerisce la risposta più recente (scritta da Matt Connolly ):

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

HEAD^consente al file di accedere al suo contenuto nel commit precedente prima dell'ultimo.

Quindi puoi git commit --amend, come ho scritto in origine di seguito.


Con Git 2.23 (agosto 2019), potresti usare il nuovo git restorecomando

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

più breve:

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

Ancora una volta, è possibile git commit --amend, come ho scritto in origine di seguito.


Risposta originale (gennaio 2011)

Se questo è il tuo ultimo commit (e non lo hai spinto da nessuna parte), puoi modificarlo :
(prima scorta o salvataggio b)

 git commit --amend

Quindi eliminare b, ripetere il commit. Ripristina b e il gioco è fatto.

--amend

Utilizzato per modificare la punta del ramo corrente.
Preparare l'oggetto albero che si desidera sostituire l'ultimo commit come al solito (questo include i soliti percorsi -i / -o ed espliciti) e l'editor del registro di commit viene eseguito il seeding con il messaggio di commit dalla punta del ramo corrente.
Il commit che crei sostituisce il suggerimento corrente - se si trattava di una fusione, i genitori del suggerimento corrente saranno i genitori - quindi l'attuale commit superiore viene scartato.


... Then stash/delete b, re-commit.., Qui non dovrebbe il termine Thenessere after? - --amenddopo lo stach / elimina b, ...
Xiè Jìléi il

@ 谢 继 雷: in altre parole, prima salva b, poi commetti - modifica, quindi ripristina? Vero. Ho aggiornato la risposta.
VonC,

Con la potenza dell'indice git, dire a chiunque di nascondere / salvare il file è semplicemente stupido (-1). È banale rimuoverlo solo dall'indice.
Jan Hudec,

1
@JanHudec Vero, ho modificato la risposta di conseguenza. Non ho seguito quella vecchia risposta da vicino come faccio su Stack Overflow. Il 99% delle domande git su SU dovrebbe comunque essere migrato su SO.
VonC,

66
  1. git diff --name-only HEAD^ - (facoltativo) consente di elencare i file modificati nell'ultimo commit.
  2. git reset HEAD^ path/to/file/to/revert- per ripristinare l' indice sull'ultima versione, lasciando intatta la copia di lavoro.
  3. git commit --amend- modificare l'ultimo commit per includere le modifiche dell'indice

9
Imho, è una risposta molto migliore di quella accettata.
mik01aj,

1
Nota che non dovresti usare git commit -a --amend(cioè non aggiungere file) per il passaggio 3, altrimenti commetterai le modifiche alla copia di lavoro che sono le modifiche che stai cercando di rimuovere. Un passaggio 2.5 facoltativo potrebbe essere git checkout path/to/file/to/revertquello di ripulire anche la tua copia di lavoro.
DMND

1
In alternativa, git rm --cached path/to/file/to/revertper annullare l'aggiunta del file senza eliminarlo dall'albero.
Jan Hudec,

13

In alternativa, se si sta utilizzando git gui, è sufficiente selezionare l'opzione "Modifica ultimo commit", il file aggiunto viene visualizzato nell'elenco "Staged", fare clic sull'icona corrispondente per spostarlo nell'elenco "Unstaged" e eseguire il commit.


1
@VonC: Modificare e dividere le patch è un'operazione abbastanza comune per gli utenti git pesanti, quindi la GUI è stata progettata per renderlo semplice ed è il miglior strumento IMO per questo.
Jan Hudec,

Quello funziona! Non ho avuto successo con altre opzioni per quel particolare compito. Grazie per il consiglio!
Serguzest,

10

Se si desidera eliminare b dall'ultimo commit

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

Se si desidera rimuovere tutte le modifiche a b nell'ultimo commit

(backup b)
(modify b to state before incorrect commit)
git commit --amend
(restore b)

git rm --cachede elimina la danza di backup / restore (-1).
Jan Hudec,

Grazie per la segnalazione. Volevo condividere come ho fatto perché questo era l'approccio con cui mi sentivo più a mio agio anche dopo aver letto l'intero thread.
pingo,

4

Un'alternativa che non richiede l'hacking dell'indice, ma conserva comunque il vecchio messaggio di commit:

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

Mi piace perché (a) usa i comandi che uso regolarmente e (b) posso fare git add -pper capire esattamente cosa voglio commettere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.