Jak przywrócić wszystkie lokalne zmiany w projekcie zarządzanym przez Git do poprzedniego stanu?

1913

Mam projekt, w którym prowadziłem git init. Po kilku zobowiązaniach zrobiłem to, git statusco powiedziało mi, że wszystko jest aktualne i nie było żadnych lokalnych zmian.

Potem wprowadziłem kilka kolejnych zmian i zdałem sobie sprawę, że chcę wszystko wyrzucić i wrócić do pierwotnego stanu. Czy to polecenie zrobi to za mnie?

git reset --hard HEAD
Jacques René Mesrine
źródło

Odpowiedzi:

3387

Jeśli chcesz przywrócić zmiany wprowadzone w kopii roboczej, wykonaj następujące czynności:

git checkout .

Jeśli chcesz przywrócić zmiany wprowadzone w indeksie (tj. Dodane), zrób to. Uwaga, spowoduje to zresetowanie wszystkich nieprzypisanych zobowiązań do opanowania! :

git reset

Jeśli chcesz cofnąć zatwierdzoną zmianę, wykonaj następujące czynności:

git revert <commit 1> <commit 2>

Jeśli chcesz usunąć nieśledzone pliki (np. Nowe pliki, pliki wygenerowane):

git clean -f

Lub nieśledzone katalogi (np. Nowe lub automatycznie generowane katalogi):

git clean -fd
1800 INFORMACJI
źródło
133
fwiw po tak długim czasie git checkout path/to/fileprzywróci tylko lokalne zmiany dopath/to/file
Matijs,
29
+1 od odpowiedzi poniżej również wymieniających git czyste -f (aby usunąć nieśledzone zmian) i -fd (również usunąć nieśledzone katalogów)
ptdev
3
a jeśli chcesz również wyczyścić nieśledzone pliki, przeczytaj ten stackoverflow.com/questions/61212/…
Surasin Tancharoen
9
git checkout .i git reset [--hard HEAD]nie działało, musiałem git clean -fdcofnąć zmiany.
BrainSlugs83
7
git resetnie resetuje twoich zmian, git reset --hardrobi to.
Cerin,
388

Uwaga: możesz także chcieć uruchomić

git clean -fd

tak jak

git reset --hard

będzie nie usunąć nieśledzone plików, gdzie jako git-clean usunie wszystkie pliki z katalogu głównego gąsienicowego, które nie są pod git śledzenia. OSTRZEŻENIE - UWAŻAJ TO! Pomocne jest uruchomienie najpierw suchego programu z git-clean, aby zobaczyć, co usunie.

Jest to szczególnie przydatne, gdy pojawi się komunikat o błędzie

~"performing this command will cause an un-tracked file to be overwritten"

Może się to zdarzyć, gdy wykonujesz kilka czynności, jedną z nich jest aktualizowanie kopii roboczej, gdy ty i twój przyjaciel dodaliście nowy plik o tej samej nazwie, ale najpierw przekazał go do kontroli źródła, a ty nie obchodzi cię usunięcie nieśledzonej kopii .

W tej sytuacji wykonanie suchego rozruchu pomoże również wyświetlić listę plików, które zostaną zastąpione.

Antony Stubbs
źródło
13
Polecenie file clean to „git clean -f”. Nieśledzone katalogów są usuwane z „git czystej -d”
Jonathan Mitchell
35
git clean -fd (wymagana jest siła dla -d)
electblake
14
-n lub --dry-run są flagami dla suchobiegu.
stephenbez
2
git clean -ffd, jeśli masz inne repozytorium git w swoim repozytorium git. Bez podwójnego f nie zostałby usunięty.
Trismegistos,
148

Ponownie sklonuj

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Usuwa lokalne, nieprzesunięte zatwierdzenia
  • ✅ Cofa wprowadzone zmiany w śledzonych plikach
  • ✅ Przywraca usunięte pliki
  • ✅ Usuwa pliki / katalogi wymienione w .gitignore(jak pliki kompilacji)
  • ✅ Usuwa pliki / katalogi, które nie są śledzone i nie znajdują się w .gitignore
  • 😀 Nie zapomnisz tego podejścia
  • 😔 Marnuje przepustowość

Oto inne polecenia, o których codziennie zapominam.

Wyczyść i zresetuj

git clean --force -d -x
git reset --hard
  • ❌ Usuwa lokalne, nieprzesunięte zatwierdzenia
  • ✅ Cofa wprowadzone zmiany w śledzonych plikach
  • ✅ Przywraca usunięte pliki
  • ✅ Usuwa pliki / katalogi wymienione w .gitignore(jak pliki kompilacji)
  • ✅ Usuwa pliki / katalogi, które nie są śledzone i nie znajdują się w .gitignore

Czysty

git clean --force -d -x
  • ❌ Usuwa lokalne, nieprzesunięte zatwierdzenia
  • ❌ Cofa wprowadzone zmiany w śledzonych plikach
  • ❌ Przywraca usunięte pliki
  • ✅ Usuwa pliki / katalogi wymienione w .gitignore(jak pliki kompilacji)
  • ✅ Usuwa pliki / katalogi, które nie są śledzone i nie znajdują się w .gitignore

