Nachdem ich die Fragen und Ihre Kommentare gelesen habe, glaube ich, dass der grundlegende Punkt, der Sie hier verwirrt, ist, was es in git (im Vergleich zu anderen Systemen) bedeutet, "auf einem branch zu sein".
In git überprüft ein git checkout
-Befehl einige bestimmte Commits [aber siehe Fußnote 1]. Es setzt auch den speziellen Namen HEAD
, sodass er auf diesen bestimmten Commit verweist. Aber: es gibt zwei verschiedene Möglichkeiten, wie HEAD
einen bestimmten Commit angeben kann. Es kann sein:
- nach ID (dies ist der nicht-übliche Fall), oder
- indirekt über Verweis auf einen branch-Namen (das ist der üblichere Fall).
Wenn Sie git checkout _branchname_
ausführen, setzt git den zweiten, üblichen Fall auf. Wenn Sie dann cat .git/refs/HEAD
ausführen, werden Sie feststellen, dass es den Literalstring ref:
enthält, gefolgt von refs/heads/_branchname_
[2]. Das bedeutet, dass Sie "auf dem branch" sind: Sie haben den Commit überprüft, auf den der branch-Name verweist, aber auch, HEAD
ist ein "symbolischer Verweis". Wenn Sie Änderungen vornehmen und diese committen, wird git den neuen Commit erstellen, dann das branch-Label-Sticky-Note abziehen und auf den neuen Commit kleben. Das "bewegt den branch" zur neu hinzugefügten Spitze, und Sie sind "immer noch auf dem branch".
Auf der anderen Seite, wenn Sie git checkout _tagname_
ausführen, setzt git den ersten, ungewöhnlichen Fall auf. Das macht es auch, wenn Sie über die SHA-1-ID (diese ea56709...
-ähnlichen Zeichenfolgen) auschecken. In diesem Fall enthält die Datei für HEAD
HEAD ist kein "symbolischer Verweis".
Was die tatsächlichen Tags selbst betrifft, handelt es sich lediglich um Namen für Commits. Aber Moment mal, ist das nicht das, was ein branch-Name ist? Ja! Der Unterschied zwischen einem branch-Namen und einem Tag-Namen besteht darin, dass von einem branch-Namen erwartet wird, dass er sich bewegt, und git wird ihn automatisch in diesem "auf einem branch" Fall verschieben. Ein Tag-Name wird nicht "erwartet, sich zu bewegen" [3] und wird sich nie automatisch bewegen.
Fußnoten:
[1] Nur um die Dinge zu verkomplizieren (oder weil die Benutzeroberfläche von git "böse" ist, wie manche sagen würden :-) ) gibt es Fälle, in denen git checkout
nicht HEAD
ändert, insbesondere wenn Sie es auffordern, bestimmte Pfadnamen zu überprüfen.
[2] In sehr alten Versionen von git wurde anstelle von ref: ...
ein symbolischer Link verwendet. Das Ziel des Links war die branch-ID-Datei, z. B. refs/heads/master
oder ähnliches, sodass durch Öffnen und Lesen der Datei die Commit-ID erhalten wurde, und Sie mussten lstat
verwenden, um festzustellen, ob Sie "auf einem branch" sind. Dies funktioniert nicht unter Windows und schloss "packing" Branches (.git/packed-refs
) aus, daher die Änderung, um stattdessen ref:
zu verwenden.
[3] Die Begriffe "erwartet" und "nicht erwartet" sollten Sie dazu bringen, zu fragen: erwartet von wem? Git selbst hat kein Problem damit, dass git-Benutzer Tags verschieben, es sind die Personen, die git verwenden (und oft Skripte, die sie schreiben), die davon verwirrt werden. Bewegen Sie also keinen Tag, es sei denn, Sie haben zuerst mit anderen Personen, die das Repository teilen, Rücksprache gehalten.