Jak cofnąć polecenie „dodaj git” przed zatwierdzeniem?

8956

Przez pomyłkę dodałem pliki do Gita, używając polecenia:

git add myfile.txt

Jeszcze nie uciekłem git commit. Czy istnieje sposób, aby to cofnąć, aby te pliki nie zostały uwzględnione w zatwierdzeniu?

paxos1977
źródło
22
Począwszy od Git v1.8.4, wszystkie odpowiedzi poniżej tego zastosowania HEADlub headmogą teraz używać @zamiast HEADzamiast. Zobacz tę odpowiedź (ostatnia sekcja), aby dowiedzieć się, dlaczego możesz to zrobić.
3
Zrobiłem trochę letniego, który pokazuje wszystkie sposoby rozpakowania pliku: stackoverflow.com/questions/6919121/...
Daniel Alder
5
Dlaczego nie skorzystać z kasy?
Erik Reppen,
13
@ErikReppen git checkoutnie usuwa zmian etapowych z indeksu zatwierdzeń. Cofa tylko nieetapowe zmiany do ostatniej zatwierdzonej wersji - która, nawiasem mówiąc, nie jest tym, czego chcę, chcę tych zmian, chcę je tylko w późniejszym zatwierdzeniu.
paxos1977,
4
Jeśli używasz Eclipse, jest to tak proste, jak odznaczenie plików w oknie dialogowym zatwierdzenia
Hamzahfrq,

Odpowiedzi:

10359

Możesz cofnąć git addprzed zatwierdzeniem za pomocą

git reset <file>

co spowoduje usunięcie go z bieżącego indeksu (listy „wkrótce do zatwierdzenia”) bez zmiany czegokolwiek innego.

Możesz użyć

git reset

bez żadnej nazwy pliku, aby wycofać wszystkie należne zmiany. Może się to przydać, gdy w rozsądnym czasie jest zbyt wiele plików, aby można je było wyświetlać pojedynczo.

W starych wersjach Gita powyższe polecenia są odpowiednio równoważne git reset HEAD <file>i git reset HEAD, i nie powiedzie się, jeśli nie zostaną HEADzdefiniowane (ponieważ nie dokonano jeszcze żadnych zatwierdzeń w repozytorium) lub niejednoznaczne (ponieważ utworzono gałąź o nazwie HEAD, co jest głupią rzeczą których nie powinieneś robić). Zostało to zmienione w Git 1.8.2 , więc we współczesnych wersjach Git możesz używać powyższych poleceń nawet przed pierwszym zatwierdzeniem:

„git reset” (bez opcji lub parametrów) używał do błędu, gdy nie masz żadnych zatwierdzeń w historii, ale teraz daje ci pusty indeks (aby dopasować nieistniejące zatwierdzenie, którego nawet nie używasz).

genhack
źródło
92
Oczywiście nie jest to prawdziwe cofnięcie, ponieważ jeśli niewłaściwy git addnapis zastąpił poprzednią, niepolecaną wersję, nie możemy go odzyskać. Próbowałem to wyjaśnić w mojej odpowiedzi poniżej.
leonbloy
7
git reset HEAD *.extgdzie extsą pliki danego rozszerzenia, które chcesz usunąć. Dla mnie było to *.bmp&*.zip
boulder_ruby
18
@Jonny, indeks (inaczej obszar przejściowy ) zawiera wszystkie pliki, a nie tylko zmienione pliki. „Zaczyna życie” (kiedy wypisujesz zatwierdzenie lub klonujesz repozytorium) jako kopię wszystkich plików w zatwierdzeniu wskazanych przez HEAD. Jeśli więc usuniesz plik z indeksu ( git rm --cached), oznacza to, że przygotowujesz się do zatwierdzenia, które usuwa ten plik. git reset HEAD <filename>z drugiej strony skopiuje plik z HEAD do indeksu, aby następne zatwierdzenie nie pokazywało żadnych zmian dokonanych w tym pliku.
Wildcard,
11
Właśnie odkryłem, że istnieje git reset -pcoś takiego git add -p. To jest niesamowite!
donquixote
10
W rzeczywistości można odzyskać zastąpione wcześniej ustawione, ale niezaangażowane zmiany, ale nie w sposób przyjazny dla użytkownika i nie w 100% bezpieczny (przynajmniej nie znalazłem): goto .git / objects, wyszukaj pliki utworzone w momencie git add, gdy chcesz odzyskać ( 61/3AF3...- > identyfikator obiektu 613AF3...), a następnie git cat-file -p <object-id>(może warto odzyskać kilka godzin pracy, ale także lekcję do częstszego popełniania ...)
Peter Schneider
2151

