Wyrzuć lokalne zobowiązania w Git

1467

Z powodu złej selekcji, moje lokalne repozytorium Git jest obecnie pięć zatwierdzeń przed początkiem i nie jest w dobrym stanie. Chcę pozbyć się tych wszystkich zobowiązań i zacząć od nowa.

Oczywiście usunięcie mojego katalogu roboczego i ponowne klonowanie to by zrobiło, ale ponowne pobranie wszystkiego z GitHub wydaje się przesadą i nie jest dobrym wykorzystaniem mojego czasu.

Być może git revertjest to, czego potrzebuję, ale nie chcę kończyć 10 zatwierdzeń przed początkiem (lub nawet sześcioma), nawet jeśli przywróci sam kod do właściwego stanu. Chcę tylko udawać, że ostatnie pół godziny się nie wydarzyło.

Czy istnieje proste polecenie, które to zrobi? Wydaje się, że jest to oczywisty przypadek użycia, ale nie znajduję żadnych jego przykładów.


Pamiętaj, że to pytanie dotyczy w szczególności zatwierdzeń , a nie :

  • nieśledzone pliki
  • zmiany nieetapowane
  • zainscenizowane, ale niezaangażowane zmiany
David Moles
źródło

Odpowiedzi:

2468

Jeśli twoje nadwyżki zatwierdzeń są widoczne tylko dla ciebie, możesz po prostu git reset --hard origin/<branch_name> cofnąć się do miejsca pochodzenia. Spowoduje to zresetowanie stanu repozytorium do poprzedniego zatwierdzenia i odrzuci wszystkie lokalne zmiany.

Wykonanie a git revertpowoduje, że nowe zatwierdzenia usuwają stare zatwierdzenia w sposób, który pozwala zachować rozsądek w historii wszystkich.

Ben Jackson
źródło
90
git reset --hard <commit hash, branch, or tag>jeśli chcesz przejść do określonego odwołania innego niż oddział zdalny.
Sam Soffes,
55
Dla jasności, jeśli nie pracujesz, masterale w innym oddziale, powinieneś biecgit reset --hard origin/<your-branch-name>
Zoltán
33
Spowoduje to nie tylko odrzucenie lokalnych zatwierdzeń, ale także wyrzucenie wszystkiego z drzewa roboczego (tj. Plików lokalnych użytkownika). Jeśli wszystko, co chcesz zrobić, to niezalecane, ale zostaw swoją pracę nienaruszoną, powinieneś zrobić „git reset HEAD ^” ... per stackoverflow.com/questions/2845731
aaronbauman 28.01.2016
3
Po tym możesz chcieć pobrać. To naprawiło licznik liczby zobowiązań oczekujących na wypchnięcie na SourceTree.
Stan
2
git reset --hard origin/<branch_name>Zresetuje również konfigurację projektu, więc zadbaj o to. Mam duży .cfgplik, który został zresetowany do wartości domyślnych. Musiałem znów spędzić nad tym godziny.
MAC
271

Po prostu usuń lokalną gałąź główną i utwórz ją w następujący sposób:

git branch -D master
git checkout origin/master -b master
Ramon Zarazua B.
źródło
2
Działa to dobrze, gdy cofanie zmian może kosztować zbyt dużo czasu, co przydarzyło mi się po kilku zmianach.
aross
1
Przydatne w przypadku problemów z wyciąganiem / pchaniem poddrzewa wśród członków zespołu!
Jorge Orpinel,
Jest to idealne rozwiązanie, gdy chcesz przywrócić gałąź zamiast po prostu master.
Vladimir Ralev
1
nie jest to dobry sposób na usunięcie pojedynczego zatwierdzenia lokalnego. Lepszy w użyciugit reset --hard origin/<branch_name>
Kirit Vaghela,
1
Może to rozwiązanie zadziała, ale to nie znaczy, że jest właściwe.
Adly
201

Próbować:

git reset --hard <the sha1 hash>

zresetować głowę tam, gdzie chcesz być. Użyj gitk, aby zobaczyć, w którym zatwierdzeniu chcesz być. Możesz zresetować również w gitk.

