Warum hat uns git eingestellt (kein Zweig)?

75

Heute morgen ziehen wir uns aus unserem Repo zurück und git zieht uns an (kein Zweig).

Ich verstehe das nicht, warum ist das passiert? Und wie kommt man da raus, ohne unsere Veränderungen zu verlieren?

e-satis
quelle

Antworten:

102

"Derzeit nicht in einem Zweig" bedeutet, dass Sie einen abgetrennten Kopf haben , dh Ihr HEAD-Zeiger verweist direkt auf ein Commit, anstatt symbolisch auf den Namen eines Zweigs zu zeigen.

Sie können in diese Situation geraten, indem Sie ein Commit von SHA1 auschecken, wenn Sie sich mitten in einer Rebase befinden oder wenn eine Zusammenführung fehlschlägt. Es ist schwer zu sagen, was Sie möglicherweise getan haben, um versehentlich in diese Situation zu geraten.

Es wird gesagt, dass Sie Ihre Änderungen möglicherweise verlieren, wenn Sie von einem abgetrennten HEAD zu einem Zweig wechseln, aber das Reflog verfolgt immer, wohin sich Ihr HEAD bewegt hat. Tatsächlich warnt Git 1.7.5 Sie, wenn Sie von einem getrennten HEAD wechseln und Commits verlieren. Sie können nur dann wirklich Arbeit verlieren, wenn Sie nicht festgeschriebene Änderungen vorgenommen haben, die Sie möglicherweise festschreiben oder aufbewahren möchten.

Ein einfacher Weg , um zu sehen , was passiert ist git reflogoder git log -g --decoratefür eine ausführlichere Auflistung. Die --decorateOption kennzeichnet jeden SHA1 mit den Namen aller Zweige, die darauf zeigen. Wenn der SHA1 Ihres aktuellen HEAD genau dem Master entspricht, müssen Sie nichts weiter tun, als git checkout masterwieder auf Kurs zu kommen. Überprüfen Sie andernfalls, ob auf den SHA1 ein anderer Zweig zeigt. Wenn nicht, möchten Sie möglicherweise einen Zweig erstellen, an dem Sie festhalten können.

Ein weiterer guter Befehl ist git branch -av, in ähnlicher Weise alle Zweige aufzulisten und auf was sie verweisen, damit Sie sehen können, was Ihr Zweig (no branch)eigentlich sein soll.

Josh Lee
quelle
Während viele Leute sagen, dass git reflogdas für sie funktioniert, gibt es nichts für mich zurück. git branch -avGibt zwar alle entfernten Zweige zurück und worauf sie verweisen, aber ich weiß nicht, wie das mit meiner lokalen Sache zusammenhängt. Wo bin ich? In welcher Branche und in welchem ​​Commit bin ich? Das möchte ich schon früh wissen.
Dudu
32

Ohne weitere Details ist es schwer zu sagen.

git pullRuft Änderungen aus dem Remote-Repository ab und führt dann eine Zusammenführung durch. Es kann so konfiguriert werden, dass eine Rebase anstelle einer Zusammenführung durchgeführt wird (entweder durch Ausführen git pull --rebaseoder durch Konfigurieren eines wahren Werts branch.<branch_name>.rebasefür den Zweig, in den Sie ziehen).

Wenn Sie mit einem Zweig begonnen haben, bleiben Sie bei jedem Zusammenführungszug immer in diesem Zweig. Auf der anderen Seite funktioniert der Rebase-Befehl immer mit einem vorübergehend getrennten HEAD (auch bekannt als "no branch"). Wenn Sie während eines Pull-Typ-Pulls in diesem Status belassen wurden, liegt dies daran, dass der Rebase-Teil des Pull auf Konflikte gestoßen ist und darauf wartet, dass Sie diese lösen und verwenden rebase --continue(oder --skip, oder --abort).

Standardmäßig speichert das Reflog jedes Update, das an HEAD vorgenommen wird (es kann auch eines für jeden Zweig geben). Sie können das Reflog mit git reflog show(oder git log -gfür eine ausführlichere Ansicht) anzeigen. Es könnte Ihnen helfen festzustellen, wie Sie in diesen Zustand gekommen sind.

Wenn Sie sich mitten in einer Rebase befinden (Sie haben ein .git/rebase-applyVerzeichnis), wurde diese wahrscheinlich gestoppt, damit Sie einige Konflikte lösen können. Verwenden Sie git statusdiese Option, um nach "nicht zusammengeführten" Einträgen zu suchen. In solchen Einträgen sollten Konfliktmarkierungen in die Dateien eingebettet sein (vorausgesetzt, es handelt sich um reine Textdateien). Sie sollten sie bearbeiten, um die Konflikte zu lösen, und sie als zusammengeführt markieren, indem Sie sie git addausführen. Führen Sie dann aus git rebase --continue, um mit der Rebase fortzufahren. Möglicherweise treten weitere Konflikte auf, die auf ähnliche Weise behandelt werden sollten (Bearbeiten, Hinzufügen, Fortfahren). Wenn Sie entscheiden, dass Sie ein bestimmtes Commit nicht mehr benötigen, können Sie es mit überspringen git rebase --skip. Sie können die gesamte Rebase mit abbrechengit rebase --abort. Alle diese Rebase-Befehle werden in der Fehlermeldung aufgeführt, wenn eine Rebase aufgrund eines Konflikts gestoppt wird. Sobald alle ausstehenden Commits angewendet (oder übersprungen) wurden, wird Ihr ursprünglicher Zweig mit dem endgültigen neuen Commit aktualisiert und Ihr HEAD wird erneut mit ihm verbunden (wenn Sie abbrechen, wird Ihr HEAD erneut verbunden, ohne den Zweig zu aktualisieren).

Wenn Ihr abgetrennter HEAD nicht auf Konflikte zurückzuführen ist, die während einer Rebase aufgetreten sind, wurde Ihr HEAD irgendwann vor dem Ziehen abgetrennt. Sie müssen den aktuellen Status des Baums auswerten, um zu entscheiden, was Sie tun möchten. Sie können git show-branch --current --alloder git log --graph --oneline --decorate --alloder ein grafisches Werkzeug verwenden gitk, um herauszufinden, wie sich Ihr aktueller (abgetrennter) KOPF auf Ihre anderen Zweige bezieht. Wenn Sie entscheiden, dass Sie den Inhalt Ihres HEAD behalten möchten, können Sie mit ihnen einen neuen Zweig erstellen git branch new_branch_name. Wenn Sie einen vorhandenen Zweig überschreiben möchten, verwenden Sie git branch --force existing_branch_name. Verwenden git checkout branch_nameSie dann, um den HEAD Ihres Repositorys wieder einem Zweig zuzuordnen.

Chris Johnsen
quelle
2
Netter Tipp über das Vorhandensein .git/rebase-applyeines Hinweises.
Mühlenhaus
2

Beachten Sie, dass Git im Falle eines " git pull --rebase" Laufs, während der getrennt HEADist, versucht hat, den Upstream-Zweig des getrennten HEAD(der per Definition nicht vorhanden ist) zu finden, und unnötige Fehlermeldungen ausgegeben hat.

Dies ist bei Git1.8.0.1 (26. November 2012) nicht mehr der Fall.

Siehe dieses Commit .

VonC
quelle