Jaka jest różnica między "Git reset" a "Git checkout"?
Zawsze myślałem o git reset
i git checkout
jako o tym samym, w tym sensie, że oba przynoszą projekt z powrotem do określonego commita. Jednak uważam, że nie mogą być dokładnie takie same, ponieważ byłoby to zbędne. Jaka jest rzeczywista różnica między nimi? Jestem trochę zdezorientowany, ponieważ svn ma tylko svn co
, aby przywrócić commit.
Dodano
VonC i Charles bardzo dobrze wyjaśnili różnice międzygit reset
i git checkout
. Moje obecne zrozumienie jest takie, że git reset
odwraca wszystkie zmian z powrotem do określonego commita, podczas gdy git checkout
mniej lub bardziej przygotowuje się do gałęzi. Okazało się, że następujące dwa diagramy są bardzo przydatne w osiągnięciu tego zrozumienia:
Dodano 3
Od http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html, kasa i reset mogą emulować rebase.
git checkout bar
git reset --hard newbar
git branch -d newbar
6 answers
-
git reset
w szczególności chodzi o aktualizację indeksu , poruszanie głową. -
git checkout
dotyczy aktualizacji drzewa roboczego (do indeksu lub podanego drzewa). Zaktualizuje głowicę tylko wtedy, gdy wymeldujesz gałąź (jeśli nie, skończysz z odłączoną głowicą ).
(w rzeczywistości, z Git 2.23 Q3 2019, będzie togit restore
, niekonieczniegit checkout
)
Dla porównania, ponieważ svn nie ma indeksu, tylko działa drzewo, svn checkout
skopiuje daną wersję do osobnego katalogu.
Bliższy odpowiednik dla git checkout
będzie:
-
svn update
(jeśli jesteś w tej samej gałęzi, co ten sam adres URL SVN) -
svn switch
(Jeśli dokonujesz transakcji na przykład z tej samej gałęzi, ale z innego adresu URL repo SVN)
Wszystkie te trzy działające modyfikacje drzewa (svn checkout
, update
, switch
) posiada tylko jedną komendę w git: git checkout
.
Ale ponieważ git ma również pojęcie indeksu (ten "obszar postojowy" między repo a drzewem roboczym), masz również git reset
.
Thinkeye wspomina w komentarzach artykuł "Reset Demystified ".
Na przykład, jeśli mamy dwie gałęzie,'
master
'i'develop
'wskazujące na różne commity, a obecnie jesteśmy na'develop
' (więc HEAD wskazuje na to) i uruchamiamygit reset master
, 'develop
' sam wskaże teraz ten sam commit, co 'master
'.Na drugim ręka, jeśli zamiast biec
git checkout master
, 'develop
' nie ruszy się,HEAD
sam się ruszy.HEAD
wskaże teraz "master
".Więc w obu przypadkach poruszamy się
HEAD
, aby wskazać na commitA
, ale sposób, w jaki to robimy, jest zupełnie inny.reset
przesunie gałąźHEAD
wskazuje na, checkout przesunie sięHEAD
, aby wskazać inną gałąź.
W tych punktach, choć:
LarsH dodaje w komentarzach :
Pierwszy akapit tej odpowiedzi jest jednak mylący: "
git checkout
... zaktualizuje głowicę tylko wtedy, gdy wymeldujesz gałąź (jeśli nie, skończysz z odłączoną głowicą)".
Nie prawda:git checkout
zaktualizuje głowicę, nawet jeśli wymeldujesz commit, który nie jest gałęzią (i tak, skończysz z odłączoną głowicą, ale nadal została zaktualizowana).git checkout a839e8f updates HEAD to point to commit a839e8f.
De Novo w komentarzach :
@LarsH ma rację.
Drugi pocisk ma błędne wyobrażenie informacje o tym, co jest w głowicy, zaktualizują głowicę tylko wtedy, gdy wymeldujesz oddział.
Głowa idzie gdziekolwiek jesteś, jak cień.
Sprawdzanie referencji niezwiązanych z gałęzią (np. znacznika) lub commita bezpośrednio spowoduje przesunięcie głowy. Wolnostojąca głowa nie oznacza, że odłączyłeś się od głowy, to znaczy, że głowa jest odłączona od gałęzi ref, którą możesz zobaczyć np.git log --pretty=format:"%d" -1
.
- dołączone Stany głowy rozpoczynają się od
(HEAD ->
,- odłączony nadal pokaże
(HEAD
, ale nie będzie strzała do gałęzi ref.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-31 04:47:54
W najprostszej formie reset
resetuje indeks bez dotykania drzewa roboczego, podczas gdy checkout
zmienia drzewo robocze bez dotykania indeksu.
Resetuje indeks tak, aby pasował do HEAD
, działające drzewo pozostawione samemu sobie:
git reset
Koncepcyjnie sprawdza indeks w drzewie roboczym. Aby to zrobić, musisz użyć -f
, aby wymusić nadpisanie lokalnych zmian. Jest to funkcja bezpieczeństwa, aby upewnić się, że Formularz "bez argumentu" nie jest destrukcyjny:
git checkout
Gdy zaczniesz dodawać parametry, to prawda, że istnieje pewne nakładanie się.
checkout
jest zwykle używany z gałęzią, tagiem lub commitem. W tym przypadku zresetuje HEAD
i indeks do podanego commita, a także wykona kasowanie indeksu do drzewa roboczego.
Ponadto, jeśli podasz --hard
do reset
możesz poprosić reset
o nadpisanie drzewa roboczego, a także o zresetowanie indeksu.
Jeśli masz aktualnie sprawdzoną gałąź istnieje zasadnicza różnica pomiędzy reset
i checkout
kiedy dostarczasz alternatywną gałąź lub commit. reset
zmieni bieżącą gałąź tak, aby wskazywała na wybrany commit, podczas gdy checkout
pozostawi bieżącą gałąź w spokoju, ale zamiast tego wykona pobranie dostarczonej gałęzi lub commita.
Inne formy reset
i commit
obejmują ścieżki zasilania.
Jeśli dostarczysz ścieżki do reset
nie możesz dostarczyć --hard
i reset
zmieni tylko wersję indeksu dostarczonych ścieżek do wersji w dostarczony commit (lub HEAD
, Jeśli nie podasz commita).
Jeśli podasz ścieżki do checkout
, podobnie jak reset
zaktualizuje ona indeksową wersję dostarczonych ścieżek, aby pasowała do dostarczonego commita (lub HEAD
), ale zawsze wyświetli indeksową wersję dostarczonych ścieżek w drzewie roboczym.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-17 13:09:38
Jeden prosty przypadek użycia podczas cofania zmiany:
1. Użyj reset, jeśli chcesz cofnąć inscenizację zmodyfikowanego pliku.
2. Użyj kasy, jeśli chcesz odrzucić zmiany do nieuszkodzonych plików.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 02:54:56
Kluczową różnicą w skrócie jest to, że reset
przesuwa bieżącą gałąź odniesienia , podczas gdy checkout
nie (przesuwa głowę).
Jak wyjaśnia książka Pro Git pod Reset Demystified ,
Pierwszą rzeczą
reset
zrobi to przesuń to, co głowa wskazuje na. To nie jest to samo co zmiana samej głowicy (czyli to co robicheckout
);reset
przesuwa gałąź , na którą wskazuje Głowa. Oznacza to, że jeśli głowica jest ustawiona namaster
branch (tzn. aktualnie znajdujesz się namaster
branch), bieganiegit reset 9e5e6a4
rozpocznie się od Wskazywaniamaster
na9e5e6a4
. [podkreślenie dodane]
Zobacz również odpowiedź VonC dla bardzo pomocny tekst i fragment diagramu z tego samego artykułu, którego nie będę powielać tutaj.
Oczywiście jest o wiele więcej szczegółów na temat tego, jakie efekty checkout
i reset
mogą mieć na indeksie i drzewie roboczym, w zależności od użytych parametrów. Może być wiele podobieństw i różnice między dwoma poleceniami. Ale jak widzę, najważniejszą różnicą jest to, czy poruszają czubkiem bieżącej gałęzi.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-22 19:27:04
Krótka mnemotechnika:
git reset HEAD : index = HEAD
git checkout : file_tree = index
git reset --hard HEAD : file_tree = index = HEAD
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-17 06:31:44
Dwa polecenia (reset i checkout) są zupełnie inne.
checkout X
NIE reset --hard X
Jeśli X jest nazwą gałęzi,
checkout X
zmieni bieżącą gałąź
while reset --hard X
will not.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-26 12:17:52