it-swarm-eu.dev

Jak vrátit 'git add' před spácháním?

Omylem jsem přidal soubory do příkazu git pomocí příkazu:

git add myfile.txt

git commit jsem ještě nespustil. Existuje způsob, jak to vrátit, takže tyto soubory nebudou zahrnuty do odevzdání?


Dosud existuje 48 odpovědí (některé vypuštěny). Nepřidávejte nové, pokud nemáte nějaké nové informace.

8101
paxos1977

Před potvrzením pomocí příkazu git add můžete vrátit zpět

git reset <file>

který ji odstraní z aktuálního indexu (seznam "o tom, že bude spáchán"), aniž by změnil cokoli jiného.

Můžeš použít

git reset

bez jakéhokoliv názvu souboru, chcete-li zrušit všechny příslušné změny. To se může hodit, když je příliš mnoho souborů, které mají být v rozumném množství uvedeny jeden po druhém.

Ve starých verzích Gitu jsou výše uvedené příkazy ekvivalentní s git reset HEAD <file> a git reset HEAD a nezdaří, pokud je HEAD nedefinováno (protože jste ještě neučinili žádné závazky ve vašem repo) nebo dvojznačné (protože jste vytvořili větev nazvanou HEAD, která je hloupá věc, kterou byste neměli dělat. Tento byl změněn v Git 1.8.2 , nicméně, v moderních verzích Gitu můžete použít příkazy výše i před provedením vašeho prvního potvrzení:

"git reset" (bez možností nebo parametrů) slouží k chybě, když nemáte ve vaší historii žádné potvrzení, ale nyní vám dává prázdný index (aby odpovídaly neexistujícímu potvrzení, že nejste ani zapnuti).

9181
genehack

Ty chceš:

git rm --cached <added_file_to_undo>

Uvažování:

Když jsem k tomu byla nová, snažila jsem se

git reset .

(chcete-li vrátit zpět celé své počáteční přidání), pouze pro získání této (ne) užitečné zprávy:

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

Ukazuje se, že je to proto, že HEAD ref (větev?) Neexistuje až po prvním potvrzení. To znamená, že narazíte na stejný problém začátečníka jako já, pokud váš pracovní postup, jako je můj, byl něco jako:

  1. cd do mého velkého nového adresáře projektu vyzkoušet Git, nové žhavosti
  2. git init
  3. git add .
  4. git status

    ... spousta svinutí kecy ...

    => Sakra, nechtěla jsem to všechno přidat.

  5. google "přidat zpět"

    => najít přetečení zásobníku - yay

  6. git reset .

    => fatal: Nepodařilo se vyřešit 'HEAD' jako platné ref.

Dále se ukáže, že je chyba zaprotokolována proti neužitečnosti v seznamu adresátů.

A že správné řešení bylo právě ve výstupním stavu Git (což jsem přece jen označil za „blbost“)

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

A řešením je skutečně použití git rm --cached FILE.

Všimněte si varování jinde - git rm vymaže místní pracovní kopii souboru, ale ne pokud používáte --cached . Výsledek git help rm:

--cached Tato volba slouží k odpojení a odstranění cest pouze z indexu. Pracovní stromové soubory, ať už upravené nebo ne, budou ponechány.

I nadále používat

git rm --cached .

odstranit vše a začít znovu. Nefungovalo však, protože zatímco add . je rekurzivní, ukazuje rm potřeby -r k recitaci. Povzdech.

git rm -r --cached .

Dobře, teď jsem zpátky tam, kde jsem začal. Příště budu používat -n na suché běh a uvidím, co bude přidáno:

git add -n .

Zapamatoval jsem si vše na bezpečné místo před důvěřováním git help rm o --cached, které nic nezničí (a co když jsem to chybně napsal).

2047
Rhubarb

Pokud zadáte:

git status

git vám řekne, co je inscenováno, atd., včetně instrukcí, jak postupovat:

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

Zjistil jsem, že git dělá docela dobrou práci, že mě to nutí dělat správné věci v takovýchto situacích.

Poznámka: Poslední verze git (1.8.4.x) tuto zprávu změnily:

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

Pro objasnění: git add přesune změny z aktuálního pracovního adresáře do pracovní oblasti (index).

Tento proces se nazývá staging . Takže nejpřirozenější příkaz do fáze změny (změněné soubory) je zřejmý:

git stage

git add je jen jednodušší alias pro git stage

Škoda, že neexistuje žádné git unstage ani git unadd příkazy. Příslušný je těžší uhodnout nebo si pamatovat, ale je zcela zřejmý:

git reset HEAD --

Pro tento účel můžeme snadno vytvořit alias:

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

A konečně máme nové příkazy:

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

Osobně používám i kratší aliasy:

git a #for staging
git u #for unstaging
238
takeshin

Kromě přijaté odpovědi, pokud byl váš omylem přidaný soubor obrovský, pravděpodobně si všimnete, že i po jeho odstranění z indexu s 'git reset' se stále zdá, že zabírá místo v adresáři .git. To není nic, čeho by se mělo bát, soubor je stále ještě v úložišti, ale pouze jako "volný objekt", nebude kopírován do jiných repozitářů (přes klon, Push) a prostor bude nakonec rekultivován - i když možná ne příliš brzy. Pokud jste nervózní, můžete spustit:

git gc --Prune=now

Aktualizace (následuje můj pokus o odstranění nějakého zmatku, který může vyplynout z nejvíce odhlasovaných odpovědí):

Takže, což je reálné undo of git add?

git reset HEAD <file>?

nebo

git rm --cached <file>?

Přísně vzato, a pokud se nemýlím: žádný .

git add nemůže být vráceno - bezpečně, obecně.

Připomeňme si nejprve, co vlastně git add <file> dělá:

  1. Pokud <file> bylo nebylo dříve sledováno , git add přidá jej do cache , s jeho aktuálním obsahem.

  2. Pokud bylo <file> již sledováno , git add uloží aktuální obsah (snímek, verze) do mezipaměti. V GIT se tato akce stále nazývá add , (ne pouhá update it), protože dvě různé verze (snímky) souboru jsou považovány za dvě různé položky: proto přidáváme skutečně novou položku do mezipaměti, která bude nakonec přijata později.

Vzhledem k tomu je otázka poněkud nejednoznačná:

Omylem jsem přidal soubory pomocí příkazu ...

Scénář OP se jeví jako první (nepozorovaný soubor), chceme, aby "undo" odstranil soubor (nejen aktuální obsah) ze sledovaných položek. Pokud je to tento případ, pak je v pořádku spustit git rm --cached <file>.

Můžeme také spustit git reset HEAD <file>. To je obecně vhodnější, protože funguje v obou scénářích: také dělá zpět, když jsme nesprávně přidali verzi již sledované položky.

Existují však dvě výhrady.

Za prvé: Existuje (jak je uvedeno v odpovědi) pouze jeden scénář, ve kterém git reset HEAD nefunguje, ale git rm --cached dělá: nový repozitář (bez povelů). Ale ve skutečnosti je to prakticky irelevantní případ.

Za druhé: Uvědomte si, že git reset HEAD nemůže magicky obnovit dříve uložený obsah souboru, pouze jej znovu synchronizuje z HEAD. Pokud naše pomýlené git add přepsalo předchozí zprovozněnou verzi, nemůžeme ji obnovit. Proto nemůžeme striktně hovořit [*].

Příklad:

$ 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

Samozřejmě, že to není příliš kritické, pokud dodržujeme obvyklý líný pracovní postup, který dělá 'git add' pouze pro přidávání nových souborů (případ 1), a aktualizujeme nový obsah příkazem commit, git commit -a.


* (Edit: výše uvedené je prakticky správné, ale stále mohou existovat nějaké mírně hackerské/spletité způsoby, jak obnovit změny, které byly inscenovány, ale nebyly spáchány a poté přepsány - viz komentáře Johannesa Matokiče a iolsmit)

161
leonbloy
git rm --cached . -r

bude "un-add" vše, co jste přidali z aktuálního adresáře rekurzivně

91
braitsch

Běh

git gui

a odstranit všechny soubory ručně nebo výběrem všech a kliknutím na tlačítko unstage z tlačítka commit .

85
Khaja Minhajuddin

Undo soubor, který již byl přidán, je poměrně snadné pomocí git , pro resetování myfile.txt, které již bylo přidáno, použijte:

git reset HEAD myfile.txt

Vysvětlete:

Poté, co jste vytvořili nepotřebné soubory, vrátíte se zpět, můžete udělat git reset, Head je hlava vašeho souboru v lokálním souboru a poslední parametr je název vašeho souboru.

Kroky v níže uvedeném obrázku vytvořím podrobněji pro vás, včetně všech kroků, které mohou nastat v těchto případech:

 git reset HEAD file

82
Alireza

Git má příkazy pro každou akci, kterou si lze představit, ale potřebuje rozsáhlé znalosti, aby se věci dostali správně, a proto je v nejlepším případě kontra-intuitivní ...

Co jste udělali dříve:

  • Změnil soubor a použil git add . nebo git add <file>.

Co chceš:

  • Odstraňte soubor z indexu, ale ponechte jej ve verzi a ponechte s nezávaznými změnami v pracovní kopii:

    git reset head <file>
    
  • Obnovit soubor do posledního stavu z HEAD, vrátit změny a odstranit je z indexu:

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

    To je nutné, protože git reset --hard HEAD nebude fungovat s jednotlivými soubory.

  • Odebrat soubor <file> z indexu a verzí a ponechat soubor bez verze se změnami v pracovní kopii:

    git rm --cached <file>
    
  • Odebrat <file> z pracovní kopie a verzí zcela:

    git rm <file>
    
80
sjas

Otázka není jasně položena. Důvodem je to, že git add má dva významy:

  1. přidání nového souboru do pracovní oblasti, pak zpět s git rm --cached file.
  2. přidání upraveného souboru do pracovní oblasti, pak zpět s git reset HEAD file.

v případě pochybností použijte

git reset HEAD file

Protože to dělá v obou případech očekávanou věc.

Upozornění: pokud uděláte git rm --cached file na souboru, který byl upraven (soubor, který existoval dříve v úložišti), pak bude soubor odstraněn v souboru git commit! Bude stále existovat ve vašem souborovém systému, ale pokud někdo jiný vytáhne váš závazek, soubor bude vymazán z jejich pracovního stromu.

git status vám řekne, zda byl soubor nový soubor nebo upraven :

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
71
Michael_Scharf

Pokud jste na svém počátečním potvrzení a nemůžete použít git reset, stačí prohlásit "Git bankruptcy" a smazat složku .git a začít znovu

61
Paul Betts

Na mnoho dalších odpovědí můžete použít git reset

VUT:

Našel jsem tento skvělý post, který ve skutečnosti přidává příkaz Git (dobře alias) pro git unadd: viz git unadd pro podrobnosti nebo ..

Jednoduše,

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

Teď můžeš

git unadd foo.txt bar.txt
55
electblake

git remove nebo git rm může být použito pro tento účel pomocí příznaku --cached. Snaž se:

git help rm
46
gnud

Použijte git add -i k odstranění právě přidaných souborů z vašeho nadcházejícího potvrzení. Příklad:

Přidání souboru, který jste nechtěli:

$ 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)
# [...]#