Chcesz:

git rm --cached <added_file_to_undo>

Rozumowanie:

Kiedy byłem nowy, po raz pierwszy spróbowałem

git reset .

(aby cofnąć całe moje początkowe dodawanie), tylko po to, aby otrzymać tę (nie taką) pomocną wiadomość:

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

Okazuje się, że dzieje się tak, ponieważ HEAD ref (gałąź?) Nie istnieje aż do pierwszego zatwierdzenia. Oznacza to, że napotkasz ten sam problem dla początkujących, co ja, jeśli Twój przepływ pracy, podobnie jak mój, był podobny:

  1. cd do mojego wspaniałego nowego katalogu projektu, aby wypróbować Git, nową popularność
  2. git init
  3. git add .
  4. git status

    ... mnóstwo bzdur przewija się przez ...

    => Cholera, nie chciałem tego wszystkiego dodawać.

  5. google „cofnij dodanie git”

    => znajdź przepełnienie stosu - yay

  6. git reset .

    => fatal: Nie można rozpoznać „HEAD” jako prawidłowego numeru referencyjnego.

Okazuje się ponadto, że na liście mailowej zarejestrowano błąd przeciwko nieużyteczności tego.

I że poprawne rozwiązanie znalazło się właśnie w danych wyjściowych statusu Git (które, tak, ja przekląłem jako „bzdura”)

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

A rozwiązaniem jest rzeczywiście użyć git rm --cached FILE.

Zwróć uwagę na ostrzeżenia w innym miejscu tutaj - git rmusuwa lokalną kopię roboczą pliku, ale nie w przypadku użycia - buforowanej . Oto wynik git help rm:

--cached Użyj tej opcji, aby wycofać scenę i usunąć ścieżki tylko z indeksu. Pliki drzewa roboczego, zmodyfikowane lub nie, zostaną pozostawione.

Kontynuuję używanie

git rm --cached .

usunąć wszystko i zacząć od nowa. Nie działało jednak, ponieważ chociaż add .jest rekurencyjne, okazuje się, że rmtrzeba -rsię powtórzyć. Westchnienie.

git rm -r --cached .

Okej, teraz wracam do miejsca, gdzie zacząłem. Następnym razem zamierzam użyć -nsuchego biegu i zobaczyć, co zostanie dodane:

git add -n .

Spakowałam wszystko do bezpiecznego miejsca, zanim ufałam, git help rmże --cachedniczego nie niszczysz (a co, jeśli źle to przeliteruję).

Rabarbar
źródło
15
Hah Postępowałem zgodnie z tym samym procesem. Tyle że się poddałem i powiedziałem rm -rf .git, git initbo nie ufałem, git rm --cachedże zachowam kopię roboczą. Mówi to trochę o tym, że git jest wciąż zbyt skomplikowany w niektórych miejscach. git unstagepowinno być standardowym poleceniem, nie obchodzi mnie, czy mogę dodać to jako alias.
Adrian Macneil
5
Dla mnie git mówigit reset HEAD <File>...
drahnr
16
git rm --cached <plik> jest właściwie poprawną odpowiedzią, jeśli jest to początkowy import <pliku> do repozytorium. Jeśli próbujesz cofnąć zmianę w pliku, poprawną odpowiedzią jest git reset. Ludzie twierdzący, że ta odpowiedź jest błędna, myślą o innym pytaniu.
Barry Kelly
14
To faktycznie zadziała, ale tylko przy pierwszym zatwierdzeniu, w którym plik nie istniał wcześniej lub w którym git addpolecenie dodało nowe pliki, ale nie zmienia istniejących plików.
naught101
4
po prostu pokazuje, jak nieintuicyjny i zawiły jest git. zamiast równoległych poleceń „cofnij” musisz dowiedzieć się, jak je cofnąć. Jak próba uwolnienia nogi w szybkim piasku, a następnie zablokowanie ręki, a następnie zablokowanie drugiej ręki ... każde polecenie należy wykonać za pomocą GUI, z rozwijanymi opcjami menu dla opcji ... Pomyśl o całym interfejsie, wzrost wydajności, jaki mieliśmy, ale mamy ten bałagan interfejsu retro wiersza poleceń. To nie jest tak, że programy git GUI sprawiają, że jest to bardziej intuicyjne.
ahnbizcad
532

