Sprawdzanie starego commita i utrzymanie głowy na gałęzi głównej?

Obecnie do przełączania na inny commit git (w tej samej gałęzi...właściwie, na gałęzi głównej!), Wykonuję polecenie

git checkout ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a
Za każdym razem, gdy robię to git mówi mi, że jestem teraz z oderwaną głową. Jak przejść do starszego commita i utrzymać głowę na tej samej gałęzi?
Author: Jo Liss, 2011-04-14

6 answers

Większość czasu, kiedy to robię, wysyłam do działu temp:

git checkout -b temp-branch-name ea3d5ed039edd6d4a07cc41bd09eb58edd1f2b3a

Potem jak skończę po prostu usuwam gałąź

 183
Author: Nick Canzoneri,
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
2011-04-14 03:54:08

To zależy od tego, co chcesz zrobić podczas kasowania tego commita. Jeśli wszystko, co robisz, to sprawdzanie go, aby móc zbudować lub przetestować tę rewizję, to nie ma nic złego w pracy z odłączoną głową. Pamiętaj tylko, aby sprawdzić aktualną gałąź przed dokonaniem zmian (na przykładgit checkout master), aby nie tworzyć zmian, które nie są zawarte w żadnej gałęzi.

Jeśli jednak chcesz wprowadzić więcej commitów od tego momentu, powinieneś utworzyć gałąź. Jeśli make commity, do których nie odwołuje się gałąź, mogą łatwo się zgubić i w końcu zostaną wyczyszczone przez garbage collector Gita, ponieważ nic się do nich nie odnosi. Możesz utworzyć nową gałąź, uruchamiając:

git checkout -b newbranch ea3d5ed

Aby pomóc w wizualizacji, oto kilka diagramów pokazujących, jak praca na odłączonej głowie różni się od pracy na gałęzi.

Zacznijmy od 3 commitów na master, A, B i C. master jest bieżącą gałęzią, więc HEAD wskazuje na master, co wskazuje na commit C.

A  B  C
*--*--* <-- master <-- HEAD

Teraz jeśli zatwierdzimy commit, git utworzy commit, który ma c jako rodzica (ponieważ jest to bieżący commit, wskazywany z HEAD Poprzez master) i zaktualizuje master, aby wskazać na nowy commit. Wszystkie nasze commity są teraz w master, a HEAD wskazuje na nowy commit przez master.

A  B  C  D
*--*--*--* <-- master <-- HEAD

Teraz sprawdźmy B, dając nam odłączony HEAD.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- HEAD

Tutaj wszystko działa dobrze; możemy przejrzeć wszystkie pliki, zbudować nasz program, przetestować go itp. Możemy nawet utwórz nowe commity; ale jeśli to zrobimy, nie ma gałęzi, na której się znajdujemy, więc nie możemy wskazać żadnej gałęzi na nowy commit. Jedyne co na to wskazuje to HEAD:

A  B  C  D
*--*--*--* <-- master
    \
     * <-- HEAD
     E

Jeśli później zdecydujemy się sprawdzić master ponownie, nie będzie nic odnoszącego się do E.

A  B  C  D
*--*--*--* <-- master <-- HEAD
    \
     *
     E

Ponieważ nie ma nic na ten temat, może być trudno go znaleźć, a git uważa commity bez odniesień za porzucone (zdarzają się dość często, jeśli zmienisz base, zmiażdżysz łatki lub zrobisz inną zabawną historię manipulacja; zazwyczaj reprezentują porzucone łatki, na których już się nie troszczysz). Po pewnym czasie, git uzna to za śmieci, które zostaną wyrzucone przy następnym uruchomieniu garbage collection.

Tak więc, zamiast sprawdzać gołą rewizję i uzyskiwać odłączoną głowę, jeśli czujesz, że zamierzasz wprowadzić więcej commitów, powinieneś użyć git checkout -b branch B, aby utworzyć gałąź i sprawdzić ją. Teraz Twoje commity nie zostaną utracone, ponieważ zostaną dołączone do gałęzi, do której możesz łatwo się odwoływać do, a następnie połączyć.

A  B  C  D
*--*--*--* <-- master
   ^
    \-- branch <-- HEAD

Jeśli zapomnisz to zrobić i utworzysz commity z gałęzi, nie ma się czym martwić. Możesz utworzyć gałąź odnoszącą się do rewizji head za pomocą git checkout -b branch. Jeśli już przełączyłeś się z powrotem do gałęzi master i zdasz sobie sprawę, że zapomniałeś zbłąkanego commita, możesz go znaleźć za pomocą git reflog, który pokaże ci historię zmian HEAD, na które wskazał w ciągu ostatnich kilku dni. Wszystko, co jeszcze znajduje się w reflogu, nie będzie zbierane śmieci, i generalnie referencje są przechowywane w reflogu przez co najmniej 30 dni.

 78