Resetowanie

git reset --hard
  • ❌ Usuwa lokalne, nieprzesunięte zatwierdzenia
  • ✅ Cofa wprowadzone zmiany w śledzonych plikach
  • ✅ Przywraca usunięte pliki
  • ❌ Usuwa pliki / katalogi wymienione w .gitignore(jak pliki kompilacji)
  • ❌ Usuwa pliki / katalogi, które nie są śledzone i nie znajdują się w .gitignore

Notatki

Przypadek testowy do potwierdzenia wszystkich powyższych (użyj bash lub sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

Zobacz też

  • git revert do dokonywania nowych zatwierdzeń, które cofają wcześniejsze zatwierdzenia
  • git checkout cofnąć się w czasie do wcześniejszych zatwierdzeń (może wymagać najpierw uruchomienia powyższych poleceń)
  • git stashtak samo jak git resetpowyżej, ale możesz to cofnąć
William Entriken
źródło
Przepraszamy za kradzież z powyższych odpowiedzi. Używam tego odniesienia stale, publikując głównie dla mnie.
William Entriken,
1
Jestem całkiem pewien, że pierwsza opcja ( Ponowne klonowanie ) faktycznie „USUWA lokalne, nieprzesunięte zatwierdzenia” :)
Marandil
1
@styfle ✅ jest czymś, co robi, ❌ jest czymś, czego nie robi
William Entriken
3
@FullDecent Czytanie jest trochę mylące. „❌ NIE usuwa lokalnych, nieprzesuniętych zatwierdzeń”. Oznacza to, że NIE można go usunąć. Podwójny negatyw oznacza, że ​​usuwa?
styfle
1
Informacje o opcji -x w git clean -f -d -x: jeśli podano opcję -x, ignorowane pliki są również usuwane. Może to być przydatne na przykład do usunięcia wszystkich produktów kompilacji. - z dokumentów GIT
Alex
82

Jeśli chcesz cofnąć wszystkie zmiany ORAZ być na bieżąco z bieżącym zdalnym urządzeniem nadrzędnym (na przykład okazuje się, że HEAD nadrzędny posunął się do przodu od momentu jego rozgałęzienia i „push” jest odrzucany), możesz użyć

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.
Michael Durrant
źródło
Wydaje się ważne, aby określić originw git reset --hard origin/master(który działa) - bez niego (tj. git reset --hard) Nic nie wydaje się być zmienione.
Jake,
Miałem kilka lokalnych zmian i nie byłem w stanie ich się pozbyć za pomocą żadnego polecenia, które zresetowałem - twarde pochodzenie / master i on był w stanie również wyciągnąć zmiany mistrza
abhishek ringsia
50

Zajrzyj do git-reflog. Spowoduje to wyświetlenie wszystkich stanów, które pamięta (domyślnie jest to 30 dni), i możesz po prostu sprawdzić ten, który chcesz. Na przykład:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d
William Pursell
źródło
dzięki ton Williamie, za git reflog. Zresetujełem moje drzewo do starej wersji i nie jestem pewien, jak wrócić do najnowszej wersji. Twój git reflog mnie uratował. Jeszcze raz dziękuję.
palaniraja
1
również mnie uratował! W moim przypadku moja przygoda z git rebase -iposzła nie tak (skończyłem z usuwaniem niektórych błędów z powodu błędu edycji). Dzięki tej wskazówce jestem z powrotem w dobrym stanie!
paneer_tikka
Co rozumiesz przez 30 dni domyślne?
Mohe TheDreamy,
@MoheTheDreamy Mam na myśli, że istnieje limit czasu. W końcu śmietnik usunie nieosiągalne odniesienia, gdy ich wiek przekroczy ten limit. Domyślnie było to (i może nadal jest) 30 dni. Dlatego starsze referencje mogą być niedostępne.
William Pursell,
36

NIEBEZPIECZEŃSTWO WCZEŚNIEJ: (proszę przeczytać komentarze. Wykonanie polecenia zaproponowanego w mojej odpowiedzi może usunąć więcej niż chcesz)

aby całkowicie usunąć wszystkie pliki, w tym katalogi, które musiałem uruchomić

git clean -f -d
Tobias Gassmann
źródło
13
Aby oszczędzić każdemu bólu, przez który właśnie przeszedłem: spowoduje to również usunięcie plików .gitignore-d!
landons
przepraszam, że sprawiłem ci kłopoty. Wtedy właśnie próbowałem przywrócić i usunąć wszystko w tym folderze. Nie pamiętam dokładnych okoliczności, ale „-d” było jedyną rzeczą, która działała dla mnie. Mam nadzieję, że nie sprawiłem Ci zbyt wiele bólu :-)
Tobias Gassmann
1
żadna krzywda. Miałem kopie zapasowe, ale prawdopodobnie uzasadnia to wyłączenie odpowiedzialności;)
landons
35

Po przeczytaniu wielu odpowiedzi i wypróbowaniu ich, znalazłem różne przypadki krawędzi, co oznacza, że ​​czasami nie w pełni czyszczą kopię roboczą.

