Jak mogę ponownie ustawić scenę po dokonaniu lokalnego zatwierdzenia?

268

Wykonałem następujące polecenie

git add <foo.java>
git commit -m "add the foo.java file"

Jak mogę teraz usunąć moje lokalne zatwierdzenie i wycofać foo.java?

Jeśli piszę git reset --hard, okazało się, że przywraca to zmodyfikowane foo.javado oryginalnego.

Zestaw Ho
źródło

Odpowiedzi:

451

git reset --soft HEAD~1powinien robić co chcesz. Następnie będziesz mieć pierwsze zmiany w indeksie (widoczne za pomocą git diff --cached), a najnowsze zmiany nie zostaną wprowadzone. git statusbędzie wyglądać następująco:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:   foo.java
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo.java
#

Następnie możesz wykonać git add foo.javai zatwierdzić obie zmiany jednocześnie.

Antti
źródło
Zredagowałem odpowiedź: „Zmiany do zatwierdzenia” mają pierwsze zmiany, a „zmiany, które nie zostały wprowadzone do zatwierdzenia”, mają drugie zmiany.
Antti
4
To, co jest opisane w tej odpowiedzi, jest właściwie tym, co git commit --amendrobi; ale przy znacznie bardziej skomplikowanym przepływie pracy. To nie odpowiada na zadane pytanie OP, pomimo podania dobrego kierunku ( git reset).
7heo.tk
2
Musiałem zamienić „^” na „~”, aby działało, więc wygląda to tak:git reset --soft HEAD~
Shahar
3
zrób git reset - miękka GŁOWA ~ 1, a następnie git zresetuj GŁOWA
Joko Wandiro
idealna odpowiedź na to, czego chcę!
DeepInJava
78

Posługiwać się:

git reset HEAD^

Spowoduje to domyślny reset „mieszany”, co spowoduje wykonanie żądanego zadania; wstaw foo.java w scenę, usuwając najnowsze zatwierdzenie.

Ryan Stewart
źródło
2
Czy mógłbyś mi wyjaśnić, co to jest „mieszany” reset, „miękki” reset i „twardy” reset?
Kit Ho
1
@Kit Ho - git reset manual ma ich doskonałe opisy.
manojlds
4
@Kit, @manojlds: Tak też stackoverflow.com/questions/2530060/... (bezwstydna wtyczka)
Cascabel
5
To właściwie jedyna poprawna odpowiedź. Dwie pozostałe odpowiedzi ustawią pliki ponownie po zatwierdzeniu.
7heo.tk
git reset --softnie działa, ale git reset HEAD^nie
wordsforthewise
43

Dla mnie, następujący sposób jest bardziej czytelny (a zatem preferowany) sposób:

git reset HEAD~1

Zamiast tego 1może istnieć dowolna liczba zatwierdzeń, które chcesz wycofać.

Andrey Deineko
źródło
39

git reset --softjest po prostu do tego: jest jak git reset --hard, ale nie dotyka plików.

wRAR
źródło
4
To było najbardziej zrozumiałe wytłumaczenie, jakie do tej pory słyszałem (w zaledwie 11 słowach)! Dzięki!
phreakhead
3
Ta odpowiedź jest zła. git reset„jest jak, git reset --hardale nie dotyka plików.”. Nie git reset --soft. git reset --softwprowadzi zmiany, więc nie będziesz musiał dodawać ich do inscenizacji na wypadek, gdybyś chciał je zatwierdzić, ale będziesz musiał git resetje wprowadzić (tak, po raz drugi i bez --soft) na wypadek, gdybyś tego nie zrobił. Ta odpowiedź jest krótka, ale niepoprawna.
7heo.tk
12

Aby cofnąć wyświetlanie wszystkich plików w ostatnim zatwierdzeniu -

git reset HEAD~

Lavika
źródło
8

„Reset” to lokalny sposób cofania zmian. Podczas zatwierdzania najpierw wybierasz zmiany, które chcesz uwzględnić w „ git add ” - to się nazywa „inscenizacja”. A kiedy zmiany zostaną wprowadzone, wtedy „ zatwierdzasz ” je.

