Annulla la messa in scena di un file eliminato in git


504

Di solito, per annullare le modifiche a un file, è necessario:

git checkout -- <file>

Cosa succede se la modifica che desidero annullare sta eliminando il file? La riga sopra darebbe un errore:

error: pathspec '<file>' did not match any file(s) known to git.

Quale comando ripristinerà quel singolo file senza annullare altre modifiche?

punto bonus: Inoltre, cosa succede se la modifica che voglio scartare è l' aggiunta di un file? Vorrei sapere anche come annullare la messa in scena di quel cambiamento.


1
Annullare le modifiche e annullare la messa in scena sono due cose diverse, che cosa stai cercando di fare?
Andrew Marshall,

1
Sono due domande e problemi diversi in un post. Questo rende le risposte troppo e inutilmente confuse.
David Sopko,

Risposte:


779

Supponendo che tu voglia annullare gli effetti di git rm <file>o rm <file>seguito da git add -Ao qualcosa di simile:

# this restores the file status in the index
git reset -- <file>
# then check out a copy from the index
git checkout -- <file>

Per annullare git add <file>, la prima riga sopra è sufficiente, supponendo che non ti sia ancora impegnata.


70
Questa --è la chiave. git reset <file>non funziona, che è ciò che mi ha portato qui.

2
Perché è end-of-options-markerrichiesto solo nel caso del file eliminato?
Haridsv,

5
@handsv Non è strettamente necessario (si potrebbe alternativamente fare git reset HEAD <file>, che è equivalente), ma git resettratta il suo primo argomento prima end-of-options-markercome un nome di riferimento, non come un nome di file. Potrebbe essere scritto un po 'più flessibile? Probabilmente. Perché no? Probabilmente lo sanno solo gli sviluppatori.
twalberg,

2
@twalberg git reset filenamefunziona bene per i file non eliminati.
Brian Gordon,

1
@AaronMahan - puoi per favore spiegare la differenza tra git reset <file>e git reset -- <file>. Sto facendo fatica a trovare una risposta su Google.
Neeraj B.

56

Ad entrambe le domande viene data risposta git status.

Per annullare la creazione di un nuovo file, utilizzare git rm --cached filename.ext

# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   test

Per annullare l'eliminazione di un file utilizzare git reset HEAD filename.ext

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    test

D'altra parte, git checkout --mai in scena, scarta solo le modifiche non organizzate.


5
Non vedo il suggerimento per un file cancellato in git 1.7.2.5 su Debian.
Tripleee,

Bello vedere git statuscitati; mostra agli utenti un modo di auto-aiuto ora e la prossima volta e nel caso in cui le informazioni vengano aggiunte o aggiornate nelle future versioni di git.
Will Caino

Questo è sbagliato. "Modifiche da impegnare" è ciò che vedi prima del git reset. Dopo il git reset, apparirà "Modificato ma non aggiornato" che significa "Modifiche non messe in scena" nella lingua nativa degli autori git, apparentemente. Ancora più importante, l'intero dogma sullo "stato git ti dice tutto quello che sai" è una bugia. (I manager che affermano che stanno sprecando il tempo delle persone e dovrebbero essere licenziati.)
personal_cloud

11

Le risposte alle tue due domande sono correlate. Inizierò con il secondo:

Dopo aver messo in scena un file (spesso con git add, anche se alcuni comandi implicitamente mettono in scena anche le modifiche, come git rm) è possibile annullare tale modifica con git reset -- <file>.

Nel tuo caso devi aver usato git rmper rimuovere il file, il che equivale a rimuoverlo semplicemente rme quindi a mettere in scena quella modifica. Se lo toglii dal palco per la prima volta, git reset -- <file>puoi recuperarlo con git checkout -- <file>.


7

Se è stato messo in scena e eseguito il commit, il seguente reimposterà il file:

git reset COMMIT_HASH file_path
git checkout COMMIT_HASH file_path
git add file_path

Questo funzionerà per una cancellazione che si è verificata in diversi commit precedenti.


1
È più efficientegit revert COMMIT_HASH
Flair,

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.