Author: Brian Campbell,
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
2011-04-14 13:08:28

Jeśli po prostu chcesz wrócić do wcześniejszego commita, aby grać z nim bez wprowadzania żadnych zmian, możesz to zrobić

git co <previous-commit-id>

Będziesz na gałęzi o nazwie "(no branch) " po tej komendzie.

Potwierdź to przez

git br

Po pobraniu kodu, możesz przełączyć się na gałąź, którą używałeś

git co <the-branch-you-were-on>

"(NO branch) " zostanie automatycznie usunięty. W ten sposób nie musisz tworzyć tymczasowej gałęzi.

 7
Author: Zack Xu,
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
2013-12-11 16:49:37

Git ' s HEAD jest po prostu wskaźnikiem, który mówi, co jest w katalogu roboczym. Jeśli chcesz sprawdzić commit, który nie jest głową gałęzi, musisz po prostu przekierować głowę, aby wskazać na ten commit. Nie da się tego obejść. Możesz utworzyć tymczasową gałąź w tym commicie, ale HEAD będzie jednak odsyłany od master.

To krótkie wyjaśnienie. Werbalność poniżej pomoże w zrozumieniu, jak głowa i mistrz różnią się od siebie:

Normalnie, rzeczy wyglądają tak:

C ← refs/heads/master ← HEAD 
↓
B
↓
A

Co oznacza: "rodzicem C jest B, a rodzicem B jest A. branch master wskazuje na C, a ja obecnie sprawdziłem zawartość master. / Align = "left" / "

Pewne założenia są w tym Ukryte, które są niezbędne do dokładnego zrozumienia grafu commit. Mianowicie, commity odnoszą się tylko do ich rodziców, a zawartość gałęzi to te commity (i tylko te commity), które można uzyskać, klikając łącza nadrzędne. (Niezmodyfikowana) zawartość drzewa roboczego i indeksu musi odpowiadać zatwierdzeniu nazwanemu przez HEAD, pośrednio ("symboliczne") lub bezpośrednio ("odłączone").

Tak więc, jeśli chcesz sprawdzić Stary commit, głowa musi zostać zaktualizowana, aby wskazać żądany commit. git-checkout robi tak:

C ← refs/heads/master 
↓
B ← HEAD
↓
A
Zostawiłeś swoją gałąź za sobą, skoro patrzysz na coś starego. To jest w zupełności OK, jak mówią Rady "odłączonej głowy" ty spokojnie (akcent mój):

Możesz się rozejrzeć, wprowadzić eksperymentalne zmiany i zatwierdzić je, a wszelkie zmiany wprowadzone w tym stanie możesz odrzucić bez wpływu na gałęzie, wykonując kolejną kasę.

Z drugiej strony, podczas resetowania gałęzi również dostaje głowę tam, gdzie musi być, to miałoby zupełnie inny efekt!

C
↓
B ← refs/heads/master ← HEAD
↓
A

Commit C stanie się śmieciem, ponieważ zadeklarowałeś, że nie chcesz, aby był częścią / align = "left" /

W skrócie, wszystko co musisz zrobić, to zrozumieć co git oznacza przez "HEAD" - to gdzie ty jesteś, a nie gdzie jest jakaś gałąź. I jeśli gdzie ty jesteś nie jest tym samym, co gdzie jest gałąź, nie ma wyboru, jak tylko użyć odłączonej głowy.

(Być może zajrzyj również do GitHub, gitk lub gitweb, aby przejrzeć historię zmian, jeśli wykolejenie głowy nadal cię irytuje.)

 4
Author: Josh Lee,
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
2011-04-14 04:53:35

Pytanie jest nieco niejasne, ale jeśli chcesz po prostu zmienić pliki w swoim drzewie roboczym, możesz po prostu to zrobić:

git checkout [commit|branch] -- .

Możesz następnie ustawić zmiany i utworzyć nowy commit, jeśli chcesz. Czasami jest to bardzo przydatne.

 1
Author: Lari Hotari,
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
2015-03-10 18:19:33

Chyba rozumiem twoje pytania. Oto, co znalazłem, by to rozwiązać. i nie ma rozwiązania GUI, możesz użyć tylko polecenia, aby go rozwiązać, i to jest naprawdę proste.

Krok 1: Utwórz znacznik starego commita, do którego chcesz wrócić.

Jak tag v2. 0

Krok 2: git checkout v2. 0

Tutaj jest, teraz twoja głowa wskazuje na commit 'v2. 0', ale master nadal wskazuje na last commit.

C:\Program Files\Git\doc\git\html\git-checkout.html ten dokument może Ci pomóc

Lub wpisz git help

 0
Author: Lion Lai,
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
2013-10-03 04:06:47