git - ultimo - pull request cos è




Come annullare 'git add' prima di eseguire il commit? (20)

Come per molte altre risposte, puoi usare git reset

MA:

Ho trovato questo piccolo post che aggiunge effettivamente il comando Git (beh un alias) per git unadd : vedi git unadd per i dettagli o ..

Semplicemente,

git config --global alias.unadd "reset HEAD"

Ora puoi

git unadd foo.txt bar.txt

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.


Correre

git gui

e rimuovere tutti i file manualmente o selezionandoli tutti e facendo clic sul pulsante non rilascia dal pulsante di commit .


Ecco un modo per evitare questo problema irritante quando si avvia un nuovo progetto:

  • Crea la directory principale per il tuo nuovo progetto.
  • Esegui git init .
  • Ora crea un file .gitignore (anche se è vuoto).
  • Configura il tuo file .gitignore.

Git rende davvero difficile fare il git reset se non si hanno commit. Se crei un piccolo commit iniziale solo per il gusto di averne uno, dopo puoi git add -A e git reset tutte le volte che vuoi per avere tutto a posto.

Un altro vantaggio di questo metodo è che se ci si imbatte in problemi di fine riga in seguito e si ha bisogno di aggiornare tutti i file, è facile:

  • Controlla quel commit iniziale. Questo rimuoverà tutti i tuoi file.
  • Quindi controlla di nuovo il commit più recente. Ciò recupererà nuove copie dei tuoi file, usando le tue attuali impostazioni di fine riga.

Forse Git si è evoluto da quando hai postato la tua domanda.

$> git --version
git version 1.6.2.1

Ora puoi provare:

git reset HEAD .

Questo dovrebbe essere quello che stai cercando.


La domanda non è chiaramente posta. La ragione è che git add ha due significati:

  1. aggiungendo un nuovo file all'area di staging, quindi annullare con git rm --cached file .
  2. aggiungendo un file modificato all'area di staging, quindi annullare con il git reset HEAD file .

in caso di dubbio, utilizzare

git reset HEAD file

Perché fa la cosa prevista in entrambi i casi.

Attenzione: se si esegue git rm --cached file su un file che è stato modificato (un file preesistente nel repository), il file verrà rimosso su git commit ! Esisterà ancora nel tuo file system, ma se qualcun altro prende il tuo commit, il file verrà cancellato dalla loro struttura di lavoro.

git status ti dirà se il file era un nuovo file o modificato :

On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   my_new_file.txt
    modified:   my_modified_file.txt

Per annullare git aggiungi uso

git reset filename


Per rimuovere nuovi file dall'area di gestione temporanea (e solo in caso di un nuovo file), come suggerito sopra:

git rm --cached FILE

Usa rm --cached solo per i nuovi file aggiunti per sbaglio.


Per ripristinare tutti i file in una particolare cartella (e le relative sottocartelle), puoi usare il seguente comando:

git reset *

Questo comando annulla le modifiche:

git reset HEAD filename.txt

Puoi anche usare

git add -p 

aggiungere parti di file.


Se sei sul tuo commit iniziale e non puoi usare git reset, basta dichiarare "Git bankruptcy" ed eliminare la cartella .git e ricominciare da capo


Si noti che se non si specifica una revisione, è necessario includere un separatore. Esempio dalla mia console:

git reset <path_to_file>
fatal: ambiguous argument '<path_to_file>': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

git reset -- <path_to_file>
Unstaged changes after reset:
M   <path_to_file>

(versione git 1.7.5.4)


Sono sorpreso che nessuno menzioni la modalità interattiva:

git add -i

scegli l'opzione 3 per aggiungere i file. Nel mio caso, spesso desidero aggiungere più di un file, con la modalità interattiva è possibile utilizzare numeri come questo per aggiungere file. Questo prenderà tutto tranne 4: 1,2,3,5

Per scegliere una sequenza basta digitare 1-5 per prendere tutto da 1 a 5.