Jeśli wpiszesz:

git status

Git powie ci, co jest inscenizowane itp., W tym instrukcje, jak się wycofać:

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

Uważam, że Git wykonuje niezłą robotę, nakłaniając mnie do robienia właściwych rzeczy w takich sytuacjach.

Uwaga: Najnowsze wersje Git (1.8.4.x) zmieniły ten komunikat:

(use "git rm --cached <file>..." to unstage)
Paul Beckingham
źródło
19
Wiadomość będzie się różnić w zależności od tego, czy addplik ed był już śledzony ( addjedyna zapisana nowa wersja do pamięci podręcznej - tutaj wyświetli wiadomość). Gdzie indziej, jeśli plik nie był wcześniej use "git rm --cached <file>..." to unstage
przemieszczany,
Świetny! Ten git reset HEAD <file>jedyny będzie działał na wypadek, gdybyś chciał usunąć scenę z usunięcia pliku
skerit
2
Moja wersja gita 2.14.3 mówi, git reset HEADaby się wycofać.
SilverWolf - Przywróć Monikę
246

Aby to wyjaśnić: git addprzenosi zmiany z bieżącego katalogu roboczego do obszaru pomostowego (indeksu).

Ten proces nazywa się inscenizacją . Tak więc większość poleceń naturalny etap zmian (zmiana plików) jest oczywista:

git stage

git add jest po prostu łatwiejszym do wpisania aliasem git stage

Szkoda, że ​​nie ma git unstageani git unaddpoleceń. Odpowiedni trudniej zgadnąć lub zapamiętać, ale jest dość oczywisty:

git reset HEAD --

Możemy łatwo stworzyć dla tego alias:

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

I wreszcie, mamy nowe polecenia:

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

Osobiście używam jeszcze krótszych aliasów:

git a # For staging
git u # For unstaging
zabiera
źródło
3
„porusza się”? Oznaczałoby to, że wyszedł z katalogu roboczego. Nie o to chodzi.
Thomas Weller,
4
Dlaczego to oczywiste?
Lenar Hoyt
W rzeczywistości git stagejest to alias git add, który jest historycznym poleceniem, zarówno na Git, jak i na innych SCM. Został dodany w grudniu 2008 z zatwierdzeniem 11920d28da w „repozytorium git Gita”, jeśli mogę powiedzieć.
Obsidian
1
Może to być niezwiązane, ale znalazłem sprawdzanie poprawności pliku, zanim jeszcze dodałem, że jest to przydatny pomysł, coś w rodzaju polecenia check-nazwa_pliku && git dodaj nazwę pliku, zastąpiłem git krótszym g na moim komputerze i do tej pory działało ok dla mnie: github.com/dataf3l/g , nie wiem, czy to się komuś przyda, ale umieszczę to tutaj w nadziei, że zaoszczędzi to czasu niektórych ludzi.
Felipe Valdes
167

Dodatek do zaakceptowanej odpowiedzi, jeśli Twój błędnie dodany plik był ogromny, prawdopodobnie zauważysz, że nawet po usunięciu go z indeksu za pomocą „ git reset” nadal wydaje się, że zajmuje on miejsce w .gitkatalogu.

Nie ma się czym martwić; plik jest rzeczywiście nadal w repozytorium, ale tylko jako „luźny obiekt”. Nie zostanie skopiowany do innych repozytoriów (przez klonowanie, wypychanie), a przestrzeń zostanie ostatecznie odzyskana - choć może nie wkrótce. Jeśli jesteś niespokojny, możesz uruchomić:

git gc --prune=now

Aktualizacja (następująca jest moja próba usunięcia pewnych nieporozumień, które mogą wyniknąć z najbardziej uprzywilejowanych odpowiedzi):

Więc, co jest prawdziwym cofania z git add?

git reset HEAD <file> ?

lub

git rm --cached <file>?

Ściśle mówiąc, a jeśli się nie mylę: brak .

git add nie można tego cofnąć - ogólnie bezpiecznie.

Przypomnijmy najpierw, co git add <file>właściwie robi:

  1. Jeśli nie<file> był wcześniej śledzony , git add dodaje go do pamięci podręcznej z bieżącą zawartością.

  2. Jeśli <file>było już śledzone , git add zapisuje bieżącą zawartość (migawkę, wersję) w pamięci podręcznej. W Git ta czynność jest nadal nazywana dodawaniem (a nie tylko aktualizacją ), ponieważ dwie różne wersje (migawki) pliku są traktowane jako dwa różne elementy: dlatego rzeczywiście dodajemy nowy element do pamięci podręcznej, aby ostatecznie popełnione później.