Oto mój obecny skrypt bash do robienia tego, co działa cały czas.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Uruchom z katalogu głównego kopii roboczej.

Scott Davey
źródło
10
Ostatnie polecenie daje mierror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L,
1
To zadziałało, kiedy wyjąłem „-”. git checkout HEAD
Jester
4
git reset --hardprzywraca śledzone pliki ( git clean -f -dprzemieszczane lub nie), usuwa nieśledzone pliki, git checkout -- HEADdlaczego więc tego potrzebujemy?
v.shashenko
Nie potrzebujemy podwójnego łącznika. To musi być literówka.
Farax,
35

po prostu wykonaj -

git stash

usunie wszystkie lokalne zmiany. i możesz go później użyć, wykonując -

git stash apply 
piyushmandovra
źródło
3
użycie git stash popautomatycznie usunie najwyższą ukrytą zmianę dla Ciebie
Arrow Cen
8
git stash dropaby usunąć najnowszy stan ukryty bez zastosowania do kopii roboczej.
deerchao
git stash
Apply
27

Spotkałem podobny problem. Rozwiązaniem jest git logsprawdzenie, która wersja zatwierdzenia lokalnego różni się od wersji zdalnej. (Np. Wersja jest 3c74a11530697214cbcc4b7b98bf7a65952a34ec).

Następnie użyj, git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecaby cofnąć zmianę.

Patrick
źródło
16

Szukałem podobnego problemu,

Chciał wyrzucić lokalne zobowiązania:

  1. sklonował repozytorium (klon git)
  2. przełączono na gałąź programistów (git checkout dev)
  3. zrobił kilka zmian (git commit -m „commit 1”)
  4. ale postanowił wyrzucić te lokalne zobowiązania, aby wrócić do zdalnego (origin / dev)

Podobnie jak poniżej:

git reset --hard origin/dev

Czek:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

teraz lokalne zatwierdzenia są tracone, z powrotem do początkowego stanu sklonowania, punkt 1 powyżej.

Manohar Reddy Poreddy
źródło
1
dzięki, to jedyna rzecz, która zadziałała dla mnie - „git reset
hard
Cieszę się, że to pomogło.
Manohar Reddy Poreddy
7

Niekoniecznie chcesz / musisz ukryć swoje pliki robocze w katalogu roboczym, ale po prostu całkowicie się ich pozbyć. Polecenie git cleanzrobi to za ciebie.

Niektóre typowe przypadki użycia tego to usunięcie cruft , który został wygenerowany przez scalanie lub narzędzia zewnętrzne lub usunięcie innych plików, aby można było uruchomić czystą kompilację.

Pamiętaj, że będziesz bardzo ostrożny wobec tego polecenia, ponieważ służy ono do usuwania plików z lokalnego katalogu roboczego, które NIE SĄ ŚLEDZONE. jeśli nagle zmienisz zdanie po wykonaniu tej komendy, nie będziesz wracał, aby zobaczyć zawartość usuniętych plików. Alternatywą, która jest bezpieczniejsza, jest wykonanie

git stash --all

który usunie wszystko, ale zapisze to wszystko w skrytce. Ta skrytka może być później wykorzystana.

Jednak jeśli naprawdę chcesz usunąć wszystkie pliki i wyczyścić katalog roboczy, powinieneś wykonać

git clean -f -d

Spowoduje to usunięcie wszystkich plików, a także podkatalogów, które nie zawierają żadnych elementów w wyniku polecenia. Mądrą rzeczą do zrobienia przed wykonaniem git clean -f -dpolecenia jest uruchomienie

git clean -f -d -n

który pokaże podgląd tego, co zostanie usunięte po uruchomieniu git clean -f -d

Oto podsumowanie twoich opcji od najbardziej agresywnych do najmniej agresywnych


Opcja 1 : Usuń wszystkie pliki lokalnie (najbardziej agresywne)

git clean -f -d

Opcja 2 : podgląd powyższego wpływu (podgląd najbardziej agresywny)

git clean -f -d -n

Opcja 3 : Ukryj wszystkie pliki (najmniej agresywne)

`git stash --all` 
jbooker
źródło
6

Wypróbuj to, aby cofnąć wszystkie zmiany niezaangażowane w oddziale lokalnym

$ git reset --hard HEAD

Ale jeśli zobaczysz taki błąd:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Możesz przejść do folderu „.git”, a następnie usunąć plik index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Na koniec uruchom ponownie polecenie:

$ git reset --hard HEAD
Janderson Silva
źródło
0

To pytanie dotyczy bardziej szerszego resetowania / przywracania repozytorium, ale w przypadku, gdy chcesz cofnąć indywidualną zmianę - dodałem tutaj podobną odpowiedź:

https://stackoverflow.com/a/60890371/2338477

Odpowiedzi na pytania:

  • Jak przywrócić indywidualną zmianę z zachowaniem lub bez zmian w historii git

  • Jak wrócić do starej wersji, aby zrestartować z tego samego stanu

TarmoPikaro
źródło