Sprawdzenie tagu Git prowadzi do „odłączonego stanu HEAD”

166

Tworzę skrypt wdrożeniowy dla mojego projektu git i właśnie zacząłem używać tagów. Dodałem nowy tag o nazwie v2.0:

git tag -a v2.0 -m "Launching version 2.0"

I przekazałem ten tag do zdalnego repozytorium

git push --tags

Kiedy próbuję wykonać skrypt wdrażania i sprawdzić v2.0tag, otrzymuję następujący komunikat:

Jesteś w stanie „odłączonej głowy”. Możesz się rozglądać, wprowadzać eksperymentalne zmiany i zatwierdzać je, a także odrzucić wszelkie zmiany wprowadzone w tym stanie bez wpływu na gałęzie, wykonując kolejne pobranie. Jeśli chcesz utworzyć nową gałąź, aby zachować utworzone przez siebie zatwierdzenia, możesz to zrobić (teraz lub później), używając ponownie -b z poleceniem checkout. Przykład: git checkout -b nazwa_nowy_branch HEAD jest teraz na

Czy to normalne? Repozytorium jest w zawieszeniu, ponieważ jeśli to zrobię:

git branch

Otrzymuję ten wynik:

* (no branch)
  master

Przepraszam, jeśli to oczywiste, ale nie mogłem tego rozgryźć.

Khriz
źródło
Kiedy mówisz „wykonaj skrypt wdrożeniowy i sprawdź wersję 2.0”, czy Twój kod wygląda jak „git checkout v2.0”? Próbuję odnowić mój skrypt wydania i kiedy uruchamiam „git checkout v2.0” z mojej maszyny produkcyjnej, otrzymuję „błąd: pathspec 'v2.0' nie pasuje do żadnego pliku (ów) znanych gitowi." Mimo że uruchomiłem polecenie „git push origin --tags” na moim komputerze lokalnym przed wykonaniem polecenia „git checkout v2.0” na produkcji. Próbowałem też uruchomić polecenia „git pull --tags” i „git fetch --tags” na produkcji przed wywołaniem „git checkout v2.0” i to też nie działa ... Wciąż otrzymuję błąd. Jakieś pomysły?
John Erck
3
Miałem zamiar usunąć powyższy komentarz, ale pomyślałem, że utrzymanie go może pomóc komuś innemu. Otrzymałem błąd, ponieważ miałem TYPO w nazwie tagu, kiedy uruchomiłem „git checkout v2.0”. Jednak błąd związany z literówką jest dokładnie tym samym błędem, który otrzymasz, jeśli uruchomisz „git checkout v2.0” BEZ literówki PRZED uruchomieniem, „git fetch --tags”. Ostatecznie mój problem został rozwiązany przez uruchomienie polecenia „git fetch --tags” PRZED uruchomieniem, „git checkout v2.0” bez żadnych błędów. Uff!
John Erck
Świetnie, tak, musisz wcześniej pobrać --tagi (lub pobrać git, który ściągnie wszystko ze zdalnego), aby git mógł pobrać tag. Przepraszam, że właśnie zobaczyłem dzisiaj twój komentarz.
Khriz

Odpowiedzi:

429

OK, najpierw kilka terminów nieco uproszczonych.

W git, A tag(podobnie jak wiele innych rzeczy) jest to, co nazywa się treeish . To sposób na nawiązanie do jakiegoś punktu w historii projektu. Drzewo może być znacznikiem, zatwierdzeniem, specyfikatorem daty, specyfikatorem porządkowym lub wieloma innymi rzeczami.

Teraz a branch jest jak tag, ale jest ruchomy. Kiedy jesteś „na” gałęzi i robisz zatwierdzenie, gałąź jest przenoszona do nowego zatwierdzenia, którego dokonałeś, wskazując jego aktualną pozycję.

