Domanda Come annullare 'git add' prima di eseguire il commit?


Ho erroneamente aggiunto file a git usando il comando:

git add myfile.txt

Non ho ancora eseguito git commit. C'è un modo per annullare questo, quindi questi file non saranno inclusi nel commit?


Ci sono finora 48 risposte (alcune cancellate). Si prega di non aggiungerne uno nuovo se non si hanno nuove informazioni.


7447
2017-12-07 21:57


origine


risposte:


Puoi annullare git add prima di impegnarsi con

git reset <file>

che lo rimuoverà dall'indice corrente (l'elenco "in procinto di essere impegnato") senza cambiare altro.

Puoi usare

git reset

senza alcun nome di file per rimuovere tutte le modifiche dovute. Questo può tornare utile quando ci sono troppi file da elencare uno per uno in un ragionevole lasso di tempo.

Nelle vecchie versioni di Git, i comandi precedenti sono equivalenti a git reset HEAD <file> e git reset HEAD rispettivamente, e falliranno se HEAD è indefinito (perché non hai ancora commesso alcun commit nel tuo repository) o ambiguo (perché hai creato un ramo chiamato HEAD, che è una cosa stupida che non dovresti fare). Questo è stato modificato in Git 1.8.2 , tuttavia, così nelle versioni moderne di Git puoi usare i comandi precedenti anche prima di fare il tuo primo commit:

"git reset" (senza opzioni o parametri) utilizzato per errore quando      non hai alcun commit nella tua cronologia, ma ora ti dà      un indice vuoto (per abbinare il commit inesistente su cui non sei nemmeno on).


8355
2017-12-07 22:30



Tu vuoi:

git rm --cached <added_file_to_undo>

Ragionamento:

Quando ero nuovo, ho provato per la prima volta

git reset .

(per annullare la mia intera aggiunta iniziale), solo per ottenere questo (non così) messaggio utile:

fatal: Failed to resolve 'HEAD' as a valid ref.

Si scopre che questo è dovuto al fatto che HEAD ref (branch?) Non esiste fino a dopo il primo commit. Cioè, ti imbatterai nello stesso problema del principiante come me se il tuo flusso di lavoro, come il mio, fosse qualcosa del tipo:

  1. cd alla mia grande nuova directory di progetto per provare Git, il nuovo hotness
  2. git init
  3. git add .
  4. git status

    ... un sacco di pergamene per ...

    => Accidenti, non volevo aggiungere tutto questo.

  5. google "annulla git add"

    => trova Stack Overflow - yay

  6. git reset .

    => fatale: impossibile risolvere "HEAD" come riferimento valido.

Si scopre inoltre che c'è un bug registrato  contro l'inutilità di questo nella mailing list.

E che la soluzione corretta era proprio lì nell'output di stato Git (che, sì, ho sorvolato come "schifo")

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

E la soluzione è davvero da usare git rm --cached FILE.

Nota gli avvertimenti qui altrove - git rm cancella la tua copia di lavoro locale del file, ma non  se usi --cached . Ecco il risultato di git help rm:

--cached       Utilizzare questa opzione per rimuovere e rimuovere i percorsi solo dall'indice.       I file dell'albero di lavoro, modificati o meno, saranno lasciati.

Procedo ad usare

git rm --cached .

rimuovere tutto e ricominciare. Non ha funzionato però, perché mentre add . è ricorsivo, risulta rm esigenze -r per recitare. Sospiro.

git rm -r --cached .

Ok, ora sono tornato a dove ho iniziato. La prossima volta che userò -n fare una corsa a secco e vedere cosa verrà aggiunto:

git add -n .

