Dlaczego moje repozytorium Git weszło w stan odłączonego HEAD?

386

Skończyło się dzisiaj z odłączoną głową, ten sam problem, jak opisano w: git push mówi wszystko na bieżąco, mimo że mam lokalne zmiany

O ile wiem, nie zrobiłem nic niezwykłego, po prostu zatwierdzam i wypycham z mojego lokalnego repozytorium.

Więc jak skończyłem z detached HEAD?

Adam Bergmark
źródło
18
Sprawdzanie zdalnej gałęzi wydaje się być najczęstszym sposobem, aby przypadkowo to zrobić; innym powszechnym sposobem jest sprawdzenie branch-name@{n}n-tej poprzedniej pozycji branch-name. Ale nie ważne co, w pewnym momencie musiał być git checkout <rev>. Jeśli to nie zadzwoni, prawdopodobnie zrobiłeś to, o czym wspomniał Will - próbowałeś to zrobić git checkout <file>i przez przypadek udało ci się określić poprawkę.
Cascabel
3
Aby cofnąć odłączony stan HEAD, zobacz Naprawianie odłączonej głowy Git? .
Moje repozytorium zakończyło się w tym stanie, gdy napotkano konflikty podczas bazowania. Na szczęście Git powiedział mi, co mam robić, gdy pobiegłem git status:all conflicts fixed: run "git rebase --continue"
Paul,
2
Dzieje się tak również, jeśli przypadkowo wpiszesz git checkout remotes/origin/my-branchzamiast git checkout my-branchlub git checkout origin/my-branch.
Adam Libuša
@adam Libusa, Dzięki, że to dla mnie zadziałało. Jaka jest różnica między zdalnymi / git / my-branch git Checkout a my-branch git checkout. Czy to nie to samo. ale to, co powiedziałeś, działało dla mnie. Z ciekawości proszę.
karunakar bhogyari

Odpowiedzi:

280

Każde pobranie zatwierdzenia, które nie jest nazwą jednego z twoich oddziałów, da ci odłączony HEAD. SHA1, który reprezentuje wierzchołek gałęzi, wciąż daje odłączoną GŁOWĘ. Tylko kasa lokalnego oddziału nazwy unika tego trybu.

Zobacz zatwierdzanie z odłączonym HEAD

Gdy HEAD jest odłączony, zatwierdzenia działają normalnie, tyle że żadna nazwana gałąź nie jest aktualizowana. (Możesz myśleć o tym jak o anonimowej gałęzi).

alternatywny tekst

Na przykład, jeśli kasujesz „zdalną gałąź” bez uprzedniego jej śledzenia, możesz skończyć z odłączonym HEAD.

Zobacz git: przełącz gałąź bez odłączania głowy


Dzięki Git 2.23 (sierpień 2019 r.) Nie musisz już używać mylącego git checkoutpolecenia .

git switch może również sprawdzić oddział i uzyskać odłączenie HEAD, z wyjątkiem:

  • ma wyraźną --detachopcję

Aby sprawdzić zatwierdzenie HEAD~3do tymczasowej inspekcji lub eksperymentu bez tworzenia nowego oddziału:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • nie można go odłączyć przez pomyłkę oddziału zdalnego śledzenia

Widzieć:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

Vs. za pomocą nowego git switchpolecenia:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

Jeśli chcesz utworzyć nowy oddział lokalny śledzący oddział zdalny:

git switch <branch> 

Jeśli <branch>nie zostanie znalezione, ale istnieje dokładnie gałąź śledzenia w jednym pilocie (nazwij ją <remote>) o pasującej nazwie, traktuj ją jako odpowiednik

git switch -c <branch> --track <remote>/<branch>

Nigdy więcej błędu!
Nigdy więcej niechcianych odłączonych HEAD!

