Warum zeigt "Git-Status" an, dass ich mich im Hauptzweig befinde und "Git-Zweig" nicht in einem neu erstellten Repository?

83

Ich versuche, einen Prozess zu automatisieren und den git branchBefehl auszugeben, um herauszufinden, in welchem ​​Zweig ich mich befinde. Bis auf ein neu initialisiertes Repo, bei dem git branchnichts zurückgegeben wird, funktioniert alles einwandfrei . Da ich mit dem Repo nichts gemacht habe, nicht einmal mit dem anfänglichen Commit, kann ich die Antwort akzeptieren. Wenn ich jedoch eine ausführe git status, wird mir mitgeteilt, dass ich auf dem masterZweig bin , wie hier zu sehen:

$ mkdir todelete
$ cd todelete
$ git init
Initialized empty Git repository in /u/u70021a/todelete/.git
$ git status
On branch master

No commits yet

nothing to commit (create/copy files and use "git add" to track)
$ git branch
$

Mache ich etwas falsch? Gibt es eine Einstellung, die ich nicht richtig eingestellt habe?

Ich habe auch eine Reihe neuer Leute bei Git und ich kann ihnen nicht erklären, warum der Befehl zum Anzeigen des Zweigs, in dem sie sich befinden, nichts anzeigt, der Statusbefehl jedoch.

GOVarney
quelle

Antworten:

94

Ich habe zwei andere Antworten positiv bewertet, aber ich denke, die Art und Weise, dies zu denken, ist einfach: Sie können sich in einem Zweig befinden, der nicht existiert. Dies ist auch in einem neuen leeren Repository normal , da dieser Zweigstellenname die Hash-ID eines vorhandenen, gültigen Commits identifizieren muss , damit ein Zweigstellenname vorhanden ist. Ein neues leeres Repository hat keine Commits, daher dürfen noch keine Zweigstellennamen existieren.

Trotzdem befinden Sie sich zunächst in einem Zweig. Der Zweig, in dem Sie sich befinden, ist derjenige, dessen Name im speziellen Namen gespeichert ist HEAD. In einem neuen, leeren Repository speichert Git den Namen master(genauer gesagt den refs/heads/mastervollständigen Namen des Zweigs) in HEAD, sodass Sie eingeschaltet sind master, solange er masternicht vorhanden ist.

Sie können ändern, welchen nicht vorhandenen Zweig Sie verwenden git checkout -b:

$ git init
Initialized empty Git repository in [path]
$ git checkout -b asdf
Switched to a new branch 'asdf'
$ git checkout -b hello
Switched to a new branch 'hello'

Wenn Sie sich in einem Zweig befinden, der nicht vorhanden ist, wird der Zweig beim nächsten Festschreiben erstellt . So git checkout --orphanfunktioniert auch.