Anders Zommarin
źródło
5
Przegłosowałem to czarno-białe, że jest to przydatna informacja, ale odpowiedź Bena Jacksona otrzymuje znacznik wyboru dla dokładnego rozwiązania tego, czego chciałem - w sposób, który nie wymagał ode mnie szukania skrótów zatwierdzania. :)
David Moles
2
Jest to jeden, gdy nowy oddział nie został zepchnięty do pochodzenia jeszcze
Jan
126

Usuń ostatnie zatwierdzenie:

git reset --hard HEAD~1

Usuń ostatni zatwierdzenie, nie niszcząc pracy, którą wykonałeś:

git reset --soft HEAD~1

James L.
źródło
5
Przydatna odpowiedź. Dziękuję Ci! Użyłem git reset --soft origin / master
Tarun Kumar
2
@TarunKumar DZIĘKUJĘ! Korzystam z integracji VS, a twoje rozwiązanie było jedynym sposobem, w jaki mogłem wymazać kilka zatwierdzeń scalania, których nie chciałem w oddziale, w którym nie miałem pozwolenia na rejestrację.
DVK
Dzięki, właśnie tego szukałem, „git reset - soft HEAD ~ 1” wykonał pracę, ponieważ popełniłem nieumyślnie i chciałem przywrócić, ale miałem inne pliki, których nie chciałem zniszczyć po przywróceniu.
edvard_munch
47

Jeśli korzystasz z aplikacji Atlassian SourceTree , możesz skorzystać z opcji resetowania w menu kontekstowym.

wprowadź opis zdjęcia tutaj

ogromny
źródło
42

Podczas próby oddziału:

git reset --hard origin/<branch_name>

Sprawdź poprawność odwrócenia (do stanu, bez lokalnych zatwierdzeń), używając odtąd „ git log” lub „ git status”.

parasrish
źródło
1
@Troyseph: wszystkie odpowiedzi wymienione powyżej próbowałem w obecnej formie i nie udało mi się naprawić scenariusza. Podejście ogólne, które nie zostało zilustrowane w żadnej z powyższych odpowiedzi, zostało tutaj wypróbowane.
parasrish
3
Przyjęta odpowiedź jest taka sama jak twoja, pomniejszona o ogólną nazwę oddziału, aw komentarzach @Zoltan wyraźnie mówiJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph
1
To jest najlepsza odpowiedź moim zdaniem.
dwjohnston
21

git reset --hard @{u}* usuwa wszystkie lokalne zmiany w bieżącym oddziale, w tym zatwierdzenia. Dziwię się, że nikt tego jeszcze nie opublikował, biorąc pod uwagę, że nie będziesz musiał sprawdzać, co zobowiązuje się do powrotu lub zabawy z oddziałami.

* To znaczy, przywróć bieżącą gałąź w - @{upstream}często origin/<branchname>, ale nie zawsze

Kevin Chen
źródło
1
Niektóre muszle, takie jak ryby, będą interpretować „@”, więc może być konieczne wstawienie „@ {u}” w cudzysłowie, np. „Git reset --hard” @ {u} ”. W każdym razie, dobre znalezisko!
trysis
Niesamowita odpowiedź jest niesamowita
Marko
1
Jak wydrukować wartość @ {u}?
Philip Rego
12

Aby zobaczyć / uzyskać identyfikator SHA-1 zatwierdzenia, do którego chcesz wrócić

gitk --all

Aby przywrócić do tego zatwierdzenia

git reset --hard sha1_id

!Uwaga. Wszystkie zatwierdzenia dokonane po tym zatwierdzeniu zostaną usunięte (i wszystkie zmiany w projekcie). Najpierw lepiej sklonuj projekt do innej gałęzi lub skopiuj do innego katalogu.