Přechod do interaktivního přidávání pro vrácení vašeho přidání (příkazy zadané na stránce git zde jsou „r“ (vrátit se), „1“ (první položka v seznamu se vrátí k přehlídkám), „vrátit se“ a opustí režim vrácení a „q“ (přestat):

$ 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.
$

A je to! Zde je váš důkaz, který ukazuje, že "foo" je zpět na seznamu nezaškrtnutých:

$ 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)
$
42
Alex North-Keys

Zde je způsob, jak se vyhnout tomuto znepokojujícímu problému při spuštění nového projektu:

  • Vytvořte hlavní adresář pro nový projekt.
  • Spustit git init.
  • Nyní vytvořte soubor .gitignore (i když je prázdný).
  • Spusťte soubor .gitignore.

Git dělá to opravdu těžké dělat git reset jestliže vy nemáte žádné závazky. Pokud vytvoříte drobný úvodní závazek jen kvůli tomu, abyste ho měli, pak můžete git add -A a git reset tolikrát, kolikrát chcete, aby bylo vše v pořádku.

Další výhodou této metody je, že pokud se později dostanete do problémů s koncem řádku a potřebujete aktualizovat všechny soubory, je to snadné:

  • Podívejte se na ten počáteční závazek. Tím odstraníte všechny soubory.
  • Pak se znovu podívejte na svůj poslední závazek. Tím se načtou nové kopie souborů pomocí aktuálního nastavení konce řádků.
