Domanda

Ho erroneamente aggiunto file a git usando il comando:

git add myfile.txt

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

È stato utile?

Soluzione

Puoi annullare git add prima di eseguire il commit con

git reset <file>

che lo rimuoverà dall'indice corrente (l'elenco &; sta per essere impegnato ") senza cambiare nient'altro.

Puoi usare

git reset

senza alcun nome di file per mettere in scena tutte le modifiche dovute. Questo può tornare utile quando ci sono troppi file per essere elencati uno per uno in un ragionevole lasso di tempo.

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

  

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

Altri suggerimenti

Desideri:

git rm --cached <added_file_to_undo>

Ragionamento:

Quando ero nuovo, ho provato per la prima volta

git reset .

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

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

Si scopre che ciò è dovuto al fatto che il riferimento HEAD (branch?) non esiste fino a dopo il primo commit. Cioè, incontrerai lo stesso problema del mio principiante se il tuo flusso di lavoro, come il mio, fosse qualcosa del tipo:

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

    ... molte pergamene di ...

    &

    = gt; Accidenti, non volevo aggiungere tutto questo.

  5. google " annulla git add "

    &

    = gt; trova Stack Overflow - yay

  6. git reset .

    &

    = gt; fatale: impossibile risolvere "HEAD" come riferimento valido

Si scopre inoltre che c'è un bug registrato contro la scarsità di ciò nella mailing list.

E che la soluzione corretta era proprio lì nell'output dello stato di Git (che, sì, ho lucidato 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 avvisi qui altrove - git rm elimina la copia di lavoro locale del file, ma non se si utilizza --cached . Ecco il risultato di git help rm:

  

- Copia cache       Utilizzare questa opzione per rimuovere la scena e rimuovere i percorsi solo dall'indice.       I file dell'albero di lavoro, modificati o meno, verranno lasciati.

Procedo all'uso

git rm --cached .

per rimuovere tutto e ricominciare. Tuttavia, non ha funzionato, perché mentre add . è ricorsivo, risulta che rm ha bisogno di -r di ricorrere. Sigh.

git rm -r --cached .

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

git add -n .

Ho zippato tutto in un posto sicuro prima di fidarmi di --cached sul <=> non distruggere nulla (e cosa succede se lo scrivessi male).

Se si digita:

git status

git ti dirà che cosa è in scena, ecc., comprese le istruzioni su come rimuovere la scena:

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

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

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

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

Per chiarire: git add sposta le modifiche dalla directory di lavoro corrente alla area di gestione temporanea (indice).

Questo processo è chiamato stadiazione . Quindi il comando più naturale per mettere in scena le modifiche (file modificati) è quello ovvio:

git stage

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

Peccato che non ci siano git unadd né <=> 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 alias anche più brevi:

git a #for staging
git u #for unstaging

Un'aggiunta alla risposta accettata, se il tuo file aggiunto per errore era enorme, probabilmente noterai che, anche dopo averlo rimosso dall'indice con 'git reset', sembra ancora occupare spazio nel .git directory. Non c'è nulla di cui preoccuparsi, il file è davvero ancora nel repository, ma solo come & Quot; oggetto sciolto & Quot ;, non verrà copiato in altri repository (tramite clone, push) e lo spazio verrà infine recuperato, anche se forse non molto presto. Se sei ansioso, puoi eseguire:

git gc --prune=now

