Come posso rimuovere nuovamente la messa in scena dei miei file dopo aver eseguito un commit locale?


268

Ho eseguito il seguente comando

git add <foo.java>
git commit -m "add the foo.java file"

Come posso cancellare il mio commit locale adesso e rimuovere il palco da foo.java?

Se digito git reset --hard, ho scoperto che ripristina il mio modificato foo.javaa quello originale.

Risposte:


452

git reset --soft HEAD~1dovrebbe fare quello che vuoi. Dopodiché, avrai le prime modifiche nell'indice (visibile con git diff --cached) e le tue ultime modifiche non verranno messe in scena. git statussarà quindi simile a questo:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

È quindi possibile eseguire git add foo.javae eseguire il commit di entrambe le modifiche contemporaneamente.


Ho modificato la risposta: "Modifiche da impegnare" hanno le prime modifiche e "modifiche non messe in scena per il commit" hanno le seconde modifiche.
Antti,

4
Ciò che è descritto in questa risposta è in realtà ciò che git commit --amendfa; ma con un flusso di lavoro molto più complicato. Questo non risponde alla domanda posta dall'OP, nonostante abbia dato una buona direzione ( git reset).
7heo.tk,

2
Ho dovuto sostituire il '^' con un '~' per farlo funzionare, quindi sembra:git reset --soft HEAD~
Shahar

3
do git reset --soft HEAD ~ 1 quindi git reset HEAD
Joko Wandiro

risposta perfetta a ciò che voglio!
DeepInJava

78

Uso:

git reset HEAD^

Questo fa un reset "misto" di default, che farà quello che hai chiesto; mettere foo.java in unstaged, rimuovendo il commit più recente.


2
Ti dispiacerebbe spiegarmi cos'è il ripristino "misto", il ripristino "soft" e il ripristino "hard"?
Kit Ho

1
@Kit Il manuale di ripristino di Ho - git contiene eccellenti descrizioni di questi.
manojlds,

4
@Kit, @manojlds: Così fa stackoverflow.com/questions/2530060/... (spudorato)
Cascabel

5
Questa è in realtà l'unica risposta corretta . Le altre due risposte metteranno di nuovo in scena i file dopo aver effettuato un commit.
7heo.tk,

git reset --softnon ha funzionato, ma git reset HEAD^ha funzionato
parole povere il

43

Per me, il seguente è il modo più leggibile (quindi preferibile) per farlo:

git reset HEAD~1

Invece 1, potrebbe esserci un numero qualsiasi di commit che vuoi mettere in scena.


39

git reset --softè solo per quello: è come git reset --hard, ma non tocca i file.


4
Questa è stata la spiegazione più facilmente comprensibile che abbia mai sentito (in sole 11 parole)! Grazie!
phreakhead

3
Quella risposta è sbagliata. git reset"è come git reset --hardma non tocca i file.". Non git reset --soft. git reset --softmetterà in scena le modifiche, quindi non dovrai aggiungerle alla messa in scena nel caso tu voglia impegnarle, ma dovrai farlo con git resetloro (sì, una seconda volta e senza il --soft) nel caso non lo facessi. Quindi quella risposta è breve, ma errata.
7heo.tk,

12

Per annullare la messa in scena di tutti i file nell'ultimo commit -

git reset HEAD~


8

"Ripristina" è il modo per annullare le modifiche localmente. Quando esegui il commit, devi prima selezionare le modifiche da includere con " git add ", che si chiama "staging". E una volta che le modifiche sono state messe in scena, le " git commit ".

Per uscire dalla messa in scena o dal commit, è necessario "ripristinare" HEAD. Su un ramo, HEAD è una variabile git che punta al commit più recente. Quindi, se hai messo in scena ma non ti sei impegnato, devi " resettare HEAD ". Ciò supporta l'attuale HEAD eliminando i cambiamenti dal palco. È l'abbreviazione di " git reset --mixed HEAD ~ 0 ".

Se hai già eseguito il commit, HEAD è già avanzato, quindi è necessario eseguire il backup del commit precedente. Qui " resetti HEAD ~ 1 " o " resetta HEAD ^ 1 " o " resetta HEAD ~ " o " resetta HEAD ^ " - tutti i riferimenti HEAD meno uno.

Qual è il simbolo migliore, ~ o ^? Pensa alla ~ tilde come a un singolo flusso : quando ogni commit ha un solo genitore ed è solo una serie di modifiche in sequenza, puoi fare riferimento al backup del flusso usando la tilde, come HEAD ~ 1, HEAD ~ 2, HEAD ~ 3, per genitore, nonno, bisnonno, ecc. (Tecnicamente sta trovando il primo genitore nelle generazioni precedenti).

Quando c'è un'unione, i commit hanno più di un genitore. Questo è quando il ^ cursore entra in gioco - puoi ricordare perché mostra i rami che si uniscono. Usando il cursore, HEAD ^ 1 sarebbe il primo genitore e HEAD ^ 2 sarebbe il secondo genitore di un singolo commit - madre e padre, per esempio.

Quindi, se stai solo tornando indietro di un hop su un commit monoparentale, allora HEAD ~ e HEAD ^ sono equivalenti - puoi usare uno dei due.

Inoltre, il ripristino può essere --soft , --mixed o --hard . Un soft reset esegue il backout del commit: ripristina HEAD, ma non estrae i file dal commit precedente, quindi tutte le modifiche nella directory di lavoro vengono mantenute. E --soft reset non cancella nemmeno lo stage (noto anche come indice ), quindi tutti i file messi in scena saranno ancora sullo stage.

Un reset --mix (predefinito) non controlla anche i file dal commit precedente, quindi tutte le modifiche vengono mantenute, ma lo stage viene cancellato. Ecco perché un semplice " git reset HEAD " cancella il palco.

Un - duro reset ripristina HEAD e cancella lo stage, ma verifica anche tutti i file dal commit precedente e quindi sovrascrive eventuali modifiche.

Se hai eseguito il push del commit in un repository remoto, il reset non funziona così bene. Puoi resettare localmente, ma quando provi a spingere sul telecomando, git vedrà che la tua HEAD locale è dietro HEAD nel ramo remoto e rifiuterà di spingere. Potresti essere in grado di forzare la spinta, ma a Git non piace davvero farlo.

In alternativa, è possibile archiviare le modifiche se si desidera mantenerle, controllare il commit precedente, annullare l'archiviazione delle modifiche, metterle in scena, creare un nuovo commit e quindi inviarlo.


+1 per la spiegazione dettagliata dell'operazione. IMO questa dovrebbe essere la risposta accettata!
ISAE,

2

Supponiamo che tu voglia mettere in scena le modifiche fino a n commit,

Dove gli hash di commit sono i seguenti:

  • h1
  • h2 ...
  • hn
  • hn + 1

Quindi eseguire il comando seguente:
git reset hn

Ora HEAD sarà a hn + 1. Le modifiche da h1 a hn non verranno messe in scena.

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.