37
Ryan Lundy

Možná se od té doby, co jste odeslali svou otázku, vyvinula Git.

$> git --version
git version 1.6.2.1

Nyní můžete vyzkoušet:

git reset HEAD .

To by mělo být to, co hledáte.

33
Kokotte23

Všimněte si, že pokud se vám nepodaří specifikovat revizi, musíte zahrnout oddělovač. Příklad z konzoly:

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>

(verze git 1.7.5.4)

33
powlo

Jak odstranit nové soubory z pracovní oblasti (a pouze v případě nového souboru), jak je uvedeno výše:

git rm --cached FILE

Použijte rm --cached pouze pro nové soubory omylem přidané.

30
Ran

Chcete-li obnovit všechny soubory v určité složce (a jejích podsložkách), můžete použít následující příkaz:

git reset *
24
Zorayr

použijte příkaz * ke zpracování více souborů najednou

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

atd

24
boulder_ruby

Stačí zadat git reset vrátí se zpět a je to jako byste nikdy nezadali git add . od posledního potvrzení. Ujistěte se, že jste se dopustili.

22
Donovan

Předpokládejme, že vytvořím nový soubor newFile.txt.

 enter image description here

Předpokládejme, že soubor přidám omylem, git add newFile.txt

 enter image description here

Nyní chci vrátit tento doplněk před potvrzením, git reset newFile.txt

 enter image description here