Aggiorna (quello che segue è il mio tentativo di eliminare un po 'di confusione che può derivare dalle risposte più votate):

Quindi, qual è il vero annulla di git add?

git reset HEAD <file>?

o

git rm --cached <file>?

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

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

Ricordiamo innanzitutto cosa fa <file>:

  1. Se git reset HEAD non è stato precedentemente rintracciato , git rm --cached lo aggiunge alla cache , con il suo contenuto attuale.

  2. Se git commit -a era già tracciato , <=> salva il contenuto corrente (istantanea, versione) nella cache. In GIT, questa azione è ancora chiamata aggiungi , (non solo aggiorna ), perché due diverse versioni (istantanee) di un file sono considerate come due elementi diversi: quindi, stiamo davvero aggiungendo un nuovo elemento alla cache, che alla fine verrà eseguito il commit 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 il " undo " per rimuovere il file (non solo il contenuto corrente) dagli elementi monitorati. Se questo è il caso, allora è possibile eseguire <=>.

E potremmo anche eseguire <=>. Questo è generalmente preferibile, perché funziona in entrambi gli scenari: fa anche l'annullamento quando abbiamo erroneamente aggiunto una versione di un elemento già tracciato.

Ma ci sono due avvertimenti.

Primo: esiste (come sottolineato nella risposta) solo uno scenario in cui <=> non funziona, ma <=> funziona: un nuovo repository (nessun commit). Ma, davvero, questo è un caso praticamente irrilevante.

Secondo: tenere presente che <=> non è in grado di ripristinare magicamente il contenuto del file precedentemente memorizzato nella cache, ma lo risincronizza semplicemente da HEAD. Se il nostro errore <=> ha sovrascritto una versione non messa in scena precedente non salvata, non possiamo recuperarla. Ecco perché, a rigore, 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 comando commit, <=>.


* (Modifica: quanto sopra è praticamente corretto, ma possono esserci ancora modi leggermente hackerati / contorti per recuperare le modifiche messe in scena ma non impegnate e poi sovrascritte - vedere i commenti di Johannes Matokic e iolsmit)

git rm --cached . -r

sarà " un-add " tutto ciò che hai aggiunto dalla tua directory corrente in modo ricorsivo

Annulla un file che è già stato aggiunto è abbastanza semplice utilizzando git , per ripristinare myfile.txt quali già aggiunti, utilizzare:

git reset HEAD myfile.txt

Spiegare:

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

Creo i passaggi nell'immagine seguente per maggiori dettagli, inclusi tutti i passaggi che possono verificarsi in questi casi:

 git ripristina il file HEAD

Esegui

git gui

e rimuovi tutti i file manualmente o selezionandoli tutti e facendo clic sul pulsante unstage from commit .

Git ha comandi per ogni azione immaginabile, ma ha bisogno di una conoscenza approfondita per ottenere le cose giuste e per questo è contro-intuitivo nella migliore delle ipotesi ...

Cosa hai fatto prima:

  • È stato modificato un file e utilizzato git add . o git add <file>.

Quello che vuoi:

  • Rimuovi il file dall'indice, ma mantienilo aggiornato e lasciato con modifiche senza commit 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>
    

    Ciò è necessario poiché git reset --hard HEAD non funzionerà con file singoli.

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

    git rm --cached <file>
    
  • Rimuovi <=> dalla copia funzionante e dal controllo delle versioni:

    git rm <file>
    

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

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

in caso di dubbio, utilizzare

git reset HEAD file

Perché fa la cosa prevista in entrambi i casi.

Avviso: se si esegue git commit su un file che è stato modificato (un file che esisteva prima nel repository), il file verrà rimosso su < =>! Esisterà ancora nel tuo file system, ma se qualcun altro tira il tuo commit, il file verrà eliminato dal suo albero 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

Se stai eseguendo il commit iniziale e non puoi utilizzare git reset, dichiara solo " Git bankruptcy " ed elimina la .git cartella e ricomincia da capo

Come per molte altre risposte puoi usare git reset

MA:

Ho trovato questo piccolo post che in realtà aggiunge il comando Git (bene un alias) per git unadd: vedi git unadd per dettagli o ..

Semplicemente,

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

Ora puoi

git unadd foo.txt bar.txt

git remove o git rm possono essere usati per questo, con il flag --cached. Prova:

git help rm

Usa git add -i per rimuovere i file appena aggiunti dal tuo prossimo commit. Esempio:

Aggiunta del file non desiderato:

$ git add foo
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]#

Entrando in add interattivo per annullare l'aggiunta (i comandi digitati su git qui sono " r " (ripristina), " 1 " (prima voce nella list revert shows), 'return' per uscire dalla modalità di ripristino e " q " (quit):

