W3docs

Detached HEAD

Verstehe den Git-Detached-HEAD-Zustand: Was er bedeutet, warum er auftritt, wie du Arbeit bewahrst und zur Branch zurückkehrst.

Definition

Ein Detached HEAD liegt vor, wenn HEAD direkt auf einen Commit zeigt statt auf einen Branch. Normalerweise verweist HEAD auf einen Branch-Namen (wie main), und dieser Branch zeigt auf den neuesten Commit – beim Committen wird der Branch automatisch vorwärtsbewegt. Im Detached-HEAD-Zustand ist diese Kette unterbrochen: HEAD steht auf einem bestimmten Commit, ohne dass ein Branch deine neuen Commits mitführt.

HEAD zeigt über einen Branch versus HEAD zeigt direkt auf einen Commit

Wie HEAD normalerweise funktioniert

HEAD ist eine Referenz, die Git mitteilt, „wo du dich gerade befindest." Im üblichen „angehängten" Zustand bilden die Referenzen eine Kette: HEAD → Branch → Commit. HEAD zeigt nicht direkt auf einen Commit – es zeigt auf einen Branch-Namen, und dieser Branch zeigt auf den neuesten Commit.

Wenn du einen neuen Commit erstellst, bewegt Git den Branch-Zeiger auf den neuen Commit vor, und da HEAD auf den Branch zeigt, folgt es automatisch. Deine History bleibt an einem benannten Branch verankert.

Diese Kette kannst du selbst einsehen. Die Datei .git/HEAD enthält eine symbolische Referenz:

cat .git/HEAD
# ref: refs/heads/main      <- attached: HEAD points at a branch

Was HEAD löst

HEAD wird immer dann gelöst, wenn du etwas auscheckst, das kein Branch ist – meistens ein bestimmter Commit, ein Tag oder eine Remote-Tracking-Referenz:

git checkout a1b2c3d      # a commit hash
git checkout v1.0.0       # a tag
git checkout origin/main  # a remote-tracking ref
git switch --detach main  # explicitly detach at main's tip

Git warnt dich, wenn dies geschieht. Die Meldung sieht so aus:

Note: switching to 'a1b2c3d'.

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.

Nach dem Lösen zeigt .git/HEAD nicht mehr auf einen Branch – es enthält direkt einen Commit-Hash:

cat .git/HEAD
# a1b2c3d4e5f6...          <- detached: HEAD points at a commit directly

Der Befehl git checkout hat eine Doppelfunktion (Branches wechseln und HEAD verschieben). Die neueren Kapitel zu git switch und git checkout erklären, warum Git diese Aufgaben getrennt hat.

Wann ein Detached HEAD nützlich ist

Ein Detached HEAD ist kein Fehler – es ist ein normales Werkzeug. Du verwendest ihn bewusst, wenn du History betrachten oder bauen möchtest, ohne einen Branch zu berühren:

  • Alte Version inspizieren – checke einen Commit oder Tag aus, um den Code so zu lesen, wie er zu diesem Zeitpunkt war.
  • Altes Release bauen oder testen – checke v1.0.0 aus, führe den Build durch und kehre dann zu deinem Branch zurück.
  • Bug bisektierengit bisect checkt Commits im Detached-HEAD-Zustand aus, während es nach dem Commit sucht, der einen Bug eingeführt hat.
  • Wegwerfexperiment ausprobieren – mache einige experimentelle Commits, entscheide, dass sie eine Sackgasse waren, und geh weg, ohne einen Branch zu hinterlassen.

Warum es wichtig ist

Im Detached HEAD umherzuschauen ist vollkommen sicher – das ist gerade der Sinn davon. Die Gefahr entsteht erst, wenn du dort commitest. Da kein Branch deine Arbeit verfolgt, sind diese neuen Commits nur über HEAD selbst erreichbar. In dem Moment, in dem du zu einem anderen Branch wechselst, bewegt sich HEAD weiter und nichts zeigt mehr auf die Commits, die du gemacht hast. Sie werden zu „hängenden" Commits: noch eine Weile im Repository vorhanden, aber ohne Referenz, die sie hält, und werden schließlich durch die Garbage Collection entfernt.

Die Lösung ist einfach – gib diesen Commits einen Namen, bevor du gehst.

Arbeit aus einem Detached HEAD sichern

Wenn du Commits in einem Detached HEAD gemacht hast und sie behalten möchtest, erstelle einen Branch bevor du den Zustand verlässt. Das verankert die Commits an einem Namen:

git switch -c my-rescued-work

Deine losgelösten Commits leben jetzt auf dem neuen Branch, sicher und erreichbar. Der entsprechende Befehl mit dem älteren Kommando lautet git checkout -b my-rescued-work.

Ein vollständiger Durchlauf

Hier ist der gesamte Ablauf – lösen, committen und die Arbeit sichern:

git checkout a1b2c3d          # detach HEAD onto an old commit
# ... edit files ...
git commit -am "Experiment"   # commit lives only on HEAD now
git switch -c experiment      # name it -> commit is now safe on a branch
git log --oneline experiment  # the new commit is reachable by name

Sobald der Branch existiert, kannst du ihn wie jeden anderen Branch mergen, rebasen oder löschen.

Zurück zur Normalität

Um einen Detached HEAD zu verlassen, ohne neue Commits zu behalten, wechsle einfach zu einem Branch:

git switch main

Wenn du im losgelösten Zustand committet hast, vergessen hast, einen Branch zu erstellen, und bereits gewechselt bist, kein Grund zur Panik – git reflog zeichnet jede Position auf, die HEAD besucht hat, einschließlich Commits, auf die kein Branch zeigt. Finde den Hash des verlorenen Commits dort und stelle ihn auf einem neuen Branch wieder her:

git reflog
# a1b2c3d HEAD@{1}: commit: Experiment   <- your lost commit
# 8120552 HEAD@{2}: checkout: moving from main to 8120552
git switch -c recovered a1b2c3d

Reflog-Einträge laufen ab (standardmäßig 90 Tage für erreichbare History, 30 für nicht erreichbare), also stelle lieber früher als später wieder her.

Verwandte Themen

  • git switch — die moderne, sicherere Methode zum Wechseln zwischen Branches.
  • git checkout — der ursprüngliche Befehl, der sowohl Branches wechseln als auch HEAD lösen kann.
  • git branch — erstelle den Branch, der losgelöste Arbeit rettet.
  • git reflog — stelle Commits wieder her, nachdem du einen Detached HEAD bereits verlassen hast.
  • git tag — das Auschecken eines Tags ist ein häufiger Weg, in einen Detached HEAD zu gelangen.

Übung

Übung
Welche Aussagen über einen Detached HEAD sind korrekt?
Welche Aussagen über einen Detached HEAD sind korrekt?
Was this page helpful?