18
Vidura Mudalige

Pro konkrétní soubor:

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

Pro všechny přidané soubory:

  • git reset.
  • git checkout.

Poznámka: checkout změní kód v souborech a přesune se do posledního aktualizovaného stavu. reset nezmění kódy; pouze resetuje záhlaví.

17
Hasib Kamal

Chcete-li vrátit zpět git, použijte

git reset filename

13
Anirudh Sood

Tento příkaz odstraní změny:

git reset HEAD filename.txt

Můžete také použít

git add -p 

přidat části souborů.

13
wallerjake

Jsem překvapen, že nikdo neuvádí interaktivní režim:

git add -i

vyberte možnost 3 pro přidání souborů. V mém případě často chci přidat více než jeden soubor, s interaktivní režim můžete použít čísla, jako je tento přidat soubory. Bude to trvat 4: 1,2,3,5

Chcete-li zvolit posloupnost, stačí zadat 1-5, aby se vše od 1 do 5.

Git stagingové soubory

13
Jonathan

git add myfile.txt # toto přidá váš soubor do seznamu

Naproti tomuto příkazu je,

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

takže budete v předchozím stavu. bude opět v seznamu nezaškrtnutých (předchozí stav).

bude resetovat hlavu s daným souborem. takže pokud to vaše hlava nemá, bude to jednoduše resetovat

9
Silent Spectator
git reset filename.txt

Odstraní soubor pojmenovaný filename.txt z aktuálního indexu, oblast "o tom, že bude spáchána", aniž by se změnilo cokoli jiného.

9
Rahul Sinha

V SourceTree to můžete snadno udělat přes gui. Můžete zkontrolovat, který příkaz sourcetree používá k odpojení souboru.

Vytvořil (a) jsem nový soubor a přidal (a) do gitu. Pak jsem ho nestabilizoval pomocí SourceTree gui. To je výsledek:

Odstavení souborů [08/12/15 10:43]
git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - cesta/do/souboru/filename.Java

SourceTree používá reset k odpojení nových souborů.

8
miva2
git reset filename.txt  

Odstraní soubor pojmenovaný filename.txt z aktuálního indexu, oblast "o tom, že bude spáchána", aniž by se změnilo cokoli jiného.

7
Joseph Mathew

Jedním z nejintuitivnějších řešení je použití SourceTree .

Můžete pouze přetahovat soubory z inscenovaných a nestabilních souborů  enter image description here

7
Marcin Szymczak

Příkaz git reset vám pomůže modifikovat pracovní oblast nebo pracovní oblast a pracovní strom. Schopnost Gitu řemeslně se dopustit přesně takového, jaký chcete, znamená, že budete někdy muset vrátit změny změn, které jste provedli pomocí programu git add.

Můžete to udělat voláním git reset HEAD <file to change>. Máte dvě možnosti, jak se zcela zbavit změn. git checkout HEAD <file(s) or path(s)> je rychlý způsob, jak vrátit změny do pracovní oblasti a pracovního stromu. S tímto příkazem buďte opatrní, protože odstraňuje všechny změny ve vašem pracovním stromu. Git o těchto změnách neví, protože nikdy nebyly spáchány. Po spuštění tohoto příkazu není možné tyto změny vrátit zpět.

Další příkaz k dispozici je git reset --hard. Je to stejně destruktivní pro váš pracovní strom - po jeho spuštění dojde ke ztrátě jakýchkoli nepotvrzených změn nebo provedených změn. Spuštění git reset -hard HEAD provede totéž jako git checkout HEAD. To prostě nevyžaduje soubor nebo cestu k práci.

Můžete použít --soft s git reset. Obnoví úložiště na vámi zadaný příkaz a provede všechny tyto změny. Změny, které jste již provedli, nejsou ovlivněny ani změny ve vašem pracovním stromu.

Nakonec můžete pomocí --mixed obnovit pracovní strom bez provedení jakýchkoli změn. To také unstages všechny změny, které jsou uvedeny.

1
SAIguru011