Mikołaj
źródło
jest to świetne w sytuacjach, gdy pilot nie jest już dostępny i wystarczy zresetować do lokalnego zatwierdzenia. gitk jest niesamowity - wcześniej nie był tego świadomy.
theRiley
Jeśli jesteś już na gitku, możesz również kliknąć prawym przyciskiem myszy na zatwierdzenie i wybrać „zresetuj gałąź XY tutaj”.
mkrieger1
A nowsze zatwierdzenia nie zostaną natychmiast usunięte. Po prostu nie ma już żadnej gałęzi, która by do nich prowadziła (pamiętaj, że gałąź jest jedynie „zakładką” do konkretnego zatwierdzenia).
mkrieger1
9

Miałem sytuację, w której chciałem usunąć zatwierdzenie, które nie zostało wypchnięte, ale zatwierdzenie było wcześniejsze. Aby to zrobić, użyłem następującego polecenia

git rebase -i HEAD~2 -> spowoduje bazowanie dwóch ostatnich zatwierdzeń

I użyłem „drop” dla podpisu zatwierdzenia, który chciałem usunąć.

Robert
źródło
9

Usuń nieśledzone pliki (niezatwierdzone zmiany lokalne)

git clean -df

Trwale usuwa wszystkie lokalne zatwierdzenia i pobiera najnowsze zdalne zatwierdzanie

git reset --hard origin/<branch_name>
ElasticCode
źródło
8

W przypadku lokalnych zatwierdzeń, które nie są wypychane, możesz także użyć git rebase -ido usunięcia lub zmiażdżenia zatwierdzenia.

Nikhil Katre
źródło
1
Wiem, że to może nie być najkrótsze rozwiązanie, ale głosowałem za tobą, ponieważ IMHO git rebase -ijest bardziej ogólnym sposobem rozwiązywania wielu podobnych problemów i może być pomocny w różnych sytuacjach.
Stefan Marinov
1
Użyj dropsłowa kluczowego (zamiast usuwania wiersza) podczas usuwania wszystkich zatwierdzeń, aby uniknąć przerwania rebase.
Michal Čizmazia
6

Prostym rozwiązaniem będzie dopasowanie lokalnego oddziału HEAD do źródła / oddziału HEAD

git reset --hard origin/master

PS: origin / master - jest zdalnym wskaźnikiem do gałęzi master. Możesz zastąpić master dowolną nazwą oddziału

narwanimonish
źródło
4

Zanim odpowiemy, dodajmy tło, wyjaśniając, co to jest HEAD. ponieważ niektóre z poniższych opcji spowodują odłączenie głowy

First of all what is HEAD?

HEADjest po prostu odniesieniem do bieżącego zatwierdzenia (najnowszego) w bieżącej gałęzi.
W HEADdanym momencie może być tylko jeden . (z wyłączeniem git worktree)

Zawartość HEADjest przechowywana w środku .git/HEADi zawiera 40 bajtów SHA-1 bieżącego zatwierdzenia.


detached HEAD

Jeśli nie korzystasz z ostatniego zatwierdzenia, co oznacza, że HEADnazywa się to wcześniejszym zatwierdzeniem w historii detached HEAD.

wprowadź opis zdjęcia tutaj

W wierszu polecenia będzie to wyglądało tak: SHA-1 zamiast nazwy gałęzi, ponieważ HEADnie wskazuje ona końca wierzchołka bieżącej gałęzi

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Kilka opcji odzyskiwania po odłączeniu HEAD:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Spowoduje to pobranie nowej gałęzi wskazującej żądany zatwierdzenie.
To polecenie pobierze do danego zatwierdzenia.
W tym momencie możesz utworzyć gałąź i od tego momentu zacząć pracować.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Zawsze możesz również użyć reflog.
git reflogwyświetli każdą zmianę, która zaktualizowała HEADi sprawdzenie żądanego wpisu ponownego logowania spowoduje HEADpowrót do tego zatwierdzenia.

Za każdym razem, gdy HEAD zostanie zmodyfikowany, pojawi się nowy wpis w reflog

git reflog
git checkout HEAD@{...}

Spowoduje to powrót do żądanego zatwierdzenia

wprowadź opis zdjęcia tutaj