W świetle tego pytanie jest nieco dwuznaczne:

Pomyłkowo dodałem pliki za pomocą polecenia ...

Scenariusz PO wydaje się być pierwszym (nieśledzony plik), chcemy, aby „cofnięcie” usunęło plik (nie tylko bieżącą zawartość) ze śledzonych elementów. W takim przypadku można uruchomić git rm --cached <file>.

I moglibyśmy także biec git reset HEAD <file>. Jest to na ogół preferowane, ponieważ działa w obu scenariuszach: wykonuje również cofanie, gdy błędnie dodaliśmy wersję już śledzonego elementu.

Ale są dwa zastrzeżenia.

Po pierwsze: istnieje (jak wskazano w odpowiedzi) tylko jeden scenariusz, w którym git reset HEADnie działa, ale git rm --cacheddziała: nowe repozytorium (bez zatwierdzeń). Ale tak naprawdę jest to praktycznie nieistotny przypadek.

Po drugie: pamiętaj, że git reset HEAD nie można magicznie odzyskać wcześniej buforowanej zawartości pliku, po prostu ponownie synchronizuje go z HEAD. Jeśli nasz wprowadzony w błąd git addnadpisał poprzednią zainscenizowaną niezaangażowaną wersję, nie możemy jej odzyskać. Właśnie dlatego, ściśle mówiąc, nie możemy cofnąć [*].

Przykład:

$ 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 irrevocably lost "version 2"
-version 1
+version 3

Oczywiście nie ma to większego znaczenia, jeśli postępujemy zgodnie ze zwykłym leniwym obiegiem pracy polegającym na wykonywaniu polecenia „git add” tylko w celu dodawania nowych plików (przypadek 1) i aktualizujemy nową zawartość za pomocą git commit -apolecenia zatwierdzenia .


* (Edycja: powyższe jest praktycznie poprawne, ale nadal mogą istnieć pewne nieco zhackowane / skomplikowane sposoby odzyskiwania zmian, które zostały wprowadzone, ale nie zostały zatwierdzone, a następnie zastąpione - patrz komentarze Johannesa Matokica i iolsmit)

leonbloy
źródło
4
Ściśle mówiąc, istnieje sposób na odzyskanie już przemieszczonego pliku, który został zastąpiony przez git add. Jak wspomniałeś, git add tworzy obiekt git dla tego pliku, który stanie się luźnym obiektem nie tylko po całkowitym usunięciu pliku, ale także po nadpisaniu nową zawartością. Ale nie ma polecenia, aby automatycznie go odzyskać. Zamiast tego plik musi zostać zidentyfikowany i wyodrębniony ręcznie lub za pomocą narzędzi napisanych tylko dla tego przypadku (libgit2 pozwoli na to). Ale to się opłaci tylko wtedy, gdy plik jest bardzo ważny i duży i nie można go odbudować, edytując poprzednią wersję.
Johannes Matokic,
2
Aby się poprawić: Po znalezieniu pliku obiektu luźnego (użyj metadanych, takich jak data / czas utworzenia), git cat-filemożna go użyć do odzyskania jego zawartości.
Johannes Matokic,
2
Innym sposobem na odzyskanie zmian, które zostały wprowadzone, ale nie zostały zatwierdzone, a następnie zastąpione przez np. Inny git addjest za pośrednictwem, git fsck --unreachablektóry wyświetli listę wszystkich nieosiągalnych obiektów, które można następnie sprawdzić git show SHA-1_IDlub git fsck --lost-found> Zapisać wiszące obiekty w .git/lost-found/commit/lub .git/lost-found/other/, w zależności od typu. Zobacz takżegit fsck --help
iolsmit,
110

Cofanie pliku, który został już dodany, jest dość łatwe przy użyciu Git. Aby zresetować myfile.txt, które zostały już dodane, użyj:

git reset HEAD myfile.txt

Wyjaśnienie:

Po umieszczeniu niechcianych plików, możesz je cofnąć git reset. Headjest głową pliku w lokalnym pliku, a ostatnim parametrem jest nazwa pliku.

Stworzyłem dla Ciebie szczegółowe kroki na obrazku poniżej, w tym wszystkie kroki, które mogą się zdarzyć w następujących przypadkach:

git zresetować plik HEAD