VonC
źródło
12
Innym sposobem na wejście w stan odłączonej głowy jest to, że znajdujesz się w środku interaktywnej bazy i chcesz edytować jeden z zatwierdzeń. Gdy Git rzuci cię na zatwierdzenie do edycji, będziesz w stanie odłączonej głowy, dopóki nie skończysz bazy.
W tym wizualnym przewodniku znajduje się wyjaśnienie: git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.Co to znaczy „pliki są kopiowane na scenę”? Myślałem, że pliki zostały zatwierdzone, co oznacza, że ​​scena została wyczyszczona?
maks.
16
W rzeczywistości otrzymasz odłączony HEAD za każdym razem, gdy kasujesz jakiekolwiek zatwierdzenie przez jego SHA1, niezależnie od tego , czy znajduje się on na końcu gałęzi; jedyną rzeczą, którą możesz kasować bez odłączania HEAD, jest nazwa oddziału. Na przykład, pomimo tego, że masterjest ed489na powyższym schemacie, git checkout ed489da ci odłączoną GŁOWĘ, podczas gdy git checkout masternie.
musiphil
8
"You can think of this as an anonymous branch":) Podoba mi się analogia
Adrien Be
117

Właśnie to odtworzyłem przypadkiem:

  1. wyświetla zdalne gałęzie

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Chcę sprawdzić jeden lokalnie, więc wycinam wklej:

    git checkout origin/Feature/f1234
    
  3. Presto! Odłączony stan HEAD

    You are in 'detached HEAD' state. [...])
    

Rozwiązanie nr 1:

Nie umieszczaj origin/z przodu mojej specyfikacji oddziału podczas sprawdzania:

git checkout Feature/f1234

Rozwiązanie nr 2:

Dodaj -bparametr, który tworzy gałąź lokalną ze zdalnego

git checkout -b origin/Feature/f1234 lub

git checkout -b Feature/f1234 automatycznie wróci do źródła

piekarnik
źródło
14
To prawie świetna odpowiedź, ale nie wyjaśnia, dlaczego wpadłeś w stan oderwanej głowy.
Goose
5
Zgadzam się, ale zapewnia rozwiązanie, którego szukałem. Dzięki!!
Kilmazing
Widziałem w tej innej odpowiedzi, że git checkout -b Feature/f1234<=> git branch Feature/f1234i git checkout Feature/f1234.
Armfoot
1
domyślnie wygląda na pochodzenie, więc kiedy podajesz origin/branchname, szuka, origin/origin/branchnameaby powiedzieć, że pierwsza jest nazwą zdalną, której używasz -b, jeśli nie tworzy anonymousgałęzi, która jest odłączona. Podobnie do wyewidencjonowywania z innego pilota musisz wspomnieć o -bparametrze, w przeciwnym razie git nie będzie wiedział, że pochodzi z nowego pilota, będzie szukał origin/remote/branchname.
garg10may
Jesteś święta!
Harvey Lin
12

próbować

git reflog 

daje to historię tego, jak twoje HEAD i wskaźniki gałęzi były przenoszone w przeszłości.

np .:

88ea06b HEAD @ {0}: kasa: przejście z DEVELOPMENT do pilotów / origin / SomeNiceFeature e47bf80 HEAD @ {1}: ściągnij origin DEVELOPMENT: Przewijanie do przodu

góra tej listy jest jednym z powodów, dla których można napotkać stan ODŁĄCZONEJ GŁOWICY ... sprawdzanie zdalnej gałęzi śledzenia.

André R.
źródło
7

Może się to łatwo zdarzyć, jeśli spróbujesz cofnąć zmiany dokonane przez ponowne sprawdzenie plików i niezupełne dostosowanie składni.

Możesz spojrzeć na wynik git log- możesz wkleić tutaj ogon dziennika od ostatniego udanego zatwierdzenia, a my wszyscy możemy zobaczyć, co zrobiłeś. Lub możesz wkleić-bin i ładnie poprosić #gitna IRC freenode.

Będzie
źródło
5

Może się to zdarzyć, jeśli masz tag o nazwie takiej samej jak gałąź.

Przykład: jeśli „release / 0.1” to nazwa znacznika, to