torek
quelle
6
Vielen Dank. Ich bin zwar nicht einverstanden mit dem, was git anzeigt. Zumindest verstehe ich warum. Ihr Checkout-Beispiel ist interessant. Gemäß der Dokumentation für "git checkout" bedeutet -b: Erstellen Sie einen neuen Zweig mit dem Namen <new_branch>, was nicht unbedingt der Fall ist. In Ihrem Beispiel werden weder Zweig asdf noch Hallo erstellt. Dies ist jedoch der Fall, wenn ein Commit ausgeführt wird. Meine persönliche Meinung ist, dass die Nachricht "On Branch Master" in "Next Commit to Branch Master" geändert werden sollte, da der Master-Zweig bis zur Durchführung eines Commits nicht vorhanden ist.
GOVarney
2
Ich bin mir nicht sicher, ob dies für Ihren Fall relevant ist oder nicht, aber ich möchte darauf hinweisen, dass es für Git möglich ist, überhaupt nicht in einem Zweig zu sein.
Sklott
Git verwendet intern, um cat .git/HEADzu sehen, auf welchem ​​Zweig es sich befindet. Wenn Sie herausfinden, dass der Zweig vorhanden ist, wird mehr CPU- und Festplattenzeit verbraucht. Deshalb haben sie dies wahrscheinlich nicht getan
Ferrybig,
Was imo erwähnt werden sollte, ist, dass Sie überhaupt nicht git branchin einem automatisierten Prozess verwenden sollten, da es nicht für diesen Anwendungsfall ausgelegt ist. Es wäre interessant zu sehen, was die Nicht-Porzellan-Befehle hier zeigen, hat git symbolic-ref --short HEADdas gleiche Verhalten?
Voo
@Voo: git symbolic-refZeigt den Namen an, der in HEAD(daher die Referenz für verwaiste / ungeborene Zweige) enthalten ist, sofern dieser HEADnicht getrennt ist. HEAD Kann in einem neuen leeren Repository nicht getrennt werden, da ein getrennter HEAD die Hash-ID eines vorhandenen, gültigen Commits enthalten muss. (In einem nicht leeren Repository mit einem abgetrennten HEAD git symbolic-refwird ein Fehler
ausgegeben
23

git branchzeigt nichts, weil es keinen Zweig gibt. Aber wie Sie lesen können man git init:

Dieser Befehl erstellt ein leeres Git-Repository - im Grunde ein Git-Verzeichnis mit Unterverzeichnissen für Objekte, Refs / Heads, Refs / Tags und Vorlagendateien. Eine anfängliche HEAD-Datei, die auf den HEAD des Hauptzweigs verweist, wird ebenfalls erstellt.

Ich habe den Teil fett gedruckt, den ich für relevant halte - es sieht so aus, als ob es noch keinen Hauptzweig gibt, aber es gibt bereits einen Verweis darauf, und deshalb wird er in gezeigt git status. Beim Festschreiben wird ein geeigneter Zweig erstellt.

Stanowczo
quelle
3
Es sieht also so aus, als würde "git status" nur den "Verzweigungsnamen" anzeigen, wie er in .git / HEAD (ref: refs / Heads / master) zu sehen ist, aber es wird keine Konsistenzprüfung durchgeführt, indem in .git / refs / Heads nachgesehen wird , ob dies der Fall ist existiert tatsächlich.
GOVarney
Ich kann es nicht genau sagen, da ich den Code von git nicht überprüft habe, aber was Sie geschrieben haben, macht für mich Sinn. Trotzdem ziehe ich Toreks Antwort meiner vor :).
Stanowczo
17

Bestehende Antworten befassen sich mit der wörtlichen Frage, warum die Ausgabe so ist, wie sie ist, aber ich denke, sie haben das eigentliche Problem irgendwie beschönigt ...

Sie sagten, Sie automatisieren etwas, daher würde ich vorschlagen, dass weder git statusnoch git branchdas beste Tool in einem Skriptkontext ist.

In dieser Diskussion finden Sie einige Alternativen: So ermitteln Sie programmgesteuert den aktuell ausgecheckten Git-Zweig

Ohne Ihre Bedürfnisse zu kennen (oder wie sich ein ungeborener Zweig verhalten soll), kann ich nicht unbedingt eine Empfehlung aussprechen, aber der Punkt, auf den ich komme, ist, dass einige Befehle für die menschliche Interaktion (Porzellan) und andere für Skripte ( Installation)

Mark Adelsberger
quelle
15

Der Zweig ist noch ungeboren. Wird git branchdaher nicht git symbolic-ref HEADangezeigt ( zeigt an, dass Ihr HEAD auf den Standardzweigmaster zeigt und dass er ungeboren ist, da er git branchnicht angezeigt wird , dh Sie können sich in einem Zweig befinden, der noch nicht vorhanden ist). Wenn Sie jedoch etwas festlegen, wird der Zweig erstellt.

Dies ist auch der Fall, wenn Sie eine orphanFiliale auschecken .

Ich nehme an, git statuszeigt den Zweignamen, da dies der Zweig ist, der erstellt wird.

Informationen zur Skripterstellung finden Sie unter Programmgesteuertes Ermitteln des aktuell ausgecheckten Git-Zweigs

MrTux
quelle
2

In Git ist der Standardzweig master. Wenn Sie git festlegen, "verwendet" git den aktuellen Zweig, auf dem Sie sich gerade befinden. Da Sie ein neues Repository initialisiert haben, befinden Sie sich im "Standard" -Zweig. Aus diesem Grund wird es in Ihrer Zweigstellenliste nicht angezeigt. Sobald Sie Ihre Änderungen festschreiben, wird es angezeigt.

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

CodeWizard
quelle
2
Ich verstehe die Verzweigung, ich verstehe nicht, warum "Git-Status" besagt, dass ich in einer Verzweigung bin, die es nicht gibt.
GOVarney