Alireza
źródło
Zdjęcie: „Polecenie dodaj ...”„Polecenie dodaje ...” ( czas teraźniejszy prosty, trzecia osoba )
Peter Mortensen
Zdjęcie: chcęchcę (tutaj nie ma potrzeby używania slangu)
Peter Mortensen
92
git rm --cached . -r

usunie rekursywnie wszystko, co dodałeś z bieżącego katalogu

Braitsch
źródło
3
Nie chciałem usuwać wszystkiego, tylko JEDEN konkretny plik.
paxos1977,
3
Przydaje się również, jeśli nie masz wcześniejszych zatwierdzeń. Przy braku poprzedniego zatwierdzenia, git reset HEAD <file>powiedziałbyfatal: Failed to resolve 'HEAD' as a valid ref.
Priya Ranjan Singh
6
Nie, powoduje to usunięcie wszystkiego z bieżącego katalogu. Zupełnie inaczej niż po prostu zmiany sceniczne.
Mark Amery
88

Biegać

git gui

i usuń wszystkie pliki ręcznie lub przez wybranie ich wszystkich i kliknięcie przycisku wycofania z zatwierdzenia .

Khaja Minhajuddin
źródło
1
Tak rozumiem to. Chciałem tylko domyślnie zasugerować, abyś wskazał, że w swojej odpowiedzi, np. „Możesz użyć git-gui....” :)
Alexander Suraphel
1
Mówi: „git-gui: polecenie nie znaleziono”. Nie jestem pewien, czy to działa.
Parinda Rajapaksha
Wow, jest to o wiele prostsze niż wykonywanie wierszy poleceń, których nie rozumiesz. Jest to zdecydowanie zalecane dla początkujących takich jak ja. Dzięki za napisanie tego!
Irfandy Jip
Dzięki. Nie chciałem ryzykować, więc musiałem użyć GUI.
Sagar Khatri
83

Git ma polecenia dla każdej możliwej akcji, ale potrzebuje rozległej wiedzy, aby wszystko było dobrze, dlatego jest co najmniej intuicyjny ...

Co robiłeś wcześniej:

  • Zmieniono plik i wykorzystano git add ., lub git add <file>.

Czego chcesz:

  • Usuń plik z indeksu, ale zachowaj jego wersję i pozostaw niezatwierdzone zmiany w kopii roboczej:

    git reset head <file>
    
  • Zresetuj plik do ostatniego stanu z poziomu HEAD, cofając zmiany i usuwając je z indeksu:

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

    Jest to potrzebne, ponieważ git reset --hard HEADnie działa z pojedynczymi plikami.

  • Usuń <file>z indeksu i wersji, zachowując niewersjonowany plik ze zmianami w kopii roboczej:

    git rm --cached <file>
    
  • <file>Całkowicie usuń z kopii roboczej i wersji:

    git rm <file>
    
sjas
źródło
1
Nie rozumiem różnicy między „git reset head <plik>” i „git rm --cached <plik>. Czy możesz to wyjaśnić?
jeswang
6
Pliki @jeswang są albo „znane” dla git (zmiany w nich są śledzone.), albo nie są „wersjonowane”. reset headcofa twoje obecne zmiany, ale plik jest nadal monitorowany przez git. rm --cachedusuwa plik z wersji, więc git nie sprawdza go już pod kątem zmian (a także usuwa ewentualnie zindeksowane obecne zmiany, o których wcześniej powiedział git add), ale zmieniony plik zostanie zachowany w kopii roboczej, czyli w folderze plików na dysku twardym.
sjas
3
Różnica jest git reset HEAD <file>tymczasowa - polecenie zostanie zastosowane tylko do następnego zatwierdzenia, ale git rm --cached <file>przestanie działać, dopóki nie zostanie dodane ponownie git add <file>. git rm --cached <file>Oznacza to również, że jeśli przekażesz tę gałąź do pilota, każda osoba ciągnąca gałąź zostanie AKTUALNIE usunięta z folderu.
DrewT,
80

Pytanie nie jest jasno postawione. Powodem jest to, że git addma dwa znaczenia:

  1. dodając nowy plik do obszaru pomostowego, a następnie cofnij za pomocągit rm --cached file .
  2. dodając zmodyfikowany plik do obszaru pomostowego, a następnie cofnij za pomocą git reset HEAD file.

W razie wątpliwości użyj

git reset HEAD file

Ponieważ w obu przypadkach spełnia oczekiwane oczekiwania.