$ git add -i
           staged     unstaged path
  1:        +1/-0      nothing foo

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> r
           staged     unstaged path
  1:        +1/-0      nothing [f]oo
Revert>> 1
           staged     unstaged path
* 1:        +1/-0      nothing [f]oo
Revert>> 
note: foo is untracked now.
reverted one path

*** Commands ***
  1: [s]tatus     2: [u]pdate     3: [r]evert     4: [a]dd untracked
  5: [p]atch      6: [d]iff       7: [q]uit       8: [h]elp
What now> q
Bye.
$

Questo è tutto! Ecco la tua prova, dimostrando che & Quot; foo & Quot; è tornato nell'elenco non tracciato:

$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# [...]
#       foo
nothing added to commit but untracked files present (use "git add" to track)
$

Ecco un modo per evitare questo fastidioso problema 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).
  • Salva il tuo file .gitignore.

Git rende davvero difficile fare git reset se non hai alcun commit. Se crei un piccolo commit iniziale solo per averne uno, dopo puoi git add -A e <=> tutte le volte che vuoi per ottenere tutto nel modo giusto.

Un altro vantaggio di questo metodo è che se riscontri problemi di fine riga in seguito e devi aggiornare tutti i tuoi file, è facile:

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

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

$> git --version
git version 1.6.2.1

Ora puoi provare:

git reset HEAD .

Questo dovrebbe essere quello che stai cercando.

Se non riesci a specificare una revisione, devi 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>

(git versione 1.7.5.4)

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

git rm --cached FILE

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

Per ripristinare tutti i file in una determinata cartella (e le sue sottocartelle), è possibile utilizzare il seguente comando:

git reset *

usa il comando * per gestire più file alla volta

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

etc

Basta digitare git reset tornerà indietro ed è come se non avessi mai digitato git add . dall'ultimo commit. Assicurati di esserti impegnato prima.

Supponiamo di creare un nuovo file newFile.txt.

 inserisci qui la descrizione dell'immagine

Supponiamo di aggiungere il file accidentalmente, git add newFile.txt

 inserisci qui la descrizione dell'immagine

Ora voglio annullare questa aggiunta, prima del commit, git reset newFile.txt

 inserisci qui la descrizione dell'immagine

Per un file specifico:

  
      
  • git reset my_file.txt
  •   
  • checkout git my_file.txt
  •   

Per tutti i file aggiunti:

  
      
  • reset git.
  •   
  • checkout git.
  •   

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

Questo comando annullerà le modifiche apportate:

git reset HEAD filename.txt

Puoi anche usare

git add -p 

per aggiungere parti di file.

Sono sorpreso che nessuno menzioni la modalità interattiva:

git add -i

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

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

File di staging

Per annullare git aggiungi usa

git reset filename

git reset filename.txt

Rimuoverà un file chiamato nomefile.txt dall'indice corrente, il " sta per essere impegnato " area, senza cambiare nient'altro.

git add myfile.txt # questo aggiungerà il tuo file all'elenco di commit

È esattamente l'opposto di questo comando,

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

quindi, sarai nello stato precedente. specificato verrà nuovamente nell'elenco non tracciato (stato precedente).

ripristinerà la tua testa con quel file specificato. quindi, se la tua testa non lo ha, significa che la ripristinerà semplicemente

In SourceTree puoi farlo facilmente tramite la GUI. Puoi controllare quale comando utilizza sourcetree per annullare la messa in scena di un file.

Ho creato un nuovo file e l'ho aggiunto a Git. Quindi l'ho messo in scena usando la GUI di SourceTree. Questo è il risultato:

  

File non di scena [08/12/15 10:43]
  git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - percorso / to / file / nomefile.java

SourceTree utilizza reset per mettere in scena i nuovi file.

Una delle soluzioni più intuitive sta usando SourceTree .

Puoi semplicemente trascinare e rilasciare i file da fasi e non inserisci qui la descrizione dell'immagine

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top