Warum ist mein Git-Repository in einen getrennten HEAD-Zustand übergegangen?

Lesezeit: 12 Minuten

Warum ist mein Git Repository in einen getrennten HEAD Zustand ubergegangen
Adam Bergmark

Ich bin heute mit einem abgetrennten Kopf gelandet, das gleiche Problem wie in beschrieben: git push sagt alles aktuell, obwohl ich lokale Änderungen habe

Soweit ich weiß, habe ich nichts Außergewöhnliches getan, nur Commits und Pushes von meinem lokalen Repo.

Wie kam ich also zu a detached HEAD?

  • Das Auschecken eines entfernten Zweigs scheint die häufigste Methode zu sein, dies versehentlich zu tun. Ein weiterer gängiger Weg ist das Auschecken [email protected]{n}die n-te vorherige Position von branch-name. Aber egal was, irgendwann muss es doch einen gegeben haben git checkout <rev>. Wenn das nicht klingelt, dann hast du wahrscheinlich das getan, was Will erwähnt hat – versucht zu tun git checkout <file> und es geschafft, versehentlich eine Revision anzugeben.

    – Kaskabel

    19. Oktober 2010 um 13:25 Uhr

  • Informationen zum Rückgängigmachen eines abgetrennten HEAD-Zustands finden Sie unter Reparieren eines abgetrennten Git-Heads?.

    Benutzer456814

    30. Mai 2014 um 5:15 Uhr

  • Mein Repo landete in diesem Zustand, als beim Rebasing Konflikte auftraten. Glücklicherweise hat mir Git gesagt, was ich tun soll, wenn ich gerannt bin git status: all conflicts fixed: run "git rebase --continue"

    – Paulus

    11. Mai 2015 um 13:22 Uhr


  • Passiert auch, wenn Sie versehentlich tippen git checkout remotes/origin/my-branch anstatt git checkout my-branch oder git checkout origin/my-branch.

    – Adam Libuša

    20. November 2019 um 12:54 Uhr


  • @adam Libusa, Danke, es hat bei mir funktioniert. Was ist der Unterschied zwischen git checkout remotes/origin/my-branch und git checkout my-branch. Ist es nicht dasselbe. aber was du gesagt hast, hat bei mir funktioniert. Aus Neugier frage ich.

    – Karunakar-Bhogyari

    17. März 2020 um 7:32 Uhr

Warum ist mein Git Repository in einen getrennten HEAD Zustand ubergegangen
VonC

Jedes Auschecken eines Commit, das nicht der Name eines von ist dein Verzweigungen bringen dir einen abgetrennten KOPF. Ein SHA1, der die Spitze eines Astes darstellt, ergibt immer noch einen abgetrennten HEAD. Nur eine Kasse einer Filiale vor Ort Name vermeidet diesen Modus.

Sehen Begehen mit einem losgelösten KOPF

Wenn HEAD getrennt ist, funktionieren Commits wie gewohnt, außer dass kein benannter Zweig aktualisiert wird. (Sie können sich dies als einen anonymen Zweig vorstellen.)

Alt-Text

Wenn Sie beispielsweise einen „entfernten Zweig“ auschecken, ohne ihn vorher zu verfolgen, können Sie am Ende mit einem abgetrennten HEAD enden.

Siehe git: Zweig wechseln, ohne den Kopf abzutrennen

Bedeutung: git checkout origin/main (oder origin/master in den alten Tagen) würde zu Folgendem führen:

Note: switching to 'origin/main'.

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.

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

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at a1b2c3d My commit message

Deshalb sollten Sie nicht verwenden git checkout nicht mehr, sondern das Neue git switch Befehl.

Mit git switchwürde derselbe Versuch, einen entfernten Zweig zu „checken“ (wechseln zu), sofort fehlschlagen:

git switch origin/main
fatal: a branch is expected, got remote branch 'origin/main'

Um mehr hinzuzufügen git switch:

Mit Git 2.23 (August 2019) müssen Sie das Verwirrende nicht verwenden git checkout Befehl mehr.

git switch kann auch einen Zweig auschecken und einen abgetrennten HEAD erhalten, außer:

  • es hat eine explizite --detach Möglichkeit

Commit auschecken HEAD~3 für temporäre Inspektion oder Experiment, ohne einen neuen Zweig zu erstellen:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • es kann nicht versehentlich ein Remote-Tracking-Zweig abgetrennt werden

Sehen:

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. mit dem neuen git switch Befehl:

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