Ostrzeżenie: jeśli zrobisz to git rm --cached filena pliku, który został zmodyfikowany (plik, który istniał wcześniej w repozytorium), plik zostanie usunięty git commit! Wciąż będzie istniał w twoim systemie plików, ale jeśli ktoś inny ściągnie twoje zatwierdzenie, plik zostanie usunięty z drzewa pracy.

git statuspoinformuje Cię, czy plik był nowym plikiem, czy zmodyfikowany :

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
Michael_Scharf
źródło
7
+1. Niezwykła liczba wysoko ocenianych odpowiedzi i komentarzy na tej stronie jest całkowicie błędna co do zachowania git rm --cached somefile. Mam nadzieję, że ta odpowiedź dotrze na górę strony w widocznym miejscu, gdzie może uchronić początkujących przed wprowadzeniem w błąd przez wszystkie fałszywe twierdzenia.
Mark Amery
jedna z najlepszych odpowiedzi tutaj, niestety jest dość nisko na liście
Creos
64

Jeśli jesteś przy pierwszym zatwierdzeniu i nie możesz użyć git reset, po prostu zadeklaruj „bankructwo Git”, usuń .gitfolder i zacznij od nowa

Ana Betts
źródło
5
Jedna wskazówka to skopiowanie pliku .git / config, jeśli dodano zdalne pochodzenie, przed usunięciem folderu.
Tiago,
4
Komentarz @ChrisJohnsen jest na miejscu. Czasami chcesz zatwierdzić wszystkie pliki oprócz jednego: git add -A && git rm --cached EXCLUDEFILE && git commit -m 'awesome commit' (Działa to również wtedy, gdy nie ma wcześniejszych zatwierdzeń, Failed to resolve 'HEAD'problem ponownie )
57

Jak na wiele innych odpowiedzi, możesz użyć git reset

ALE:

Znalazłem ten świetny mały post, który faktycznie dodaje polecenie Git (cóż, alias) dla git unadd: zobacz git unadd lub…

Po prostu,

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

Teraz możesz

git unadd foo.txt bar.txt
electblake
źródło
45

Służy git add -ido usuwania właśnie dodanych plików z nadchodzącego zatwierdzenia. Przykład:

Dodanie pliku, którego nie chciałeś:

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

Przechodzenie do interaktywnego dodawania w celu cofnięcia dodawania (polecenia wpisywane w git tutaj to „r” (cofnij), „1” (pierwszy wpis na liście pokazuje cofnięcie), „return”, aby wyjść z trybu przywracania i „q” (porzucić):

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

Otóż ​​to! Oto twój dowód pokazujący, że „foo” powraca na nieśledzoną listę:

$ 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)
$
Alex North-Keys
źródło
42

git removelub git rmmożna do tego użyć --cachedflagi. Próbować:

git help rm
gnud
źródło
9
Czy to nie spowoduje całkowitego usunięcia pliku?
Willa
8
git rm --cached ...usunie pliki z repozytorium git. Będą one nadal istnieć na twoim komputerze, ale BARDZO różni się od nieustawionych zmian w pliku. Dla każdego, kto się na to natknie, nie jest to prawidłowa odpowiedź na pytanie.
Addison,
38

Oto sposób na uniknięcie tego irytującego problemu podczas rozpoczynania nowego projektu:

  • Utwórz katalog główny dla nowego projektu.
  • Uruchom git init.
  • Teraz utwórz plik .gitignore (nawet jeśli jest pusty).
  • Zatwierdź plik .gitignore.

Git sprawia, że ​​naprawdę trudno to zrobić, git resetjeśli nie masz żadnych zobowiązań. Jeśli utworzysz małe początkowe zatwierdzenie tylko ze względu na jego posiadanie, potem możesz git add -Aigit reset tyle razy, ile chcesz, aby dostać wszystko prawo.

Kolejną zaletą tej metody jest to, że jeśli później wystąpią problemy z zakończeniem linii i konieczne będzie odświeżenie wszystkich plików, to proste:

  • Sprawdź to wstępne zatwierdzenie. Spowoduje to usunięcie wszystkich plików.
  • Następnie sprawdź ponownie swoje ostatnie zatwierdzenie. Spowoduje to pobranie świeżych kopii plików przy użyciu bieżących ustawień zakończenia linii.