Ho chiuso tutto in un posto sicuro prima di fidarmi git help rm riguardo a --cached non distruggere nulla (e cosa succede se l'ho sbagliato a scrivere).


1950
2018-03-25 16:20



Se si digita:

git status

git ti dirà cosa è messo in scena, ecc., incluse le istruzioni su come disimballare:

use "git reset HEAD <file>..." to unstage

Trovo che git faccia un buon lavoro a spingermi a fare la cosa giusta in situazioni come questa.

Nota: le versioni git recenti (1.8.4.x) hanno cambiato questo messaggio:

(use "git rm --cached <file>..." to unstage)

484
2017-12-07 23:22



Chiarire: git add sposta le modifiche dalla directory di lavoro corrente a area di sosta  (indice).

Questo processo è chiamato messa in scena . Quindi il comando più naturale per palcoscenico  le modifiche (file modificati) sono ovvi:

git stage

git add è solo un più facile da digitare alias per git stage

Peccato che non ci sia git unstage né git unadd comandi. Quello rilevante è più difficile da indovinare o ricordare, ma è abbastanza ovvio:

git reset HEAD --

Possiamo facilmente creare un alias per questo:

git config --global alias.unadd 'reset HEAD --'
git config --global alias.unstage 'reset HEAD --'

E infine, abbiamo nuovi comandi:

git add file1
git stage file2
git unadd file2
git unstage file1

Personalmente uso anche alias più brevi:

git a #for staging
git u #for unstaging

220
2017-09-10 20:28



Un'aggiunta alla risposta accettata, se il tuo file aggiunto erroneamente fosse enorme, probabilmente te ne accorgerai, anche dopo averlo rimosso dall'indice con ' git reset', sembra ancora occupare spazio nel .git directory. Questo non è nulla di cui preoccuparsi, il file è effettivamente ancora nel repository, ma solo come "oggetto libero", non verrà copiato in altri repository (tramite clone, push) e lo spazio verrà infine recuperato - sebbene forse non molto presto. Se sei ansioso, puoi eseguire:

git gc --prune=now

Aggiornare  (Quello che segue è il mio tentativo di chiarire una certa confusione che può sorgere dalle risposte più votate):

Quindi, qual è il vero disfare  di git add?

git reset HEAD <file> ?

o

git rm --cached <file>?

A rigor di termini, e se non mi sbaglio: nessuna .

git add  non può essere non fatto  - in sicurezza, in generale.

Ricordiamo prima cosa git add <file> in realtà fa:

  1. Se <file> era non precedentemente monitorato , git add  lo aggiunge alla cache , con il suo contenuto attuale.

  2. Se <file> era già tracciato , git add  salva il contenuto corrente  (istantanea, versione) nella cache. In GIT, questa azione è ancora chiamata Inserisci , (non semplice aggiornare  it), perché due diverse versioni (istantanee) di un file sono considerate due elementi diversi: quindi, stiamo effettivamente aggiungendo un nuovo elemento alla cache, per essere eventualmente commesso in seguito.

Alla luce di ciò, la domanda è leggermente ambigua:

Ho erroneamente aggiunto file usando il comando ...

Lo scenario dell'OP sembra essere il primo (file non tracciato), vogliamo che "undo" rimuova il file (non solo il contenuto corrente) dagli elementi tracciati. Se  questo è il caso, quindi è ok per correre git rm --cached <file>.

E potremmo anche correre git reset HEAD <file>. Questo è generalmente preferibile, perché funziona in entrambi gli scenari: fa anche l'annullamento quando abbiamo aggiunto erroneamente una versione di un oggetto già tracciato.

Ma ci sono due avvertimenti.

Primo: C'è (come sottolineato nella risposta) solo uno scenario in cui git reset HEAD non funziona, ma git rm --cached fa: un nuovo repository (nessun commit). Ma, davvero, questo è un caso praticamente irrilevante.

Secondo: essere consapevoli di questo git reset HEAD  non è in grado di recuperare magicamente il contenuto del file precedentemente memorizzato, lo risincronizza semplicemente dall'HEAD. Se il nostro fuorviato git add ha sovrascritto una versione precedente non salvata, non possiamo ripristinarla. Ecco perché, in senso stretto, non possiamo annullare.

Esempio:

$ git init
$ echo "version 1" > file.txt
$ git add file.txt   # first add  of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add  file.txt   # stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt   
$ git diff  file.txt
-version 2
+version 3
$ git add  file.txt    # oops we didn't mean this
$ git reset HEAD file.txt  # undo ?
$ git diff --cached file.txt  # no dif, of course. stage == HEAD
$ git diff file.txt   # we have lost irrevocably "version 2"
-version 1
+version 3

Naturalmente, questo non è molto critico se seguiamo il solito flusso di lavoro pigro di fare 'git add' solo per aggiungere nuovi file (caso 1), e aggiorniamo nuovi contenuti tramite il commit, git commit -a comando.


136
2018-05-18 18:05



git rm --cached . -r

"annulla" tutto ciò che hai aggiunto dalla tua directory corrente in modo ricorsivo


85
2017-12-09 21:19



Correre

git gui

e rimuovere tutti i file manualmente o selezionandoli tutti e facendo clic su disimpegnare dal commit  pulsante.


77
2017-10-12 01:12



Git ha comandi per ogni azione immaginabile, ma ha bisogno di una conoscenza approfondita per fare le cose per bene e per questo è al massimo intuitivo ...

Cosa hai fatto prima:

  • Modificato un file e usato git add ., o git add <file>.

Ciò che vuoi:

  • Rimuovi il file dall'indice, ma mantienilo aggiornato e lasciato con modifiche non vincolate nella copia di lavoro:

    git reset head <file>
    
  • Ripristina il file all'ultimo stato da HEAD, annullando le modifiche e rimuovendole dall'indice:

    # Think `svn revert <file>` IIRC.
    git reset HEAD <file>
    git checkout <file>
    
    # If you have a `<branch>` named like `<file>`, use:
    git checkout -- <file>
    

    Questo è necessario da allora git reset --hard HEAD non funzionerà con singoli file.

  • Rimuovere <file> dall'indice e dal controllo delle versioni, mantenendo il file non versione con le modifiche nella copia di lavoro:

    git rm --cached <file>
    
  • Rimuovere <file> dalla copia di lavoro e dal controllo delle versioni completamente:

    git rm <file>
    

73
2018-03-29 11:14