Git file di gestione temporanea


Tu vuoi:

git rm --cached <added_file_to_undo>

Ragionamento:

Quando ero nuovo a questo, 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 - 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 in effetti è 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 che rm bisogno di -r recitare. Sospiro.

git rm -r --cached .

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

git add -n .

Ho chiuso tutto in un posto sicuro prima di --cached git help rm a --cached non distruggendo nulla (e se l'avessi scritto male).


Un'aggiunta alla risposta accettata, se il file aggiunto erroneamente era enorme, probabilmente noterete che, anche dopo averlo rimosso dall'indice con ' git reset ', sembra ancora occupare spazio nella directory .git . 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

Aggiornamento (ciò che segue è il mio tentativo di chiarire una certa confusione che può derivare dalle risposte più votate):

Quindi, qual è il vero annullamento di git add ?

git reset HEAD <file> ?

o

git rm --cached <file> ?

A rigor di termini, e se non sbaglio: nessuno .

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

Ricordiamo innanzitutto cosa git add <file> realtà:

  1. Se <file> non è stato tracciato in precedenza , git add aggiunge alla cache , con il suo contenuto corrente.

  2. Se <file> è già stato tracciato , git add salva il contenuto corrente (istantanea, versione) nella cache. In GIT, questa azione è ancora chiamata add , (non è un semplice aggiornamento ), perché due diverse versioni (istantanee) di un file sono considerate due elementi diversi: quindi, stiamo effettivamente aggiungendo un nuovo elemento alla cache, per essere infine impegnato più tardi.

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, allora è ok per eseguire git rm --cached <file> .

E potremmo anche eseguire 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 del fatto che git reset HEAD non può recuperare magicamente il contenuto del file precedentemente memorizzato, lo risincronizza semplicemente dall'HEAD. Se il nostro git add fuorviato ha sovrascritto una versione precedente non salvata, non possiamo recuperarla. 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

Ovviamente, 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 comando commit, git commit -a .

* (Modifica: quanto sopra è praticamente corretto, ma ci possono essere alcuni modi un po 'hacker / complicati per recuperare le modifiche che sono state messe in scena ma non impegnate e poi sovrascritte - vedi i commenti di Johannes Matokic e iolsmit)


usa il comando * per gestire più file alla volta

git reset HEAD *.prj
git reset HEAD *.bmp
git reset HEAD *gdb*

eccetera


git add myfile.txt # per aggiungere il tuo file alla lista dei commit

Al contrario di questo comando,

git reset HEAD myfile.txt  # this will undo it. 

così, sarai nello stato precedente. specificato sarà nuovamente nell'elenco non tracciato (stato precedente).

resetterà la tua testa con quel file specificato. quindi, se la tua testa non ce l'ha significa, lo ripristinerà semplicemente


Annullare un file che è già stato aggiunto è abbastanza semplice usando git , per resettare myfile.txt che ha già aggiunto, usa:

git reset HEAD myfile.txt

Spiegare:

Dopo aver messo in scena i file indesiderati, per annullare, puoi eseguire il git reset , Head è la testa del tuo file in locale e l'ultimo parametro è il nome del tuo file.

Creo i passaggi nell'immagine sottostante in ulteriori dettagli per te, compresi tutti i passaggi che possono accadere in questi casi:


Per un file specifico:

  • git resetta my_file.txt
  • git checkout my_file.txt

Per tutti i file aggiunti:

  • git reset.
  • git checkout.

Nota: il checkout cambia il codice nei file e passa all'ultimo stato (commit) aggiornato. il reset non cambia i codici; semplicemente resetta l'intestazione.


git reset filename.txt

Rimuoverà un file denominato nomefile.txt dall'indice corrente, l'area "in procinto di essere impegnata", senza cambiare altro.


git reset filename.txt  

Rimuoverà un file denominato nomefile.txt dall'indice corrente, l'area "in procinto di essere impegnata", senza cambiare altro.







git-stage