Aby wycofać się z inscenizacji lub zatwierdzenia, „resetujesz” HEAD. W gałęzi HEAD jest zmienną git, która wskazuje na ostatnie zatwierdzenie. Więc jeśli wystawiłeś inscenizację, ale się nie zaangażowałeś, „ resetujesz HEAD ”. Jest to zgodne z obecnym HEAD, usuwając zmiany ze sceny. To skrót od „ git reset - mixed HEAD ~ 0 ”.

Jeśli już zatwierdziłeś, HEAD już się posunął, więc musisz wykonać kopię zapasową do poprzedniego zatwierdzenia. Tutaj „ resetujesz HEAD ~ 1 ” lub „ resetujesz HEAD ^ 1 ” lub „ resetujesz HEAD ~ ” lub „ reset HEAD ^ ” - wszystkie odniesienia HEAD minus jeden.

Który lepszy symbol ~ lub ^? Pomyśl o tyldy ~ jako o pojedynczym strumieniu - gdy każde zatwierdzenie ma pojedynczego rodzica i jest to po prostu seria zmian w sekwencji, możesz odwoływać się do strumienia za pomocą tyldy, jako HEAD ~ 1, HEAD ~ 2, HEAD ~ 3, dla rodzica, dziadka, pradziadka itp. (Technicznie jest to znalezienie pierwszego rodzica we wcześniejszych pokoleniach).

Kiedy następuje scalenie, zatwierdzenia mają więcej niż jednego rodzica. Wtedy pojawia się ^ caret - pamiętasz, ponieważ pokazuje gałęzie, które się ze sobą łączą. Korzystając z karetki, HEAD ^ 1 byłby pierwszym rodzicem, a HEAD ^ 2 byłby drugim rodzicem pojedynczego zatwierdzenia - na przykład matki i ojca.

Więc jeśli cofasz się tylko o jeden skok w zatwierdzeniu przez jednego rodzica, HEAD ~ i HEAD ^ są równoważne - możesz użyć jednego z nich.

Również reset może być --soft , --mixed lub --hard . Miękki reset po prostu wycofuje zatwierdzenie - resetuje HEAD, ale nie pobiera plików z wcześniejszego zatwierdzenia, więc wszystkie zmiany w katalogu roboczym zostają zachowane. I --soft reset nie kasuje nawet sceny (znanej również jako indeks) ), więc wszystkie pliki, które zostały wyreżyserowane, nadal będą na scenie.

--Mixed resetu (domyślnie) również nie sprawdza się pliki z wcześniej popełnić, więc wszystkie zmiany zostaną zachowane, ale scena jest wyczyszczone. Właśnie dlatego prosty „ GIT reset HEAD ” ze sceny.

- - twardy reset resetuje HEAD i czyści scenę, ale także sprawdza wszystkie pliki z wcześniejszego zatwierdzenia, więc zastępuje wszelkie zmiany.

Jeśli przekazałeś zatwierdzenie do zdalnego repozytorium, reset nie działa tak dobrze. Możesz zresetować lokalnie, ale kiedy spróbujesz pchnąć do pilota, git zobaczy, że twój lokalny HEAD znajduje się za HEAD w zdalnej gałęzi i odmówi pchnięcia. Możesz być w stanie wymusić push, ale git naprawdę nie lubi tego robić.

Alternatywnie możesz ukryć swoje zmiany, jeśli chcesz je zachować, sprawdzić wcześniejsze zatwierdzenie, cofnąć ukrywanie zmian, wprowadzić je w etap, utworzyć nowe zatwierdzenie, a następnie je przesłać.

HieroB
źródło
+1 za szczegółowe wyjaśnienie operacji. IMO to powinna być zaakceptowana odpowiedź!
ISAE
2

Powiedzmy, że chcesz wprowadzić zmiany do n zatwierdzeń,

Skróty zatwierdzania są następujące:

  • h1
  • h2 ...
  • hn
  • hn + 1

Następnie uruchom następujące polecenie:
git reset hn

Teraz HEAD będzie w hn + 1. Zmiany z h1 na hn zostaną wycofane ze sceny.

Vasantha Ganesh K.
źródło