Wenn Sie einen neuen lokalen Zweig erstellen möchten, der einen Remote-Zweig verfolgt:

git switch <branch> 

Wenn <branch> wird nicht gefunden, aber es gibt einen Tracking-Zweig in genau einem Remote (nennen Sie es <remote>) mit einem übereinstimmenden Namen als gleichwertig behandeln

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

Kein Fehler mehr!
Kein ungewollter abgelöster KOPF mehr!

  • Eine andere Möglichkeit, den Status „Detached Head“ einzugeben, besteht darin, dass Sie sich mitten in einer interaktiven Rebase befinden und einen der Commits bearbeiten möchten. Wenn Git Sie zum Bearbeiten am Commit absetzt, befinden Sie sich in einem abgetrennten Kopfzustand, bis Sie die Rebase abgeschlossen haben.

    Benutzer456814

    9. Juli 2013 um 3:48 Uhr

  • Tatsächlich erhalten Sie einen abgetrennten HEAD, wenn Sie einen Commit anhand seines SHA1 auschecken. ob oder nicht es ist an der Spitze eines Astes; Das einzige, was Sie auschecken können, ohne einen abgetrennten HEAD zu erhalten, ist ein Zweigname. Obwohl zum Beispiel master ist bei ed489 auf dem Diagramm oben, git checkout ed489 wird Ihnen einen abgetrennten KOPF geben, während git checkout master wird nicht.

    – musiphil

    13. Februar 2014 um 8:26 Uhr


  • "You can think of this as an anonymous branch" 🙂 Ich mag die Analogie

    – Adrien Be

    5. März 2016 um 8:36 Uhr

  • @Schatz Sicher. Ich habe die Antwort bearbeitet, um ein Beispiel hinzuzufügen, in dem ich einen entfernten Zweig auschecke … und am Ende einen abgetrennten HEAD habe.

    – VonC

    9. Februar 2021 um 13:42 Uhr


Warum ist mein Git Repository in einen getrennten HEAD Zustand ubergegangen
Owen

Ich habe das jetzt zufällig reproduziert:

  1. listet die entfernten Branches auf

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Ich möchte einen lokal auschecken, also schneide ich ihn aus:

    git checkout origin/Feature/f1234
    
  3. Presto! Abgetrennter HEAD-Zustand

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

Lösung Nr. 1:

Nicht einschließen origin/ vorne in meiner Zweigspezifikation beim Auschecken:

git checkout Feature/f1234

Lösung Nr. 2:

Addieren -b Parameter, der eine lokale Verzweigung von der Remote erstellt

git checkout -b origin/Feature/f1234 oder

git checkout -b Feature/f1234 Es wird automatisch auf den Ursprung zurückgegriffen

  • Dies ist fast eine großartige Antwort, erklärt aber nicht, warum Sie in einen distanzierten Kopfzustand geraten sind.

    – Gans

    12. Mai 2016 um 18:25 Uhr

  • Ich stimme zu, aber es bietet die Lösung, nach der ich gesucht habe. Danke!!

    – Kilmazing

    15. März 2017 um 15:07 Uhr

  • Ich habe in dieser anderen Antwort das gesehen git checkout -b Feature/f1234 <=> git branch Feature/f1234 und git checkout Feature/f1234.

    – Armfuß

    13. Juli 2017 um 18:25 Uhr

  • standardmäßig sieht es in origin aus, also wenn du gibst origin/branchnamees sucht origin/origin/branchname um zu sagen, dass der erste der entfernte Name ist, den Sie verwenden -bwenn du es nicht tust, erstellt es a anonymous Filiale, die abgetrennt ist. Ebenso müssten Sie beim Auschecken von einer anderen Fernbedienung erwähnen -b Parameter andernfalls hat Git keine Möglichkeit zu wissen, dass es von einer neuen Fernbedienung stammt, es wird danach suchen origin/remote/branchname.

    – garg10mai

    14. August 2017 um 7:02 Uhr


  • Der Hinweis auf das Weglassen von “origin/” wirkte wie ein Zauber. Danke!

    – SMBiggs

    28. Oktober 2020 um 19:57 Uhr

Versuchen

git reflog 

Dadurch erhalten Sie eine Historie darüber, wie Ihre HEAD- und Verzweigungszeiger in der Vergangenheit bewegt wurden.

z.B :

88ea06b [email protected]{0}: Checkout: Verschieben von DEVELOPMENT zu remotes/origin/SomeNiceFeature e47bf80 [email protected]{1}: Ursprung ziehen DEVELOPMENT: Schneller Vorlauf