Twój HEADjest wskaźnikiem do gałęzi, która jest uważana za „bieżącą”. Zwykle, gdy klonujesz repozytorium, HEADwskaże, masterktóre z kolei wskaże zatwierdzenie. Kiedy następnie robisz coś takiego git checkout experimental, przełączasz się, HEADaby wskazywał experimentalgałąź, która może wskazywać na inny zatwierdzenie.

Teraz wyjaśnienie.

Kiedy robisz a git checkout v2.0, przełączasz się na zatwierdzenie, które nie jest wskazane przez branch. PlikHEADJest teraz „dom”, a nie wskazując na oddział. Jeśli zdecydujesz się teraz zatwierdzić (tak jak możesz), nie ma wskaźnika gałęzi do aktualizacji, aby śledzić to zatwierdzenie. Przełączenie z powrotem do innego zatwierdzenia spowoduje utratę tego nowego zatwierdzenia, które zrobiłeś. To właśnie mówi wiadomość.

Zwykle możesz powiedzieć git checkout -b v2.0-fixes v2.0. Spowoduje to utworzenie nowego wskaźnika do gałęzi na zatwierdzeniu wskazywanym przez drzewo v2.0(w tym przypadku znacznik), a następnie przesunie HEADgo do tego miejsca. Teraz, jeśli dokonasz zatwierdzeń, będzie można je śledzić (za pomocą v2.0-fixesgałęzi) i możesz pracować tak, jak zwykle. Nie ma nic "złego" w tym, co zrobiłeś, zwłaszcza jeśli chcesz tylko rzucić okiem na v2.0kod. Jeśli jednak chcesz wprowadzić tam zmiany, które chcesz śledzić, będziesz potrzebować gałęzi.

Powinieneś poświęcić trochę czasu na zrozumienie całego modelu gita DAG. Jest to zaskakująco proste i sprawia, że ​​wszystkie polecenia są dość jasne.

Noufal Ibrahim
źródło
Ok, dzięki, nie muszę wprowadzać żadnych zmian w kodzie, więc myślę, że wszystko jest w porządku. Nie muszę tworzyć oddziału. Wielkie dzięki!
Khriz,
1
Zgubiłem się, gdy po raz pierwszy spojrzałem na tę odpowiedź, ale po przeczytaniu dokumentacji gałęzi Git: http://git-scm.com/book/en/Git-Branching-What-a-Branch- Czy to było dużo jaśniejsze .
znak stiles
3
Świetna odpowiedź, ale mogę dodać w odniesieniu do: „Przełączenie z powrotem do innego zatwierdzenia spowoduje utratę tego nowego zatwierdzenia, które zrobiłeś.” - nadal możesz znaleźć zatwierdzenie w git reflog, co jest świetnym poleceniem, o którym warto wiedzieć! Dopóki nie doszło do czyszczenia pamięci, pozornie „niemożliwe” jest utrata zatwierdzenia.
Dmitry Minkovsky
Zatwierdzenia bez odwołań mogą zostać utracone przez operację czyszczenia pamięci.
Noufal Ibrahim
1
Adres URL jest nieprawidłowy, ponieważ zmienili układ strony.
jcubic
12

Tak, to normalne. Dzieje się tak, ponieważ pobierasz pojedynczy zatwierdzenie, które nie ma głowy. Zwłaszcza że (wcześniej czy później) nie jest szefem żadnej gałęzi.

Ale zwykle nie ma problemu z tym stanem. Możesz stworzyć nową gałąź z tagu, jeśli dzięki temu poczujesz się bezpieczniej :)

KingCrunch
źródło
1
Ok, będę trzymać to w ten sposób ... bezpieczeństwo jest przereklamowany i tak;)
Khriz
Jak skomentowałeś w odpowiedzi Noufals (muszę przyznać, że jest lepsza;)): Dopóki niczego nie zmieniasz, nie ma się czym martwić. Jeśli jednak zakładasz , że możesz coś zmienić, możesz po prostu utworzyć gałąź, ponieważ są one tanie w gicie i możesz je usunąć (i odtworzyć później i tak dalej).
KingCrunch,