git checkout release/0.1

tworzy odłączoną HEAD przy „release / 0.1”. Jeśli spodziewasz się, że wersja / 0.1 jest nazwą oddziału, to jesteś zdezorientowany.

radzimir
źródło
1
Tak. Ale jak to naprawić? Jak kupujesz w oddziale?
Martin
5

Detached HEAD oznacza, że ​​to, co obecnie jest wyewidencjonowane, nie jest oddziałem lokalnym.

Niektóre scenariusze, które spowodują Detached HEADstan:

  • Powiedzmy, jeśli kasujesz zdalny oddziałorigin/master . To gałąź tylko do odczytu. Tak więc, podczas tworzenia zatwierdzenia z origin/masterniego będzie on swobodny , tzn. Nie będzie podłączony do żadnej gałęzi.

  • Jeśli kasujesz określony tag lub zatwierdzasz . Podczas wykonywania nowego zatwierdzenia stąd, ponownie będzie on swobodny , tj. Nie będzie podłączony do żadnej gałęzi. Zauważ, że kiedy gałąź jest wyewidencjonowana, nowe zatwierdzenia zawsze są automatycznie umieszczane na końcu.

    Jeśli chcesz wrócić i sprawdzić konkretny zatwierdzenie lub znacznik, aby rozpocząć pracę od tego miejsca, możesz utworzyć nową gałąź pochodzącą z tego zatwierdzenia i przejść do niego git checkout -b new_branch_name. Zapobiegnie to Detached HEADstanowi, ponieważ masz teraz wyewidencjonowany oddział, a nie zatwierdzenie.

Tim Skov Jacobsen
źródło
3

Prostym przypadkowym sposobem jest zrobienie git checkout headliterówki HEAD.

Spróbuj tego:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

co daje

Note: checking out 'head'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme
Thomas Weller
źródło
Wspomniany również w longair.net/blog/2012/05/07/the-most-confusing-git-terminology (poszukaj „„ HEAD ”i„ head ””)
VonC
@VonC: dzięki za ten link. Przygotowuję szkolenie na Git i chcę również wskazać, dlaczego czasami jest to tak mylące. Mam już wiele przykładów (np. checkout -bKtóre wyglądają jak kasy, ale w rzeczywistości oddziały), ale kolejna lista jest po prostu mile widziana.
Thomas Weller,
2

Innym sposobem na wejście w stan odłączonej głowy git jest próba zatwierdzenia do zdalnej gałęzi. Coś jak:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

Pamiętaj, że jeśli to zrobisz, każda kolejna próba sprawdzenia pochodzenia / foo spowoduje powrót do stanu odłączonej głowy!

Rozwiązaniem jest utworzenie własnego lokalnego oddziału foo, który śledzi pochodzenie / foo, a następnie opcjonalnie push.

Prawdopodobnie nie ma to nic wspólnego z twoim pierwotnym problemem, ale ta strona jest wysoko w hitach Google dla „git odłączona głowa”, a ten scenariusz jest poważnie niedokumentowany.

dspeyer
źródło
Ta sytuacja wydaje się być tym, o czym mówi powyższa odpowiedź Owena - gdzie wycinanie i wklejanie „origin / foo” sprawia, że ​​git uważa to za „origin / origin / foo”.
mvanle
1

Kiedy kasujesz do zatwierdzenia git checkout <commit-hash>lub do zdalnej gałęzi, HEAD zostanie odłączony i spróbuje utworzyć na nim nowe zatwierdzenie.

Zatwierdzenia, które nie są osiągalne przez żaden oddział lub tag, zostaną wyrzucone do pamięci i usunięte z repozytorium po 30 dniach.

Innym sposobem rozwiązania tego jest utworzenie nowej gałęzi dla nowo utworzonego zatwierdzenia i pobranie go. git checkout -b <branch-name> <commit-hash>

W tym artykule pokazano, jak uzyskać stan odłączonego HEAD .

Nesha Zoric
źródło