Der Anfang dieser Liste ist ein Grund, warum man auf einen DETACHED HEAD-Zustand stoßen könnte … beim Auschecken eines Remote-Tracking-Zweigs.

Detached HEAD bedeutet, dass das, was derzeit ausgecheckt ist, keine lokale Filiale ist.

Einige Szenarien, die zu a führen Detached HEAD Zustand:

  • Wenn Sie einen Remote-Zweig auscheckensagen origin/master. Dies ist ein schreibgeschützter Zweig. Also beim Erstellen eines Commit von origin/master es wird sein freischwebenddh mit keiner Verzweigung verbunden.

  • Wenn Sie ein bestimmtes Tag oder Commit auschecken. Wenn Sie von hier aus einen neuen Commit durchführen, wird dies erneut der Fall sein freischwebend, dh mit keiner Verzweigung verbunden. Beachten Sie, dass wenn a sich verzeigen ausgecheckt ist, werden neue Commits immer automatisch an die Spitze gesetzt.

    Wenn Sie zurückgehen und ein bestimmtes Commit oder Tag auschecken möchten, um von dort aus zu arbeiten, können Sie einen neuen Branch erstellen, der von diesem Commit ausgeht, und zu diesem wechseln git checkout -b new_branch_name. Dadurch wird verhindert, dass Detached HEAD Geben Sie an, dass Sie jetzt einen ausgecheckten Zweig und keinen Commit haben.

Dies kann passieren, wenn Sie ein Tag mit dem gleichen Namen wie eine Verzweigung haben.

Beispiel: Wenn „Release/0.1“ der Tag-Name ist, dann

git checkout release/0.1

erzeugt abgetrennten HEAD bei “release/0.1”. Wenn Sie erwarten, dass release/0.1 ein Zweigname ist, werden Sie verwirrt.

  • Jawohl. Aber wie kann man das beheben? Wie gehen Sie in der Filiale zur Kasse?

    – Martin

    1. Juli 2019 um 13:45 Uhr

  • Ich habe das mit diesem stackoverflow.com/a/5719854/573034 behoben. Der letzte Befehl (git pull --prune --tags) hat nicht funktioniert, also habe ich es getan git tag -l | xargs git tag -d um lokale Tags zu entfernen und git fetch --tags um entfernte Tags erneut abzurufen

    – Paulo

    9. Juli 2020 um 7:39 Uhr


  • Genau das war mein Problem. Die Git-Warnmeldung gibt keine Hinweise darauf, dass dies möglich ist.

    – JoeAC

    14. August 2020 um 3:47 Uhr

Wenn git umbenennen sollte detached HEAD Ich würde es so nennen ein KOPF, der nicht durch eine Verzweigung identifiziert wird und bald vergessen sein wird.

Wir Menschen können uns Filialnamen leicht merken. Wir tun es git checkout new-button-feature / git checkout main. main und new-button-feature sind leicht zu merken. Und wir können einfach tun git branch und erhalten Sie eine Liste aller Filialen. Aber um dasselbe mit nur Commits zu tun, müssten Sie das tun git reflog was sehr mühsam ist. Weil Sie Tausende von Commits haben, aber nur sehr wenige Branches.

Die Kennung eines getrennten Commits ist nur sein SHA. Angenommen, Sie haben einen Commit (keinen Zweig) ausgecheckt, dh Sie haben es getan git checkout d747dd10e450871928a56c9cb7c6577cf61fdf31 Du wirst kriegen:

Hinweis: Überprüfen Sie ‘d747dd10e450871928a56c9cb7c6577cf61fdf31’.

Sie befinden sich im Status „freistehender HEAD“.

Wenn Sie dann einige Änderungen vorgenommen und ein Commit durchgeführt haben, befinden Sie sich immer noch NICHT in einem Zweig.

Glaubst du, du würdest dich an den Commit-SHA erinnern? Das wirst du nicht!

Git will nicht, dass das passiert. Daher informiert es Sie HEAD ist keinem Zweig zugeordnet Sie neigen also eher dazu, eine neue Filiale auszuchecken. Als Ergebnis unter dieser Nachricht heißt es auch:

Wenn Sie einen neuen Zweig erstellen möchten, um von Ihnen erstellte Commits beizubehalten, können Sie dies (jetzt oder später) tun, indem Sie erneut -b mit dem Befehl checkout verwenden. Beispiel:

git Kasse -b


