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ędzy git reseti 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:

http://a.imageshack.us/img651/1559/86421927.pnghttp://a.imageshack.us/img801/1986/resetr.png

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.

Tutaj wpisz opis obrazka

git checkout bar 
git reset --hard newbar 
git branch -d newbar 

Tutaj wpisz opis obrazka

Author: prosseek, 2010-09-03

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 to git restore, niekoniecznie git 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 uruchamiamy git 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 commit A, 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łąź.

http://git-scm.com/images/reset/reset-checkout.png

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.
 206
Author: VonC,
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.

 67
Author: CB Bailey,
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.

 50
Author: John Doe,
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 robi checkout); reset przesuwa gałąź , na którą wskazuje Głowa. Oznacza to, że jeśli głowica jest ustawiona na master branch (tzn. aktualnie znajdujesz się na master branch), bieganie git reset 9e5e6a4 rozpocznie się od Wskazywania master na 9e5e6a4. [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.

 11
Author: LarsH,
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
 4
Author: Филя Усков,
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.

 3
Author: wiki1000,
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