Jaka jest różnica między 'git reset --hard HEAD ~ 1' a 'git reset --soft HEAD ~ 1'?

Odpowiedzi:

184

git resetzna pięć „trybów”: miękki, mieszany, twardy, scalaj i zachowaj. Zacznę od pierwszych trzech, ponieważ są to tryby, z którymi zwykle się spotykasz. Potem znajdziesz miły mały bonus, więc bądź na bieżąco.

miękki

Podczas używania git reset --soft HEAD~1usuniesz ostatnie zatwierdzenie z bieżącej gałęzi, ale zmiany w pliku pozostaną w twoim drzewie roboczym . Również zmiany pozostaną w twoim indeksie, więc po dodaniu a git commitstworzysz zatwierdzenie z dokładnie takimi samymi zmianami, jak zatwierdzenie, które "usunąłeś" wcześniej.

mieszany

Jest to tryb domyślny i podobny do trybu miękkiego. Kiedy "usuwasz" zatwierdzenie git reset HEAD~1, nadal zachowasz zmiany w swoim drzewie roboczym, ale nie w indeksie; więc jeśli chcesz "ponawiać" zatwierdzenie, będziesz musiał dodać zmiany ( git add) przed zatwierdzeniem.

ciężko

Podczas korzystania git reset --hard HEAD~1będziesz stracić wszystkie uncommited zmian w uzupełnieniu do zmian wprowadzonych w ostatnim popełnić. Zmiany nie pozostaną w twoim drzewie roboczym, więc wykonanie git statuspolecenia powie ci, że nie masz żadnych zmian w swoim repozytorium.

Ostrożnie chodź z tym. Jeśli przypadkowo usuniesz niezatwierdzone zmiany, które nigdy nie były śledzone przez git(mów: zatwierdzone lub przynajmniej dodane do indeksu), nie masz możliwości przywrócenia ich za pomocą git.

Premia

trzymać

git reset --keep HEAD~1jest interesujący i przydatny. Resetuje tylko pliki, które różnią się między bieżącym HEAD a podanym zatwierdzeniem. Przerywa resetowanie, jeśli którykolwiek z tych plików ma niezatwierdzone zmiany. Zasadniczo działa jako bezpieczniejsza wersja hard.

Ten tryb jest szczególnie przydatny, gdy masz kilka zmian i chcesz przełączyć się na inną gałąź bez utraty tych zmian - na przykład gdy zacząłeś pracować na niewłaściwej gałęzi.


Możesz przeczytać więcej na ten temat w dokumentacji resetowania git .

Uwaga
Podczas git resetusuwania zatwierdzenia, zatwierdzenie nie jest tak naprawdę utracone, po prostu nie ma odniesienia do niego ani żadnego z jego elementów podrzędnych. Nadal można odzyskać zatwierdzenie, które zostało „usunięte” git resetprzez znalezienie jego klucza SHA-1, na przykład za pomocą polecenia takiego jak git reflog.

Sascha Wolf
źródło
1
Nie zgadzam się, że te 3 to te, których zwykle powinniśmy używać. Są to 3, które były dostępne jako pierwsze, więc ludzie mówią o nich więcej, ale --hardprawie nigdy nie jest to właściwe, ponieważ --keepjest znacznie bezpieczniejsze i dotyczy większości senariuszy, w których --harddziała. Ćwiczenie palców --keepmoże cię uratować pewnego dnia ...
Matthieu Moy
Nie próbowałem sugerować, że powinniśmy ich używać, a jedynie, że są to polecenia, które spotyka się przez większość czasu. Możesz dowolnie edytować odpowiedź według własnego uznania.
Sascha Wolf
Aby dodać trochę więcej szczegółów, po git reset --soft HEAD ~ 1, używając git commit --reuse-message = HEAD @ {1}, aby ponownie użyć ostatniego zatwierdzenia z zachowanym starym indeksem, jak pokazano tutaj stackoverflow.com/a/ 25930432/2883282
englealuze
3
@MatthieuMoy, trzy lata później, ale dodałem sekcję na keep. ;)
Sascha Wolf
Jak mogę cofnąć ostatnie zatwierdzenie? Proszę pomóż. Jeśli użyję git reset --soft HEAD ~ 1, otrzymam: fatal: dwuznaczny argument 'HEAD ~ 1': nieznana wersja lub ścieżka nie znajduje się w drzewie roboczym. Użyj '-', aby oddzielić ścieżki od wersji, na przykład: 'git <command> [<revision> ...] - [<file> ...]'
elvis
8

Reset Gita ma 5 głównych trybów: miękki, mieszany, scalony, twardy, zachowaj . Różnica między nimi polega na zmianie lub niezmienności nagłówka, etapu (indeksu), katalogu roboczego .

Reset Gita - hard zmieni nagłówek, indeks i katalog roboczy.
Reset Gita - soft zmieni tylko głowę. Brak zmian w indeksie, katalogu roboczym.

Innymi słowy, jeśli chcesz cofnąć zatwierdzenie, opcja --soft powinna być wystarczająco dobra. Ale po tym nadal masz zmiany ze złego zatwierdzenia w indeksie i katalogu roboczym. Możesz modyfikować pliki, naprawiać je, dodawać do indeksowania i ponownie zatwierdzać.

Dzięki --twardemu projektowi otrzymujesz czysty plan. Jakby nie było żadnej zmiany od ostatniego zatwierdzenia. Jeśli jesteś pewien, że tego właśnie chcesz, przejdź dalej. Ale kiedy to zrobisz, całkowicie stracisz ostatnie zatwierdzenie. (Uwaga: nadal istnieją sposoby na odzyskanie utraconego zatwierdzenia).

apadana
źródło
5

Jest to przydatny artykuł, który w sposób graficzny przedstawia wyjaśnienie polecenia resetowania.

https://git-scm.com/docs/git-reset

Reset - twardy może być dość niebezpieczny, ponieważ nadpisuje kopię roboczą bez sprawdzania, więc jeśli w ogóle nie zatwierdziłeś pliku, zniknie.

Jeśli chodzi o drzewo źródłowe, nie mam możliwości cofnięcia zatwierdzeń. Najprawdopodobniej i tak użyłby resetu pod osłonami

FamiliarPie
źródło
+1 za link do oficjalnej dokumentacji. Chciałbym również wspomnieć, git reset --helpktóre dość dobrze (moim zdaniem) wyjaśnia pięć trybów, a przynajmniej dwa, o które poprosił PO.
ThanksForAllTheFish,
1
Link jest uszkodzony. Prawdopodobnie jest to aktualna wersja: git-scm.com/docs/git-reset
Kiki Jewell,
1

To jest główna różnica między use git reset --hard i git reset --soft:

--soft

W ogóle nie dotyka pliku indeksu ani drzewa roboczego (ale resetuje głowicę do, tak jak robią to wszystkie tryby). To pozostawia wszystkie zmienione pliki jako „Zmiany do zatwierdzenia”, jak określiłby to status git.

--hard

Resetuje indeks i drzewo robocze. Wszelkie zmiany w śledzonych plikach w drzewie roboczym są odrzucane.

Alexandr
źródło
1
To jest to, czego szukałem. Zwięzłe i dokładne.
Qasim