git reset --hard <commit_id>

„Przenieś” HEAD z powrotem do żądanego zatwierdzenia.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Uwaga: ( od wersji Git 2.7 )
    możesz również korzystać z nich git rebase --no-autostash.

git revert <sha-1>

„Cofnij” podany zakres zatwierdzania lub zatwierdzania.
Polecenie reset spowoduje „cofnięcie” wszelkich zmian dokonanych w danym zatwierdzeniu.
Nowe zatwierdzenie z łatką cofania zostanie zatwierdzone, podczas gdy oryginalne zatwierdzenie pozostanie również w historii.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Ten schemat ilustruje, które polecenie robi co.
Jak widać, reset && checkoutzmodyfikuj HEAD.

wprowadź opis zdjęcia tutaj

CodeWizard
źródło
3

Dla osób zainteresowanych rozwiązaniem Visual Studio, oto ćwiczenie:

  1. W Team Exploreroknie połącz się z docelowym repozytorium.
  2. Następnie Brancheskliknij prawym przyciskiem myszy gałąź zainteresowania i wybierz View history.
  3. Kliknij prawym przyciskiem myszy zatwierdzenie w Historyoknie i wybierz Reset -> Delete changes (--hard).

Spowoduje to usunięcie lokalnych zatwierdzeń i zresetowanie stanu repozytorium do wybranego zatwierdzenia. Tzn. Twoje zmiany po wycofaniu repo zostaną utracone.

Bozhidar Stoyneff
źródło
2

Jeśli Twój oddział wyprzedza „ origin/XXX” o 5 zatwierdzeń.

Możesz wydać:

git reset --hard HEAD~5

I powinno usunąć ostatnie 5 zatwierdzeń.

Ha Choo
źródło
0
git reset --hard <SHA-Code>

Przyda się to, jeśli popełniłeś jakieś błędy w lokalnej kopii, które chcesz mieć pewność, że nie zostaną przypadkowo zepchnięte do twojego oddziału.

Kod SHA można uzyskać, przeglądając webVersion pulpitu git dla ostatniego zatwierdzenia w gałęzi.

W ten sposób możesz zsynchronizować się z ostatnim zatwierdzeniem w gałęzi.

Możesz to zrobić git pullpo pomyślnym zakończeniu twardego resetu, aby potwierdzić nic nowego do synchronizacji, tzn. Zobaczysz komunikat.

Twój oddział jest aktualny Origin/<Branch Name>

Sameer Ashraf
źródło
0

Jeśli wprawisz lokalne repozytorium w kompletny bałagan, to niezawodnym sposobem na odrzucenie lokalnych zatwierdzeń w Git jest ...

  1. Użyj „git config --get remote.origin.url”, aby uzyskać adres URL zdalnego pochodzenia
  2. Zmień nazwę lokalnego folderu git na „my_broken_local_repo”
  3. Użyj „git clone <url_from_1>”, aby uzyskać świeżą lokalną kopię zdalnego repozytorium git

Z mojego doświadczenia Eclipse dobrze sobie radzi w zmieniającym się świecie. Może jednak być konieczne wybranie dotkniętych projektów w Eclipse i ich wyczyszczenie, aby zmusić Eclipse do ich odbudowania. Sądzę, że inne IDE również mogą wymagać wymuszonej przebudowy.

Zaletą powyższej procedury jest to, że dowiesz się, czy twój projekt opiera się na plikach lokalnych, które nie zostały wprowadzone do git. Jeśli stwierdzisz, że brakuje Ci plików, możesz skopiować je z „my_broken_local_repo” i dodać je do git. Gdy masz pewność, że Twoje nowe lokalne repozytorium zawiera wszystko, czego potrzebujesz, możesz usunąć „my_broken_local_repo”.

Adam Gawne-Cain
źródło
0

Jeśli chcesz po prostu wyrzucić lokalne zatwierdzenia i zachować modyfikacje wykonane w plikach, wykonaj
git reset @ ~
Inne odpowiedzi dotyczyły twardego resetu

Ashish Banker
źródło