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?
git
version-control
git-commit
git-stage
paxos1977
źródło
źródło
HEAD
lubhead
mogą teraz używać@
zamiastHEAD
zamiast. Zobacz tę odpowiedź (ostatnia sekcja), aby dowiedzieć się, dlaczego możesz to zrobić.git checkout
nie 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.Odpowiedzi:
Możesz cofnąć
git add
przed zatwierdzeniem za pomocąco spowoduje usunięcie go z bieżącego indeksu (listy „wkrótce do zatwierdzenia”) bez zmiany czegokolwiek innego.
Możesz użyć
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>
igit reset HEAD
, i nie powiedzie się, jeśli nie zostanąHEAD
zdefiniowane (ponieważ nie dokonano jeszcze żadnych zatwierdzeń w repozytorium) lub niejednoznaczne (ponieważ utworzono gałąź o nazwieHEAD
, 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:źródło
git add
napis zastąpił poprzednią, niepolecaną wersję, nie możemy go odzyskać. Próbowałem to wyjaśnić w mojej odpowiedzi poniżej.git reset HEAD *.ext
gdzieext
są pliki danego rozszerzenia, które chcesz usunąć. Dla mnie było to*.bmp
&*.zip
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.git reset -p
coś takiegogit add -p
. To jest niesamowite!git add
, gdy chcesz odzyskać (61/3AF3...
- > identyfikator obiektu613AF3...
), a następniegit cat-file -p <object-id>
(może warto odzyskać kilka godzin pracy, ale także lekcję do częstszego popełniania ...)Chcesz:
Rozumowanie:
Kiedy byłem nowy, po raz pierwszy spróbowałem
(aby cofnąć całe moje początkowe dodawanie), tylko po to, aby otrzymać tę (nie taką) pomocną wiadomość:
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:
git init
git add .
git status
... mnóstwo bzdur przewija się przez ...
=> Cholera, nie chciałem tego wszystkiego dodawać.
google „cofnij dodanie git”
=> znajdź przepełnienie stosu - yay
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”)
A rozwiązaniem jest rzeczywiście użyć
git rm --cached FILE
.Zwróć uwagę na ostrzeżenia w innym miejscu tutaj -
git rm
usuwa lokalną kopię roboczą pliku, ale nie w przypadku użycia - buforowanej . Oto wynikgit help rm
:Kontynuuję używanie
usunąć wszystko i zacząć od nowa. Nie działało jednak, ponieważ chociaż
add .
jest rekurencyjne, okazuje się, żerm
trzeba-r
się powtórzyć. Westchnienie.Okej, teraz wracam do miejsca, gdzie zacząłem. Następnym razem zamierzam użyć
-n
suchego biegu i zobaczyć, co zostanie dodane:Spakowałam wszystko do bezpiecznego miejsca, zanim ufałam,
git help rm
że--cached
niczego nie niszczysz (a co, jeśli źle to przeliteruję).źródło
rm -rf .git
,git init
bo 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 unstage
powinno być standardowym poleceniem, nie obchodzi mnie, czy mogę dodać to jako alias.git reset HEAD <File>...
git add
polecenie dodało nowe pliki, ale nie zmienia istniejących plików.Jeśli wpiszesz:
Git powie ci, co jest inscenizowane itp., W tym instrukcje, jak się wycofać:
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:
źródło
add
plik ed był już śledzony (add
jedyna zapisana nowa wersja do pamięci podręcznej - tutaj wyświetli wiadomość). Gdzie indziej, jeśli plik nie był wcześniejuse "git rm --cached <file>..." to unstage
git reset HEAD <file>
jedyny będzie działał na wypadek, gdybyś chciał usunąć scenę z usunięcia plikugit reset HEAD
aby się wycofać.Aby to wyjaśnić:
git add
przenosi 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 add
jest po prostu łatwiejszym do wpisania aliasemgit stage
Szkoda, że nie ma
git unstage
anigit unadd
poleceń. Odpowiedni trudniej zgadnąć lub zapamiętać, ale jest dość oczywisty:Możemy łatwo stworzyć dla tego alias:
I wreszcie, mamy nowe polecenia:
Osobiście używam jeszcze krótszych aliasów:
źródło
git stage
jest to aliasgit 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ć.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.git
katalogu.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ć:
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:Jeśli nie
<file>
był wcześniej śledzony ,git add
dodaje go do pamięci podręcznej z bieżącą zawartością.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:
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 HEAD
nie działa, alegit rm --cached
dział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łądgit add
nadpisał 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:
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 -a
polecenia 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)
źródło
git cat-file
można go użyć do odzyskania jego zawartości.git add
jest za pośrednictwem,git fsck --unreachable
który wyświetli listę wszystkich nieosiągalnych obiektów, które można następnie sprawdzićgit show SHA-1_ID
lubgit 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
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:Wyjaśnienie:
Po umieszczeniu niechcianych plików, możesz je cofnąć
git reset
.Head
jest 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:
źródło
usunie rekursywnie wszystko, co dodałeś z bieżącego katalogu
źródło
git reset HEAD <file>
powiedziałbyfatal: Failed to resolve 'HEAD' as a valid ref.
Biegać
i usuń wszystkie pliki ręcznie lub przez wybranie ich wszystkich i kliknięcie przycisku wycofania z zatwierdzenia .
źródło
git-gui
....” :)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:
git add .
, lubgit add <file>
.Czego chcesz:
Usuń plik z indeksu, ale zachowaj jego wersję i pozostaw niezatwierdzone zmiany w kopii roboczej:
Zresetuj plik do ostatniego stanu z poziomu HEAD, cofając zmiany i usuwając je z indeksu:
Jest to potrzebne, ponieważ
git reset --hard HEAD
nie działa z pojedynczymi plikami.Usuń
<file>
z indeksu i wersji, zachowując niewersjonowany plik ze zmianami w kopii roboczej:<file>
Całkowicie usuń z kopii roboczej i wersji:źródło
reset head
cofa twoje obecne zmiany, ale plik jest nadal monitorowany przez git.rm --cached
usuwa 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ł gitadd
), ale zmieniony plik zostanie zachowany w kopii roboczej, czyli w folderze plików na dysku twardym.git reset HEAD <file>
tymczasowa - polecenie zostanie zastosowane tylko do następnego zatwierdzenia, alegit rm --cached <file>
przestanie działać, dopóki nie zostanie dodane ponowniegit 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.Pytanie nie jest jasno postawione. Powodem jest to, że
git add
ma dwa znaczenia:git rm --cached file
.git reset HEAD file
.W razie wątpliwości użyj
Ponieważ w obu przypadkach spełnia oczekiwane oczekiwania.
Ostrzeżenie: jeśli zrobisz to
git rm --cached file
na pliku, który został zmodyfikowany (plik, który istniał wcześniej w repozytorium), plik zostanie usuniętygit 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 status
poinformuje Cię, czy plik był nowym plikiem, czy zmodyfikowany :źródło
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.Jeśli jesteś przy pierwszym zatwierdzeniu i nie możesz użyć
git reset
, po prostu zadeklaruj „bankructwo Git”, usuń.git
folder i zacznij od nowaźródło
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 )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,
Teraz możesz
źródło
Służy
git add -i
do usuwania właśnie dodanych plików z nadchodzącego zatwierdzenia. Przykład:Dodanie pliku, którego nie chciałeś:
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ć):
Otóż to! Oto twój dowód pokazujący, że „foo” powraca na nieśledzoną listę:
źródło
git remove
lubgit rm
można do tego użyć--cached
flagi. Próbować:źródło
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.Oto sposób na uniknięcie tego irytującego problemu podczas rozpoczynania nowego projektu:
git init
.Git sprawia, że naprawdę trudno to zrobić,
git reset
jeśli nie masz żadnych zobowiązań. Jeśli utworzysz małe początkowe zatwierdzenie tylko ze względu na jego posiadanie, potem możeszgit add -A
igit 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:
źródło
autocrlf
wartości ... To nie będzie działać w każdym projekcie, w zależności od ustawień.git reset somefile
igit reset
oba działają teraz przed pierwszym zatwierdzeniem. Tak było od czasu wydania kilku wydań Git.Może Git ewoluował, odkąd opublikowałeś swoje pytanie.
Teraz możesz spróbować:
To powinno być to, czego szukasz.
źródło
Pamiętaj, że jeśli nie określisz wersji, musisz dołączyć separator. Przykład z mojej konsoli:
(Git wersja 1.7.5.4)
źródło
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?Aby usunąć nowe pliki z obszaru przejściowego (i tylko w przypadku nowego pliku), jak sugerowano powyżej:
Użyj rm --cached tylko dla nowych plików przypadkowo dodanych.
źródło
--cached
jest to bardzo ważna część.Aby zresetować każdy plik w określonym folderze (i jego podfolderach), możesz użyć następującego polecenia:
źródło
git status
aby zobaczyć wszystko, co pozostało i zresetować je ręcznie, tjgit reset file
.Użyj
*
polecenia do obsługi wielu plików jednocześnie:itp.
źródło
.*
lub.*.prj
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.źródło
Załóżmy, że utworzę nowy plik
newFile.txt
:Załóżmy, że dodam plik przypadkowo
git add newFile.txt
:Teraz chcę cofnąć to dodanie przed zatwierdzeniem
git reset newFile.txt
:źródło
W przypadku konkretnego pliku:
Dla wszystkich dodanych plików:
Uwaga: kasa zmienia kod w plikach i przechodzi do ostatniego zaktualizowanego (zatwierdzonego) stanu. reset nie zmienia kodów; po prostu resetuje nagłówek.
źródło
git reset <file>
igit checkout <file>
.Ta komenda usunie twoje zmiany:
Możesz także użyć
aby dodać części plików.
źródło
Istnieje również tryb interaktywny:
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
źródło
Aby cofnąć
git add
, użyj:źródło
Usunie plik o nazwie filename.txt z bieżącego indeksu, obszaru „wkrótce do zatwierdzenia”, bez zmiany czegokolwiek innego.
źródło
git add myfile.txt
# Spowoduje to dodanie pliku do listy do zatwierdzeniaWręcz przeciwnie do tego polecenia,
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.
źródło
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:
Sourcetree używa
reset
do wypuszczania nowych plików.źródło
źródło