Um ein bisschen tiefer zu gehen, ist ein Zweig so gebaut, dass er intelligent ist. Es aktualisiert seinen HEAD, wenn Sie Commits vornehmen. Tags hingegen sollen nicht so sein. Wenn Sie ein Tag auschecken, befinden Sie sich wieder auf einem abgetrennten HEAD. Der Hauptgrund ist, dass, wenn Sie einen neuen Commit von diesem Tag machen, dieser Commit von nichts referenziert wird (nicht von einem Zweig oder Tag), es immer noch als getrennter HEAD betrachtet wird.

Angehängte HEADs können nur passieren, wenn Sie sich auf einem Zweig befinden.

Weitere Informationen finden Sie hier

HEAD ist ein Zeiger und zeigt – direkt oder indirekt – auf ein bestimmtes Commit:

Attached HEAD bedeutet, dass es an einen Zweig angehängt ist (dh es zeigt auf einen Zweig).

Detached HEAD bedeutet, dass es mit keinem Zweig verbunden ist, dh es zeigt direkt auf einen Commit.

Aus einem anderen Blickwinkel zu betrachten, wenn Sie auf einem Ast sind und tun cat .git/HEAD du würdest bekommen:

ref: refs/heads/Your-current-branch-name

Dann, wenn Sie es tun cat refs/heads/Your-current-branch-name dann sehen Sie auch den SHA des Commits, auf den Ihr Zweig zeigt/auf den er verweist.

Wenn Sie sich jedoch auf einem freistehenden KOPF befanden, und cat .git/HEAD Sie würden nur den SHA des Commit erhalten und nichts weiter:

639ce5dd952a645b7c3fcbe89e88e3dd081a9912

Mit nichts weiter meine ich, dass der Kopf auf keinen Ast zeigt. Es zeigt nur direkt auf ein Commit.


Als Ergebnis all dessen, jedes Mal, wenn Sie einen Commit auschecken (ohne den Branch-Namen zum Auschecken zu verwenden), selbst wenn dieser Commit der letzte Commit von Ihnen war hauptsächlich Zweig, du bist still in einem getrennten HEAD, da Ihr HEAD auf keinen Ihrer lokalen Zweige zeigt. Daher wird Sie selbst das Auschecken eines Tags in einen abgetrennten KOPF versetzen. Hinzu kommt, dass selbst das Auschecken eines entfernten Zweigs, den Sie in Ihren Computer geladen haben, zu einem abgetrennten Kopf führen würde, dh git checkout origin main würde auch als freistehender Kopf enden …

Zusammenfassung

Alle folgenden Ursachen führen zu einem abgetrennten Kopf:

  • checken Sie jeden Commit aus
  • Beliebiges Etikett auschecken
  • Auschecken einer beliebigen Remote-Zweigstelle

Du bist nur auf einem befestigten Kopf, wenn du einen ausgecheckt hast lokal sich verzeigen


Besonderer Dank an Josh Caswell & Saagar Jha mir zu helfen, das herauszufinden.

  • Jawohl. Aber wie kann man das beheben? Wie gehen Sie in der Filiale zur Kasse?

    – Martin

    1. Juli 2019 um 13:45 Uhr

  • Ich habe das mit diesem stackoverflow.com/a/5719854/573034 behoben. Der letzte Befehl (git pull --prune --tags) hat nicht funktioniert, also habe ich es getan git tag -l | xargs git tag -d um lokale Tags zu entfernen und git fetch --tags um entfernte Tags erneut abzurufen

    – Paulo

    9. Juli 2020 um 7:39 Uhr


  • Genau das war mein Problem. Die Git-Warnmeldung gibt keine Hinweise darauf, dass dies möglich ist.

    – JoeAC

    14. August 2020 um 3:47 Uhr

1646909293 785 Warum ist mein Git Repository in einen getrennten HEAD Zustand ubergegangen
Wille

Es kann leicht passieren, wenn Sie versuchen, vorgenommene Änderungen rückgängig zu machen, indem Sie Dateien erneut auschecken und die Syntax nicht ganz richtig hinbekommen.

Sie können sich die Ausgabe von ansehen git log – Sie könnten das Ende des Protokolls seit dem letzten erfolgreichen Commit hier einfügen, und wir könnten alle sehen, was Sie getan haben. Oder Sie könnten es in den Papierkorb einfügen und nett fragen #git im Freenode-IRC.

987610cookie-checkWarum ist mein Git-Repository in einen getrennten HEAD-Zustand übergegangen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy