Das Auschecken des Git-Tags führt zu einem "getrennten HEAD-Status".

166

Ich entwickle ein Bereitstellungsskript für mein Git-Projekt und habe gerade angefangen, Tags zu verwenden. Ich habe ein neues Tag namens hinzugefügt v2.0:

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

Und ich habe dieses Tag in das Remote-Repository verschoben

git push --tags

Wenn ich versuche, das Bereitstellungsskript auszuführen und das v2.0Tag auszuchecken, wird folgende Meldung angezeigt:

Sie befinden sich im Status "Freistehender KOPF". Sie können sich umschauen, experimentelle Änderungen vornehmen und diese festschreiben, und Sie können alle in diesem Zustand vorgenommenen Festschreibungen verwerfen, ohne Auswirkungen auf Zweige zu haben, indem Sie eine weitere Prüfung durchführen. Wenn Sie einen neuen Zweig erstellen möchten, um die von Ihnen erstellten Commits beizubehalten, können Sie dies (jetzt oder später) tun, indem Sie -b erneut mit dem Befehl checkout verwenden. Beispiel: git checkout -b new_branch_name HEAD ist jetzt bei

Ist das normal? Das Repository ist in der Schwebe, denn wenn ich das tue:

git branch

Ich bekomme diese Ausgabe:

* (no branch)
  master

Entschuldigung, wenn dies offensichtlich ist, aber ich konnte es nicht herausfinden.

Khriz
quelle
Wenn Sie sagen: "Führen Sie das Bereitstellungsskript aus und checken Sie die Version 2.0 aus", sieht Ihr Code wie folgt aus: "Git Checkout Version 2.0"? Ich versuche, mein Release-Skript zu überarbeiten, und wenn ich "git checkout v2.0" von meinem Produktionscomputer aus starte, wird "Fehler: Pfadspezifikation 'v2.0' stimmte nicht mit Dateien überein, die git bekannt sind." Obwohl ich "git push origin --tags" auf meinem lokalen Computer ausgeführt habe, bevor ich "git checkout v2.0" in der Produktion ausführe. Ich habe auch versucht, "git pull --tags" und "git fetch --tags" in der Produktion auszuführen, bevor ich "git checkout v2.0" aufgerufen habe, und das funktioniert auch nicht ... Ich bekomme immer noch das Error. Irgendwelche Ideen?
John Erck
3
Ich wollte gerade den obigen Kommentar löschen, dachte dann aber, dass es jemand anderem helfen könnte, ihn aufrechtzuerhalten. Ich habe den Fehler erhalten, weil ich einen TYPO in meinem Tag-Namen hatte, als ich "git checkout v2.0" ausführte. Der Tippfehler ist jedoch genau der gleiche Fehler, den Sie erhalten, wenn Sie "git checkout v2.0" OHNE Tippfehler VOR dem Ausführen "git fetch --tags" ausführen. Letztendlich wurde mein Problem gelöst, indem "git fetch --tags" vor dem Ausführen von "git checkout v2.0" ohne Tippfehler ausgeführt wurde. Puh!
John Erck
Schön, ja, Sie müssen vorher Abruf-Tags abrufen (oder Git-Abruf, der alles von der Fernbedienung abruft), damit Git das Tag auschecken kann. Entschuldigung, ich habe heute gerade Ihren Kommentar gesehen.
Chriz

Antworten:

429

Okay, zuerst ein paar Begriffe etwas vereinfacht.

In gita ist tag(wie viele andere Dinge) das, was man als Baum bezeichnet . Es ist eine Möglichkeit, sich auf einen Punkt in der Geschichte des Projekts zu beziehen. Treeishes können ein Tag, ein Commit, ein Datumsbezeichner, ein Ordnungsbezeichner oder viele andere Dinge sein.

Jetzt branchist a wie ein Tag, aber beweglich. Wenn Sie sich in einem Zweig befinden und einen Commit durchführen, wird der Zweig in den neuen Commit verschoben, den Sie vorgenommen haben, und gibt die aktuelle Position an.

Ihr HEADist Zeiger auf einen Zweig, der als "aktuell" betrachtet wird. Normalerweise , wenn Sie ein Repository klonen, HEADwird zeigen auf , masterdie wiederum weisen auf eine zu begehen. Wenn Sie dann so etwas tun git checkout experimental, wechseln Sie den HEADto-Punkt zu dem experimentalZweig, der möglicherweise auf ein anderes Commit verweist.

Nun die Erklärung.

Wenn Sie a ausführen git checkout v2.0, wechseln Sie zu einem Commit, auf das a nicht verweist branch. Das HEADist jetzt "losgelöst" und zeigt nicht auf einen Zweig. Wenn Sie sich jetzt (wie Sie möchten) für ein Commit entscheiden, müssen Sie keinen Verzweigungszeiger aktualisieren, um dieses Commit zu verfolgen. Wenn Sie zu einem anderen Commit zurückkehren, verlieren Sie dieses neue Commit, das Sie vorgenommen haben. Das sagt Ihnen die Nachricht.

Normalerweise können Sie sagen git checkout -b v2.0-fixes v2.0. Dadurch wird ein neuer Verzweigungszeiger an dem Commit erstellt, auf den der Baum zeigt v2.0(in diesem Fall ein Tag), und dann wird Ihr HEADto-Punkt darauf verschoben . Wenn Sie jetzt Commits vornehmen, können Sie diese (mithilfe des v2.0-fixesZweigs) verfolgen und wie gewohnt arbeiten. Es ist nichts "Falsches" an dem, was Sie getan haben, besonders wenn Sie sich nur den v2.0Code ansehen möchten . Wenn Sie dort jedoch Änderungen vornehmen möchten, die Sie verfolgen möchten, benötigen Sie eine Verzweigung.

Sie sollten einige Zeit damit verbringen, das gesamte DAG-Modell von git zu verstehen. Es ist überraschend einfach und macht alle Befehle ziemlich klar.

Noufal Ibrahim
quelle
Ok, danke, ich muss keine Änderungen am Code vornehmen, also denke ich, dass es in Ordnung ist. Ich muss keinen Zweig erstellen. Vielen Dank!
Khriz
1
Ich war verloren, als ich diese Antwort zum ersten Mal durchgesehen habe, aber nachdem ich die Dokumentation zur Git-Verzweigung gelesen hatte: http://git-scm.com/book/en/Git-Branching-What-a-Branch-Ist es viel klarer .
Mark Stiles
3
Fantastische Antwort, aber darf ich hinzufügen in Bezug auf: "Wenn Sie zu einem anderen Commit zurückkehren, verlieren Sie dieses neue Commit, das Sie gemacht haben." - Sie finden das Commit immer noch in git reflog, was ein großartiger Befehl ist, über den Sie Bescheid wissen sollten! Wenn keine Speicherbereinigung stattgefunden hat, ist es anscheinend "unmöglich", ein Commit zu verlieren.
Dmitry Minkovsky
Nicht referenzierte Commits können durch eine Speicherbereinigungsoperation verloren gehen.
Noufal Ibrahim
1
Die URL ist falsch, weil sie das Layout der Seite geändert haben.
Jcubic
12

Ja, das ist normal. Dies liegt daran, dass Sie ein einzelnes Commit auschecken, das keinen Kopf hat. Insbesondere ist es (früher oder später) kein Leiter einer Branche.

Aber normalerweise gibt es kein Problem mit diesem Zustand. Sie können einen neuen Zweig aus dem Tag erstellen, wenn Sie sich dadurch sicherer fühlen :)

KingCrunch
quelle
1
Ok, ich werde es so halten ... Sicherheit wird sowieso überbewertet;)
Khriz
Wie Sie in Noufals Antwort kommentiert haben (es ist die bessere, muss ich sagen;)): Solange Sie nichts ändern, gibt es nichts, worüber Sie sich Sorgen machen müssen. Wenn Sie jedoch davon ausgehen , dass Sie etwas ändern können, können Sie einfach einen Zweig erstellen, da diese in Git billig sind und Sie ihn löschen (und später neu erstellen usw.).
KingCrunch