Ryan Lundy
źródło
1
Potwierdzony! Próbowałem zresetować git po dodaniu git. a git narzekał na skorumpowaną GŁOWĘ. Postępując zgodnie z twoją radą, mogę bez problemu dodawać i resetować w obie strony :)
Kounavi,
1
Druga część działa, ale jest nieco niezdarna. Jak obsługiwane są zakończenia linii, zależy od autocrlfwartości ... To nie będzie działać w każdym projekcie, w zależności od ustawień.
sjas
1
Ta odpowiedź była rozsądna w chwili jej opublikowania, ale obecnie jest nieaktualna; git reset somefilei git resetoba działają teraz przed pierwszym zatwierdzeniem. Tak było od czasu wydania kilku wydań Git.
Mark Amery
@MarkAmery, możesz mieć rację (byłoby fajnie, gdybyś opublikował źródło swojego potwierdzenia), ale nadal jest opłacalne rozpoczęcie repo z czystym zatwierdzeniem lub dwoma.
Ryan Lundy,
34

Może Git ewoluował, odkąd opublikowałeś swoje pytanie.

$> git --version
git version 1.6.2.1

Teraz możesz spróbować:

git reset HEAD .

To powinno być to, czego szukasz.

Kokotte23
źródło
2
Jasne, ale masz pytanie uzupełniające, w jaki sposób należy dodać jeden z dwóch (lub więcej) dodanych plików. Podręcznik „git reset” wspomina jednak, że „git reset <ścieżki>” jest jednak przeciwieństwem „git add <ścieżki>”.
Alex North-Keys
34

Pamiętaj, że jeśli nie określisz wersji, musisz dołączyć separator. Przykład z mojej konsoli:

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 wersja 1.7.5.4)

powlo
źródło
2
Próbowałem git reset <path>i działa dobrze bez separatora. Używam również git 1.9.0. Może to nie działa w starszych wersjach?
31

Aby usunąć nowe pliki z obszaru przejściowego (i tylko w przypadku nowego pliku), jak sugerowano powyżej:

git rm --cached FILE

Użyj rm --cached tylko dla nowych plików przypadkowo dodanych.

Biegł
źródło
4
Pamiętaj, że --cachedjest to bardzo ważna część.
bierze
1
-1; nie, to nie powoduje wycofania pliku, powoduje stopniowe usunięcie pliku (bez faktycznego usuwania go z drzewa pracy).
Mark Amery
25

Aby zresetować każdy plik w określonym folderze (i jego podfolderach), możesz użyć następującego polecenia:

git reset *
Zorayr
źródło
4
W rzeczywistości nie resetuje to każdego pliku, ponieważ * używa rozszerzenia powłoki i ignoruje pliki dot (i katalogi kropek).
Luc
Możesz uruchomić, git statusaby zobaczyć wszystko, co pozostało i zresetować je ręcznie, tj git reset file.
Zorayr
25

Użyj *polecenia do obsługi wielu plików jednocześnie:

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

itp.

boulder_ruby
źródło
3
Pamiętaj, że * zwykle nie będzie zawierać plików-kropek ani „katalogów-kropek”, chyba że wyraźnie określisz .*lub.*.prj
Luc
23

Po prostu wpisz git reset, cofnie się z powrotem i jest tak, jakbyś nigdy nie pisał git add .od ostatniego zatwierdzenia. Upewnij się, że dokonałeś wcześniej.

Donovan
źródło
Tak się składa, że ​​było ostatnie zatwierdzenie ... ale konkretnie pytałem o usunięcie pojedynczego pliku z zatwierdzenia, nie każdego pliku z zatwierdzenia.
paxos1977
20

Załóżmy, że utworzę nowy plik newFile.txt:

Wpisz opis zdjęcia tutaj

Załóżmy, że dodam plik przypadkowo git add newFile.txt:

Wpisz opis zdjęcia tutaj

Teraz chcę cofnąć to dodanie przed zatwierdzeniem git reset newFile.txt:

Wpisz opis zdjęcia tutaj

Vidura Mudalige
źródło
Załóżmy, że jestem na pierwszym zdjęciu, co oznacza, że ​​nawet nie napisałem „git.add”. Nie chcę też wcale tej zmiany. Mam na myśli, że kiedy mam status git, nie powinien pokazywać żadnych czerwonych plików. Mam na myśli, że powinien być zsynchronizowany, tak jakby od ostatniego wypychania git nie został zmieniony żaden plik. jak to osiągnąć.
Niezniszczalny
Więc załóżmy, że dopiero zaczynasz. I chcesz pozbyć się wszystkich dokonanych zmian, które powodują, że plik „newFile.txt” staje się czerwony.
Niezniszczalny
Kiedy zrobię status git. Nie powinienem w ogóle widzieć żadnych zmian. Wszystkie czerwone pliki powinny zostać cofnięte.
Niezniszczalny
Cześć, myślę, że twoje pytanie dotyczy usuwania nieśledzonych plików z bieżącego drzewa. W tym celu możesz użyć „git clean -f -d”. Spowoduje to również usunięcie nieśledzonych katalogów.
Vidura Mudalige
Jeśli nie chcesz usuwać nieśledzonych plików, po prostu zignoruj ​​flagę „-f”.
Vidura Mudalige
19

