Jak anulować lokalne zatwierdzenie git


744

Mój problem polega na tym, że zmieniłem plik, np .: README, dodałem nowy wiersz „ this for my test line ” i zapisałem plik, a następnie wydałem następujące polecenia

 git status

 # On branch master
 # Changed but not updated:
 #   (use "git add <file>..." to update what will be committed)
 #   (use "git checkout -- <file>..." to discard changes in working directory)
 #
 #  modified:   README
 #
 no changes added to commit (use "git add" and/or "git commit -a")


 git add README

 git commit -a -m 'To add new line to readme'

Nie wypchnąłem kodu do github, teraz chcę anulować to zatwierdzenie.

Do tego użyłem

   git reset --hard HEAD~1

Ale zgubiłem nowo dodaną linię „ to dla mojej linii testowej ” z pliku README. To nie powinno się zdarzyć. Potrzebuję treści, aby tam być. Czy istnieje sposób na zachowanie zawartości i anulowanie mojego lokalnego zatwierdzenia?


3
Wygląda na to, że zdecydowanie nie pytasz git revert, co tworzy nowe zatwierdzenie z odwrotnym różnicą cofniętego zatwierdzenia. Resetowanie po prostu wskazuje bieżącą gałąź na inne zatwierdzenie, w tym przypadku przed zatwierdzeniem, które chcesz „zapomnieć”.
Cascabel

1
Uwaga: Warto wspomnieć, że git-commitmożna przerwać, jeśli zostawisz wiadomość pustą, więc jeśli faktycznie nie ukończyłeś zatwierdzenia, może to być pomocne.
GKFX

Odpowiedzi:


1420

Po prostu użyj git resetbez --hardflagi:

git reset HEAD~1

PS: W systemach opartych na Uniksie możesz używać HEAD^równego HEAD~1. W systemie Windows HEAD^nie będzie działać, ponieważ ^sygnalizuje kontynuację linii. Więc twój wiersz polecenia po prostu cię zapyta More?.


13
Nawiasem mówiąc, nazywa się to --mixed w instrukcji .
Josh Lee

10
Nowsze wersje Git pozwalają nawet @^na skrót HEAD^.
Koraktor

Nie wiem, co to zrobiło, ale wiele plików pojawiło się na mojej liście zmian, plików, których nie dotknąłem
FRR

@feresr Jeśli tak naprawdę nie dotknąłeś tych plików w ostatnim zatwierdzeniu lub w drzewie roboczym, jest to spowodowane innymi niespójnościami w twoim drzewie roboczym, np. jesteś w systemie Windows, a końce plików się nie zgadzają.
Koraktor,

1
czy można zresetować wszystkie zatwierdzenia jedną ręką?
Webwoman

185

Użyj --softzamiast --hardflagi:

git reset --soft HEAD^

18
czy możesz wyjaśnić różnicę między 2 flagami?
John Giotta

1
Jeśli otworzysz konsolę Menedżera pakietów i uruchomisz „git reset --soft HEAD ^”, zrobi to, co chcesz (i to, czego potrzebowałem).
David Cornelson,

54
@JohnGiotta - git reset --soft HEAD^usunie ostatni lokalny (unpushed) zobowiązać ale zachować zmiany zostały zrobione
Fider

@fider Saviour! Nie jestem pewien, czy zaakceptowana odpowiedź nadal działa, ale powinna to być dokładna odpowiedź, jakiej potrzebuje PO.
Babu

git reset --soft HEAD~w
systemie

34

Jeśli jesteś w środku zatwierdzenia (tj. Już w edytorze), możesz go anulować, usuwając wszystkie wiersze powyżej pierwszego #. To przerwie zatwierdzenie.

Możesz więc usunąć wszystkie wiersze, aby komunikat zatwierdzenia był pusty, a następnie zapisz plik:

To powinno wyglądać tak.

Otrzymasz wiadomość z napisem Aborting commit due to empty commit message..

EDYTOWAĆ :

Możesz także usunąć wszystko linie, a wynik będzie dokładnie taki sam.

Aby usunąć wszystkie wiersze w vimie (jeśli jest to domyślny edytor), po przejściu do edytora wpisz, ggaby przejść do pierwszego wiersza, a następnie dGusuń wszystkie wiersze. Na koniec napisz i zamknij plik, wqa zatwierdzenie zostanie przerwane.


3
To jest dokładnie to, czego szukasz! Ta odpowiedź wymaga więcej głosów pozytywnych :)
jdunk

Do Twojej wiadomości, działa to również, jeśli próbujesz przerwaćrebase -i mybranchname
inostia

18

Pierwszą rzeczą, którą powinieneś zrobić, to ustalić, czy chcesz zachować lokalne zmiany przed usunięciem komunikatu zatwierdzenia.

Służy git logdo wyświetlania bieżących komunikatów zatwierdzania, a następnie znajdź commit_id przed zatwierdzeniem, który chcesz usunąć, a nie zatwierdzenie, które chcesz usunąć.

Jeśli chcesz zachować zmienione lokalnie pliki i po prostu usuń komunikat zatwierdzenia:

git reset --soft commit_id

Jeśli chcesz usunąć wszystkie lokalnie zmienione pliki i komunikat zatwierdzenia:

git reset --hard commit_id

To jest różnica miękkości i twardości


1
Myślę, że jest odwrotnie.
Ruff9

9

Możesz powiedzieć Gitowi, co zrobić ze swoim indeksem (zestawem plików, które staną się następnym zatwierdzeniem) i katalogiem roboczym podczas wykonywania resetowania gita, używając jednego z parametrów:

--soft: Tylko zatwierdzenia zostaną zresetowane, podczas gdy indeks i katalog roboczy nie zostaną zmienione.

--mixed: Spowoduje to zresetowanie indeksu zgodnie z HEAD, podczas gdy katalog roboczy nie zostanie zmieniony. Wszystkie zmiany pozostaną w katalogu roboczym i pojawią się jako zmodyfikowane.

--hard: Resetuje wszystko (zatwierdza, indeks, katalog roboczy), aby dopasować HEAD.

W twoim przypadku chciałbym git reset --softzachować zmodyfikowane zmiany w indeksie i katalogu roboczym. Sprawdź to, aby uzyskać bardziej szczegółowe wyjaśnienie.


1

Użyj poniższego polecenia:

$ git reset HEAD~1

Po tym możesz również przeglądać pliki, które cofają się jak poniżej odpowiedzi.

Unstaged changes after reset:
M   application/config/config.php
M   application/config/database.php
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.