Come annullare un commit git locale


744

Il mio problema è che ho modificato un file, ad esempio: README, ho aggiunto una nuova riga " questa per la mia linea di test " e ho salvato il file, quindi ho emesso i seguenti comandi

 git status

 # On branch master
 # Changed but not updated:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #  modified:   README
 #
 no changes added to commit (use "git add" and/or "git commit -a")


 git add README

 git commit -a -m 'To add new line to readme'

Non ho inviato il codice a github, ora voglio annullare questo commit.

Per questo ho usato

   git reset --hard HEAD~1

Ma ho perso la riga appena aggiunta ' this for my test line ' dal file README. Questo non dovrebbe succedere. Ho bisogno del contenuto per essere lì. C'è un modo per conservare il contenuto e annullare il mio commit locale?


3
Sembra che tu non lo stia sicuramente chiedendo git revert, il che crea un nuovo commit con il diff inverso del commit ripristinato. Il ripristino punta semplicemente il ramo corrente a un commit diverso, in questo caso, quello precedente al commit che si desidera "dimenticare".
Cascabel,

1
NB: Potrebbe valere la pena ricordare che git-commitpuò essere interrotto se si lascia il messaggio vuoto, quindi se non si è effettivamente terminato il commit potrebbe essere utile.
GKFX,

Risposte:


1423

Basta usare git resetsenza la --hardbandiera:

git reset HEAD~1

PS: Su sistemi basati su Unix è possibile utilizzare un valore HEAD^uguale a HEAD~1. Su Windows HEAD^non funzionerà perché ^segnala una continuazione della linea. Quindi il tuo prompt dei comandi ti chiederà semplicemente More?.


13
A proposito, questo è chiamato --mixed nel manuale .
Josh Lee,

10
Le versioni più recenti di Git consentono anche @^come scorciatoia per HEAD^.
Koraktor,

Non so cosa sia successo, ma molti file sono stati visualizzati nell'elenco delle modifiche, file che non ho toccato
FRR

@feresr Se davvero non hai toccato quei file nell'ultimo commit o nell'albero di lavoro questo è causato da altre incongruenze nell'albero di lavoro, ad esempio sei su Windows e le terminazioni dei file non corrispondono.
Koraktor,

1
è possibile ripristinare tutto il commit da un lato?
Webwoman

185

Usa --softinvece di --hardflag:

git reset --soft HEAD^

18
puoi spiegare la differenza tra le 2 bandiere?
John Giotta,

1
Se apri la Console di gestione pacchetti ed esegui questo "git reset --soft HEAD ^", fa quello che vuoi (e quello che mi serviva).
David Cornelson,

54
@JohnGiotta - git reset --soft HEAD^rimuoverà l'ultimo commit locale (non scaricato) ma manterrà le modifiche che hai fatto
fider

@fider Savior! Non sono sicuro che la risposta accettata funzioni ancora, ma questa dovrebbe essere la risposta esatta richiesta dall'OP.
Babu,

git reset --soft HEAD~su windows
Jack0fshad0ws

34

Se sei nel mezzo di un commit (ovvero già nel tuo editor), puoi annullarlo eliminando tutte le righe sopra la prima #. Ciò interromperà il commit.

Quindi puoi eliminare tutte le righe in modo che il messaggio di commit sia vuoto, quindi salva il file:

Dovrebbe sembrare come questo.

Riceverai quindi un messaggio che dice Aborting commit due to empty commit message..

MODIFICA :

Puoi anche eliminare tutte le righe e il risultato sarà esattamente lo stesso.

Per eliminare tutte le righe in vim (se quello è l'editor predefinito), una volta che sei nell'editor, digita ggper andare alla prima riga, quindi dGper eliminare tutte le righe. Infine, scrivi ed esci dal file wqe il tuo commit verrà interrotto.


3
Questo è esattamente quello che stavo cercando! Questa risposta richiede più voti :)
jdunk l'

Cordiali saluti, questo funziona anche se stai cercando di interrompere unrebase -i mybranchname
inostia il

18

La prima cosa da fare è determinare se si desidera mantenere le modifiche locali prima di eliminare il messaggio di commit.

Utilizzare git logper mostrare i messaggi di commit correnti, quindi trovare commit_id prima il commit che si desidera eliminare, non il commit che si desidera eliminare.

Se si desidera conservare i file modificati localmente ed eliminare il messaggio di commit:

git reset --soft commit_id

Se si desidera eliminare tutti i file modificati localmente e il messaggio di commit:

git reset --hard commit_id

Questa è la differenza tra morbido e duro


1
Penso che sia il contrario.
Ruff9

9

Puoi dire a Git cosa fare con il tuo indice (insieme di file che diventeranno il prossimo commit) e la directory di lavoro quando esegui git reset usando uno dei parametri:

--soft: Verranno ripristinati solo i commit, mentre Index e la directory di lavoro non verranno modificati.

--mixed: Questo ripristinerà l'indice in modo che corrisponda a HEAD, mentre la directory di lavoro non verrà toccata. Tutte le modifiche rimarranno nella directory di lavoro e verranno visualizzate come modificate.

--hard: Reimposta tutto (commit, indice, directory di lavoro) in modo che corrisponda a HEAD.

Nel tuo caso, vorrei utilizzare git reset --softper mantenere le modifiche modificate nell'indice e nella directory di lavoro. Assicurati di controllare questo per una spiegazione più dettagliata.


1

Usa il comando seguente:

$ git reset HEAD~1

Dopo questo è anche possibile visualizzare i file che ritornano come sotto la risposta.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
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.