W przypadku konkretnego pliku:

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

Dla wszystkich dodanych plików:

  • git reset.
  • Git Checkout.

Uwaga: kasa zmienia kod w plikach i przechodzi do ostatniego zaktualizowanego (zatwierdzonego) stanu. reset nie zmienia kodów; po prostu resetuje nagłówek.

Hasib Kamal
źródło
3
Proszę wyjaśnić różnicę między git reset <file>i git checkout <file>.
Trent
1
reset nie zmienia pliku, po prostu odłóż go od stołu montażowego (= indeks, w którym został wstawiony przez git add)
frank
kasa zmień kody w pliku i przejdź do ostatniego zaktualizowanego stanu. reset nie zmienia kodów, po prostu resetuje nagłówek. Na przykład zresetuj użycie dodanych lub zatwierdzonych plików resetujących przed wypychaniem i użyj kasowania z powrotem do ostatniego zaktualizowanego / zatwierdzonego etapu przed dodaniem git.
Hasib Kamal
1
reset = usuń plik ze stołu montażowego, jednak zmiany będą nadal dostępne. checkout = pobiera zaktualizowany plik z repozytorium i zastępuje bieżący plik
Imam Bux
14

Ta komenda usunie twoje zmiany:

git reset HEAD filename.txt

Możesz także użyć

git add -p 

aby dodać części plików.

wallerjake
źródło
14

Istnieje również tryb interaktywny:

git add -i

Wybierz opcję 3, aby usunąć pliki. W moim przypadku często chcę dodać więcej niż jeden plik, a w trybie interaktywnym możesz używać takich liczb do dodawania plików. To zajmie wszystko oprócz 4: 1, 2, 3 i 5

Aby wybrać sekwencję, po prostu wpisz 1-5, aby wziąć wszystkie od 1 do 5.

Pliki pomostowe Git

Jonathan
źródło
„Dziwię się, że nikt nie wspomniał o trybie interaktywnym” - tak: stackoverflow.com/a/10209776/1709587
Mark Amery
14

Aby cofnąć git add, użyj:

git reset filename
Anirudh Sood
źródło
10
git reset filename.txt

Usunie plik o nazwie filename.txt z bieżącego indeksu, obszaru „wkrótce do zatwierdzenia”, bez zmiany czegokolwiek innego.

Rahul Sinha
źródło
10

git add myfile.txt # Spowoduje to dodanie pliku do listy do zatwierdzenia

Wręcz przeciwnie do tego polecenia,

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

więc będziesz w poprzednim stanie. Określony będzie ponownie na liście bez śledzenia (poprzedni stan).

Zresetuje twoją głowę tym określonym plikiem. więc jeśli twoja głowa tego nie ma, po prostu ją zresetuje.

Mohideen bin Mohammed
źródło
9

W Sourcetree możesz to łatwo zrobić za pomocą GUI. Możesz sprawdzić, którego polecenia Sourcetree używa do rozpakowywania pliku.

Utworzyłem nowy plik i dodałem go do Git. Następnie odsłoniłem go za pomocą GUI Sourcetree. Oto wynik:

Niestacjonarne pliki [08/12/15 10:43] git -c diff.mnemonicprefix = false -c core.quotepath = false -c credential.helper = sourcetree reset -q - path / to / file / filename.java

Sourcetree używa resetdo wypuszczania nowych plików.

miva2
źródło
Tak, tę samą technikę można zastosować w TortoiseGit , uzyskując polecenia Git dla typowych przypadków użycia.
Peter Mortensen
8
git reset filename.txt  

Usunie plik o nazwie filename.txt z bieżącego indeksu, obszaru „wkrótce do zatwierdzenia”, bez zmiany czegokolwiek innego.

Joseph Mathew
źródło
git reset [nazwa pliku] np: git reset src / main / java / com / dao / ImportCsvDataresentImpl.java
Rohit Chaurasiya