Wie kann ich losgelösten KOPF mit Master / Ursprung in Einklang bringen?

1558

Ich bin neu in der Verzweigungskomplexität von Git. Ich arbeite immer an einem einzelnen Zweig und schreibe Änderungen fest und drücke dann regelmäßig auf meinen entfernten Ursprung.

Vor kurzem habe ich einige Dateien zurückgesetzt, um sie aus dem Commit-Staging herauszuholen, und später rebase -ieinige lokale Commits entfernt. Jetzt bin ich in einem Zustand, den ich nicht ganz verstehe.

git logZeigt in meinem Arbeitsbereich genau, was ich erwarten würde - ich bin im richtigen Zug mit den Verpflichtungen, die ich nicht wollte, und neuen dort usw.

Aber ich habe nur in das Remote-Repository gepusht, und was da ist, ist anders - ein paar der Commits, die ich in der Rebase getötet hatte, wurden gepusht, und die neuen Commits, die lokal festgeschrieben wurden, sind nicht da.

Ich denke, "master / origin" ist von HEAD getrennt, aber ich bin nicht 100% klar, was das bedeutet, wie man es mit den Kommandozeilen-Tools visualisiert und wie man es behebt.

Ben Zotto
quelle
Haben Sie die Commits vor der Rebase verschoben?
Manojlds
@manojlds: Nicht sicher, was du meinst. Ich habe einige Zeit vor dem Rebase gepusht, aber nicht unmittelbar vorher.
Ben Zotto
Wie in haben Sie zuvor die Commits gepusht, die Sie in der Rebase -i entfernt haben. Aus Ihrer Antwort denke ich nicht.
Manojlds
@manojlds: Richtig. Ich habe nur Commits getötet, die jünger waren als der letzte Push. (Obwohl, wie ich bereits erwähnte, ich seitdem gepusht habe, da ich dachte, alles sei in Ordnung)
Ben Zotto
Können Sie erklären, was Sie teilweise getan haben I did a reset of some files to get them out of commit staging? Entschuldigung für die Fragen :)
Manojlds

Antworten:

2521

Lassen Sie uns zunächst klären, was HEAD ist und was es bedeutet, wenn es abgenommen wird.

HEAD ist der symbolische Name für das aktuell ausgecheckte Commit. Wenn HEAD nicht getrennt ist (die „normale“ Situation 1 : Sie haben einen Zweig ausgecheckt), zeigt HEAD tatsächlich auf den „ref“ eines Zweigs und der Zweig zeigt auf das Commit. HEAD ist somit an einen Zweig „gebunden“. Wenn Sie ein neues Commit durchführen, wird der Zweig, auf den HEAD zeigt, aktualisiert, um auf das neue Commit zu verweisen. HEAD folgt automatisch, da es nur auf den Zweig zeigt.

  • git symbolic-ref HEADAusbeuten refs/heads/master
    Der Zweig mit dem Namen "master" wird ausgecheckt.
  • git rev-parse refs/heads/masterYield 17a02998078923f2d62811326d130de991d1a95a
    Dieses Commit ist der aktuelle Tipp oder „Kopf“ des Hauptzweigs.
  • git rev-parse HEADergibt auch 17a02998078923f2d62811326d130de991d1a95a
    Dies ist, was es bedeutet, ein "symbolischer Verweis" zu sein. Es zeigt durch eine andere Referenz auf ein Objekt.
    (Symbolische Verweise wurden ursprünglich als symbolische Links implementiert, später jedoch in einfache Dateien mit zusätzlicher Interpretation geändert, damit sie auf Plattformen ohne Symlinks verwendet werden können.)

Wir haben HEADrefs/heads/master17a02998078923f2d62811326d130de991d1a95a

Wenn HEAD getrennt ist, zeigt es direkt auf ein Commit - anstatt indirekt über einen Zweig auf eines zu verweisen. Sie können sich einen abgetrennten KOPF als einen unbenannten Zweig vorstellen.

  • git symbolic-ref HEAD scheitert mit fatal: ref HEAD is not a symbolic ref
  • git rev-parse HEADRenditen 17a02998078923f2d62811326d130de991d1a95a
    Da es sich nicht um einen symbolischen Verweis handelt, muss er direkt auf das Commit selbst verweisen.

Wir haben HEAD17a02998078923f2d62811326d130de991d1a95a

Das Wichtigste, an das Sie sich bei einem abgetrennten HEAD erinnern sollten, ist, dass wenn das Commit, auf das es zeigt, ansonsten nicht referenziert ist (kein anderer Ref kann es erreichen), es beim Auschecken eines anderen Commits „baumelt“. Letztendlich werden solche baumelnden Commits durch den Garbage Collection-Prozess zurückgeschnitten (standardmäßig werden sie mindestens 2 Wochen lang aufbewahrt und können länger aufbewahrt werden, indem auf HEADs Reflog verwiesen wird).

1 Es ist vollkommen in Ordnung, „normale“ Arbeiten mit einem abgetrennten KOPF auszuführen. Sie müssen nur nachverfolgen, was Sie tun, um zu vermeiden, dass Sie die abgelaufene Geschichte aus dem Reflog heraus fischen müssen.


Die Zwischenschritte einer interaktiven Rebase werden mit einem abgetrennten HEAD ausgeführt (teilweise, um eine Verschmutzung des Reflogs des aktiven Zweigs zu vermeiden). Wenn Sie den vollständigen Rebase-Vorgang abgeschlossen haben, wird Ihr ursprünglicher Zweig mit dem kumulativen Ergebnis des Rebase-Vorgangs aktualisiert und HEAD erneut an den ursprünglichen Zweig angehängt. Ich vermute, dass Sie den Rebase-Prozess nie vollständig abgeschlossen haben. Dadurch erhalten Sie einen getrennten HEAD, der auf das Commit verweist, das zuletzt von der Rebase-Operation verarbeitet wurde.

Um sich von Ihrer Situation zu erholen, sollten Sie einen Zweig erstellen, der auf das Commit verweist, auf das Ihr losgelöster HEAD derzeit zeigt:

git branch temp
git checkout temp

(Diese beiden Befehle können als abgekürzt werden. git checkout -b temp)

Dadurch wird Ihr HEAD wieder mit dem neuen tempZweig verbunden.

Als Nächstes sollten Sie das aktuelle Commit (und seinen Verlauf) mit dem normalen Zweig vergleichen, an dem Sie voraussichtlich arbeiten werden:

git log --graph --decorate --pretty=oneline --abbrev-commit master origin/master temp
git diff master temp
git diff origin/master temp

(Sie möchten wahrscheinlich mit den Protokolloptionen experimentieren: Hinzufügen -p, weglassen --pretty=…, um die gesamte Protokollnachricht anzuzeigen usw.)

Wenn Ihr neuer tempZweig gut aussieht, möchten Sie ihn möglicherweise aktualisieren (z. B.), masterum darauf zu verweisen:

git branch -f master temp
git checkout master

(Diese beiden Befehle können als abgekürzt werden. git checkout -B master temp)

Sie können dann den temporären Zweig löschen:

git branch -d temp

Schließlich möchten Sie wahrscheinlich die wiederhergestellte Geschichte vorantreiben:

git push origin master

Möglicherweise müssen Sie --forceam Ende dieses Befehls einen Push hinzufügen , wenn der Remote-Zweig nicht schnell zum neuen Commit weitergeleitet werden kann (dh Sie haben ein vorhandenes Commit gelöscht oder neu geschrieben oder auf andere Weise einen Teil des Verlaufs neu geschrieben).

Wenn Sie sich mitten in einer Rebase-Operation befanden, sollten Sie diese wahrscheinlich bereinigen. Sie können überprüfen, ob eine Rebase ausgeführt wurde, indem Sie nach dem Verzeichnis suchen .git/rebase-merge/. Sie können die laufende Rebase manuell bereinigen, indem Sie nur dieses Verzeichnis löschen (z. B. wenn Sie sich nicht mehr an den Zweck und den Kontext der aktiven Rebase-Operation erinnern). Normalerweise würden Sie verwenden git rebase --abort, aber das führt zu einem zusätzlichen Zurücksetzen, das Sie wahrscheinlich vermeiden möchten (es verschiebt HEAD zurück zum ursprünglichen Zweig und setzt es zurück zum ursprünglichen Commit, wodurch einige der oben geleisteten Arbeiten rückgängig gemacht werden).

Chris Johnsen
quelle
6
Interessant von man git-symbolic-ref: "In der Vergangenheit gab .git/HEADes einen symbolischen Link, auf den verwiesen wurde refs/heads/master. Als wir zu einem anderen Zweig wechseln wollten, haben wir dies getan ln -sf refs/heads/newbranch .git/HEAD, und als wir herausfinden wollten, in welchem ​​Zweig wir uns befinden, haben wir dies getan readlink .git/HEAD. Aber symbolische Links sind nicht vollständig portabel Daher sind sie jetzt veraltet und symbolische Verweise (wie oben beschrieben) werden standardmäßig verwendet. "
Dmitry Minkovsky
10
Ich stimme @AntonioSesto zu: Für die meisten Projekte (auch für ziemlich große) benötigen Sie nicht die umwerfende Komplexität, die Git bietet. Mein Gehirn rebelliert damit, sich mit etwas auseinanderzusetzen, das so deutlich überarbeitet ist. Ich brauche es nicht und ich will es nicht.
Jasper Sprengers
36
Dies ist eine gute Antwort, aber ich denke, dass der temporäre Zweig nicht erforderlich ist (obwohl ich normalerweise selbst einen verwende). git branch -f master HEAD && git checkout masterist genug - vorausgesetzt, Ihr Ziel ist es, Ihren aktuellen Kopf zu behalten, ihn aber als zu bezeichnen master. Andere Ziele sind ebenfalls sinnvoll und erfordern andere Rezepte.
Adrian Ratnapala
38
Lol bei dem Kommentar über die Länge. Während der Rest von uns einfach durchblättert, bis wir die Zeile "Um sich von Ihrer Situation zu erholen [...]" erreichen, und von dort aus fortfahren - während wir uns im Kopf notieren, dass es eine nützliche, gut erklärte Hintergrundgeschichte gibt, die wir lesen können an einem regnerischen Tag. Die Option , mehr zu lesen, tut Ihnen nicht weh, aber es kommt anderen zugute.
underscore_d
5
Deshalb hasse ich Idioten.
Monica Heddneck
626

Mach das einfach:

git checkout master

Wenn Sie Änderungen haben, die Sie beibehalten möchten, gehen Sie folgendermaßen vor:

git checkout -b temp
git checkout -B master temp
Daniel Alexiuc
quelle
57
Dies ist eine gefährliche Antwort. Personen, die zu dieser Antwort kommen, haben unterschiedliche Zustände und Antworten auf "Nur um dies zu beheben" beantworten keine Fragen. Dieser kann leicht die Arbeit zerstören.
Archonic
15
! "git checkout master" führt dazu, dass alle Änderungen verloren gehen, wenn der abgenommene Kopf nicht Teil des Masters ist !!
Tony
3
@Blauhirn Du hast wahrscheinlich das Commit ausgecheckt, nicht die Filiale. Der Zweig zeigt immer noch auf dasselbe Commit, aber Sie befinden sich in einem anderen "Modus".
Daniel Alexiuc
1
git resetsollte mit einer Warnung kommen "Wenn Sie keine Ahnung haben, was Sie tun, hören Sie auf". Ich habe mich gerade von einer Stunde des Terrors erholt und gedacht, ich hätte die letzte Arbeitswoche verloren. Vielen Dank!
Opus1217
1
Einverstanden mit @Archonic Es ist wichtig zu verstehen, wie Git funktioniert, bevor Sie blind Befehle ausführen. Sie können Zeit sparen, indem Sie die große Antwort nicht lesen, aber mehr Zeit verlieren, wenn Ihre Arbeit verloren geht.
Yusufali2205
132

Ich bin auf dieses Problem gestoßen und als ich die am besten gewählte Antwort gelesen habe:

HEAD ist der symbolische Name für das aktuell ausgecheckte Commit.

Ich dachte: Ah-ha! Wenn HEADder symbolische Name für das aktuelle Checkout-Commit lautet, kann ich ihn masterabgleichen, indem ich ihn gegen Folgendes umbasiere master:

git rebase HEAD master

Dieser Befehl:

  1. Checkt aus master
  2. Identifiziert die übergeordneten Commits von HEADback bis zu dem Punkt, von dem HEADabgewichen wirdmaster
  3. spielt diese Commits zusätzlich master

Das Endergebnis ist, dass alle Commits, die in waren, HEADaber nicht, masterdann auch in sind master. masterbleibt ausgecheckt.


In Bezug auf die Fernbedienung:

Ein paar der Commits, die ich in der Rebase getötet hatte, wurden gepusht, und die neuen Commits, die vor Ort begangen wurden, sind nicht da.

Der Remote-Verlauf kann nicht mehr mithilfe Ihres lokalen Verlaufs vorgespult werden. Sie müssen push ( git push -f) erzwingen, um den Remote-Verlauf zu überschreiben. Wenn Sie Mitarbeiter haben, ist es normalerweise sinnvoll, dies mit ihnen zu koordinieren, damit alle auf derselben Seite sind.

Nachdem Sie masterauf Remote gedrückt haben origin, wird Ihr Remote-Tracking-Zweig origin/masterso aktualisiert, dass er auf dasselbe Commit wie verweist master.

Dmitry Minkovsky
quelle
3
git: "Zuerst den Kopf zurückspulen, um deine Arbeit noch einmal abzuspielen ... Schneller Vorlauf des Masters zu HEAD." ich: "nett!"
Benjamin
81

Hier finden Sie eine grundlegende Erklärung für den abgetrennten Kopf:

http://git-scm.com/docs/git-checkout

Befehlszeile zur Visualisierung:

git branch

oder

git branch -a

Sie erhalten die Ausgabe wie folgt:

* (no branch)
master
branch1

Die * (no branch)zeigt, dass Sie in losgelöstem Kopf sind.

Sie hätten durch ein git checkout somecommitusw. in diesen Zustand gelangen können, und es hätte Sie mit folgenden Warnungen gewarnt:

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 neuer_zweigname

Nun, um sie auf den Meister zu bringen:

Machen Sie ein git reflogoder auch nur git logund notieren Sie Ihre Commits. Nun git checkout masterund git mergedie Commits.

git merge HEAD@{1}

Bearbeiten:

Verwenden Sie zum Hinzufügen git rebase -inicht nur das Löschen / Beenden von nicht benötigten Commits, sondern auch das Bearbeiten. Erwähnen Sie einfach "Bearbeiten" in der Festschreibungsliste, und Sie können Ihr Festschreiben ändern und dann ein "Weiter" ausstellen git rebase --continue. Dies hätte sichergestellt, dass Sie nie zu einem freistehenden KOPF gekommen sind.

Manojlds
quelle
Vielen Dank für das Detail und die tollen Informationshinweise hier. Es scheint, dass eine explizite Zusammenführung nicht erforderlich war, aber dies visualisierte einige Konzepte, auf die ich zurückkommen werde. Vielen Dank.
Ben Zotto
6
Was macht "@ {1}"?
ebi
35

Holen Sie sich Ihr freistehendes Commit in einen eigenen Zweig

Einfach laufen git checkout -b mynewbranch.

Führen git logSie dann aus , und Sie werden sehen, dass sich das Commit jetzt HEADin diesem neuen Zweig befindet.

Rose Perrone
quelle
Wenn ich das mache, hängt es mynewbranchan irgendetwas?
Benjohn
1
Ja, es hängt an der Stelle, an der der abgenommene Kopf angebracht worden wäre, genau das, was ich wollte. Vielen Dank!
Benjohn
22

Wenn Sie nur einen Hauptzweig haben und zurück zum "Entwickeln" oder einer Funktion möchten, gehen Sie wie folgt vor:

git checkout origin/develop

Hinweis: Herkunft / Entwicklung auschecken .

Sie befinden sich im getrennten HEAD- Zustand. 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 ...

dann

git checkout -b develop

Es klappt :)

amdev
quelle
7
Was für mich funktioniert hat, ist nicht "Ursprung / Entwicklung der Git-Kasse", sondern "Entwicklung der Git-Kasse". Die Verwendung von 'Ursprung / Entwicklung' hat immer zu keinen Änderungen geführt und bleibt dabei in "KOPF am Ursprung / Entwicklung losgelöst". Das Überspringen des Ursprungs-Teils hat alles behoben.
DrStrangepork
18

Wenn Sie Ihren aktuellen abgetrennten KOPF drücken möchten ( git logvorher prüfen ), versuchen Sie:

git push origin HEAD:master

um Ihren abgetrennten HEAD am Ursprung in die Hauptniederlassung zu senden. Wenn Ihr Push abgelehnt wird, versuchen Sie git pull origin masterzuerst, die Änderungen vom Ursprung zu erhalten. Wenn Sie sich nicht um die Änderungen vom Ursprung kümmern und diese abgelehnt werden, weil Sie eine absichtliche Neugründung vorgenommen haben und Ursprung / Master durch Ihren derzeit getrennten Zweig ersetzen möchten, können Sie dies erzwingen ( -f). Falls Sie den Zugriff auf frühere Commits verloren haben, können Sie jederzeit git reflogden Verlauf aller Zweige anzeigen.


Führen Sie die folgenden Befehle aus, um unter Beibehaltung der Änderungen zu einem Hauptzweig zurückzukehren:

git rebase HEAD master
git checkout master

Siehe: Git: "Derzeit in keinem Zweig." Gibt es eine einfache Möglichkeit, zu einem Zweig zurückzukehren, während die Änderungen beibehalten werden?

Kenorb
quelle
2
Dies sendet tatsächlich die getrennten Commits an origin / master. Um den Kopf an den lokalen Zweig anzuschließen,
Paschalis
Wenn ich das mache, bekomme ich Dieses Repository ist für Git LFS konfiguriert, aber 'git-lfs' wurde nicht in Ihrem Pfad gefunden. Wenn Sie Git LFS nicht mehr verwenden möchten, entfernen Sie diesen Hook, indem Sie .git / hooks / post-checkout löschen.
user2568374
16

Ich habe diese Frage bei der Suche gefunden You are in 'detached HEAD' state.

Nachdem ich analysiert hatte, was ich getan hatte, um hierher zu kommen, stellte ich im Vergleich zu dem, was ich in der Vergangenheit getan hatte, fest, dass ich einen Fehler gemacht hatte.

Mein normaler Fluss ist:

git checkout master
git fetch
git checkout my-cool-branch
git pull

Diesmal habe ich:

git checkout master
git fetch
git checkout origin/my-cool-branch
# You are in 'detached HEAD' state.

Das Problem ist, dass ich versehentlich getan habe:

git checkout origin/my-cool-branch

Eher, als:

git checkout my-cool-branch

Die Lösung (in meiner Situation) bestand einfach darin, den obigen Befehl auszuführen und dann den Ablauf fortzusetzen:

git checkout my-cool-branch
git pull
user664833
quelle
11

Folgendes hat bei mir funktioniert (nur mit Zweigstellenmaster):

git push origin HEAD:master
git checkout master        
git pull

Der erste schiebt den abgetrennten KOPF zum entfernten Ursprung.

Der zweite wechselt zum Zweigmaster.

Der dritte stellt den HEAD wieder her, der an den Zweigstellenmaster angehängt wird.

Beim ersten Befehl können Probleme auftreten, wenn der Push abgelehnt wird. Dies wäre jedoch kein Problem mehr mit abgenommenem Kopf, sondern mit der Tatsache, dass dem abgetrennten KOPF einige entfernte Änderungen nicht bekannt sind.

Daniel Porumbel
quelle
hat nicht funktioniert, ich habe: Dieses Repository ist für Git LFS konfiguriert, aber 'git-lfs' wurde nicht in Ihrem Pfad gefunden. Wenn Sie Git LFS nicht mehr verwenden möchten, entfernen Sie diesen Hook, indem Sie .git / hooks / pre-push löschen. UND Sie befinden sich derzeit nicht in einer Filiale. Bitte geben Sie an, mit welchem ​​Zweig Sie zusammenführen möchten.
user2568374
11

Ich bin heute auf dieses Problem gestoßen und bin mir ziemlich sicher, dass ich es folgendermaßen gelöst habe:

git branch temp
git checkout master
git merge temp

Ich war auf meinem Arbeitscomputer, als ich herausfand, wie das geht, und jetzt stoße ich auf meinem PC auf dasselbe Problem. Ich muss also bis Montag warten, bis ich wieder am Arbeitscomputer bin, um genau zu sehen, wie ich es gemacht habe.

Adamwineguy
quelle
@ StarShine Kenorb hat das Problem behoben. Jetzt werden Ihre getrennten Commits in einem neuen Zweig, temp, gespeichert, auf master umgeschaltet und temp in master zusammengeführt.
Cees Timmerman
Ich weiß nicht, warum ppl dies ablehnen. Es hat meinen Problemstatus behoben, aber Sie möchten möglicherweise den Befehl delete temp branch einfügen.
GlassGhost
8

Wenn Sie ganz sicher sind, dass HEAD der gute Zustand ist:

git branch -f master HEAD
git checkout master

Sie können wahrscheinlich nicht zum Ursprung drängen, da Ihr Meister vom Ursprung abgewichen ist. Wenn Sie sicher sind, dass niemand anderes das Repo verwendet, können Sie Folgendes erzwingen:

git push -f

Am nützlichsten, wenn Sie sich in einem Feature-Zweig befinden, den sonst niemand verwendet.

Geon
quelle
6

Alles, was Sie tun müssen, ist 'git checkout [Filialname]', wobei [Filialname] der Name des ursprünglichen Zweigs ist, von dem Sie in einen getrennten Kopfzustand geraten sind. Das (von asdfasdf getrennt) verschwindet.

In der Verzweigung 'dev' checken Sie beispielsweise das Commit asdfasd14314 -> aus

'git checkout asdfasd14314'

Sie befinden sich jetzt in einem Zustand mit losgelöstem Kopf

'git branch' listet so etwas wie -> auf

* (detached from asdfasdf)
  dev
  prod
  stage

aber um aus dem losgelösten Kopfzustand herauszukommen und zurück zu dev ->

'git checkout dev'

und dann wird 'git branch' aufgelistet ->

* dev
  prod
  stage

Aber das ist natürlich so, wenn Sie nicht beabsichtigen, Änderungen aus dem Zustand des abgetrennten Kopfes beizubehalten, aber ich tue dies häufig, ohne Änderungen vorzunehmen, sondern nur, um mir ein vorheriges Commit anzusehen

Adam Freeman
quelle
6

Wie Chris sagte, hatte ich folgende Situation

git symbolic-ref HEAD scheitert mit fatal: ref HEAD is not a symbolic ref

Es wurde jedoch git rev-parse refs/heads/masterauf ein gutes Commit hingewiesen, von dem ich mich erholen konnte (in meinem Fall das letzte Commit, und Sie können dieses Commit mithilfe von sehengit show [SHA]

Danach habe ich viele unordentliche Dinge getan, aber was behoben zu sein scheint, ist nur,

git symbolic-ref HEAD refs/heads/master

Und der Kopf ist wieder angebracht!

Varun Garg
quelle
1
Vielen Dank! Mein Kopf hatte sich gelöst. Ich könnte es aufholen, um zu meistern, aber sie zeigten zufällig auf dasselbe Commit und nicht auf den Master, der auf das Commit zeigte. Guter Tipp = D
RagingRoosevelt
4

Anstatt zu tun git checkout origin/master

mach einfach git checkout master

Dann git branchwird Ihre Filiale bestätigt.

Goran Ch.
quelle
4

Ich hatte heute dieses Problem, bei dem ich ein Submodul aktualisiert hatte, aber in keinem Zweig war. Ich hatte mich bereits verpflichtet, also würde das Verstauen, Auschecken und Entstauen nicht funktionieren. Am Ende pflückte ich das Commit des abgetrennten Kopfes. Unmittelbar nach dem Festschreiben (als der Push fehlschlug) tat ich Folgendes:

git checkout master
git cherry-pick 99fe23ab

Mein Gedanke war: Ich bin auf einem distanzierten Kopf, aber ich möchte Meister werden. Angenommen, mein losgelöster Zustand unterscheidet sich nicht sehr vom Master. Wenn ich mein Commit auf den Master anwenden könnte, wäre ich festgelegt. Genau das macht Cherry-Pick.

vorbenetzen
quelle
3

Wenn Sie haben einige Commits auf dem Master und wollen einfach nur „rückwärts merge“ masterdort (dh wollen Sie masterzu Punkt HEAD), die Einzeiler sein würden:

git checkout -B master HEAD
  1. Dadurch wird ein neuer Zweig mit dem Namen erstellt master, auch wenn er bereits vorhanden ist (was wie ein Umzug ist masterund das wollen wir).
  2. Der neu erstellte Zweig zeigt auf HEAD, wo Sie sich befinden.
  3. Der neue Zweig ist ausgecheckt, sodass Sie masterdanach eingeschaltet sind.

Ich fand dies besonders nützlich bei Unter-Repositorys, die sich auch ziemlich oft in einem getrennten Zustand befinden.

Quazgar
quelle
3

Ich hatte das gleiche Problem und habe es durch die folgenden Schritte gelöst.

Wenn Sie Ihre Änderungen behalten müssen

  1. Zuerst müssen Sie den git checkout masterBefehl ausführen , um zum Hauptzweig zurückzukehren.
  2. Wenn Sie Ihre Änderungen beibehalten müssen, führen Sie einfach git checkout -b changesund aus git checkout -B master changes

Wenn Sie Ihre Änderungen nicht benötigen

  1. So entfernen Sie alle nicht verfolgten Dateien aus Ihrem Zweiglauf git clean -df.

  2. Dann müssen Sie alle nicht bereitgestellten Änderungen in Ihrem Repository löschen. Dazu muss man laufengit checkout --

  3. Schließlich müssen Sie Ihren Zweig mit dem git checkout masterBefehl wieder in den Hauptzweig zurückversetzen .

Aravinda Meewalaarachchi
quelle
3

Für mich war es so einfach wie das erneute Löschen der lokalen Niederlassung, da ich keine lokalen Commits hatte, die ich pushen wollte:

So tat ich:

git branch -d branchname

Und dann nochmal die Filiale auschecken:

git checkout branchname
Klaus
quelle
1

Wenn ich mich persönlich in einer Situation befinde, in der sich herausstellt, dass ich einige Änderungen vorgenommen habe, während ich nicht in der Lage bin master(dh HEADdirekt über der masterPosition abgesetzt bin und dazwischen keine Commits liegen), kann das Verstauen helfen:

git stash # HEAD has same content as master, but we are still not in master
git checkout master  # switch to master, okay because no changes and master
git stash apply  # apply changes we had between HEAD and master in the first place
Ben Usman
quelle
1

In einfachen Worten bedeutet der getrennte HEAD-Status, dass Sie nicht zum HEAD (oder zur Spitze) eines Zweigs ausgecheckt sind .

Mit einem Beispiel verstehen

Ein Zweig ist in den meisten Fällen eine Folge mehrerer Commits wie:

Commit 1: master -> branch_HEAD (123be6a76168aca712aea16076e971c23835f8ca)

Commit 2: master -> 123be6a76168aca712aea16076e971c23835f8ca -> branch_HEAD (100644a76168aca712aea16076e971c23835f8ca)

Wie Sie oben bei einer Abfolge von Festschreibungen sehen können, verweist Ihre Verzweigung auf Ihre letzte Festschreibung. Wenn Sie also in diesem Fall auschecken , um 123be6a76168aca712aea16076e971c23835f8ca festzuschreiben , befinden Sie sich in einem getrennten Kopfzustand, da HEAD Ihrer Verzweigung auf 100644a76168aca712aea16076e971c23835f8ca verweist und Sie technisch an HEAD of no branch ausgecheckt sind. Sie befinden sich also im getrennten HEAD-Zustand.

Theoretische Erklärung

In diesem Blog heißt es eindeutig, dass ein Git-Repository ein Commit-Baum ist, wobei jedes Commit auf seinen Vorfahren verweist, wobei jeder Commit-Zeiger aktualisiert wird und diese Zeiger auf jeden Zweig in den Unterverzeichnissen .git / refs gespeichert werden. Tags werden in .git / refs / tags und Zweige in .git / refs / Heads gespeichert. Wenn Sie sich eine der Dateien ansehen, werden Sie feststellen, dass jedes Tag einer einzelnen Datei mit einem 40-stelligen Commit-Hash entspricht. Wie oben von @Chris Johnsen und @Yaroslav Nikitenko erläutert, können Sie diese Referenzen überprüfen.

Keshav
quelle
0

Ich bin in einen wirklich dummen Zustand geraten, ich bezweifle, dass irgendjemand dies nützlich finden wird ... aber nur für den Fall

git ls-remote origin
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        HEAD
6f96ad0f97ee832ee16007d865aac9af847c1ef6        refs/heads/HEAD
0d2ab882d0dd5a6db93d7ed77a5a0d7b258a5e1b        refs/heads/master

was ich schließlich mit behoben habe

git push origin :HEAD
KCD
quelle
0

Das hat bei mir perfekt funktioniert:

1. git stashum Ihre lokalen Änderungen zu speichern

Wenn Sie Änderungen verwerfen möchten,
git clean -df
git checkout -- .
entfernt git clean alle nicht verfolgten Dateien (Warnung: Ignorierte Dateien, die direkt in .gitignore erwähnt werden, werden möglicherweise nicht gelöscht, ignorierte Dateien in Ordnern werden möglicherweise gelöscht) und git checkout löscht alle nicht bereitgestellten Änderungen.

2. git checkout masterzum Hauptzweig wechseln (vorausgesetzt, Sie möchten Master verwenden)
3. Das git pullletzte Commit aus dem Hauptzweig ziehen
4. git statusum zu überprüfen, ob alles gut aussieht

On branch master
Your branch is up-to-date with 'origin/master'.
jmojico
quelle
0

In meinem Fall lief ich git statusund sah, dass ich einige nicht verfolgte Dateien in meinem Arbeitsverzeichnis hatte.

Damit die Rebase funktioniert, musste ich sie nur reinigen (da ich sie nicht brauchte).

Falsarella
quelle
0

Wenn Sie EGit in Eclipse verwenden: Nehmen Sie an, Ihr Master ist Ihr Hauptentwicklungszweig

  • Übernehmen Sie Änderungen an einem Zweig, normalerweise einem neuen
  • dann von der Fernbedienung ziehen
  • Klicken Sie dann mit der rechten Maustaste auf den Projektknoten, wählen Sie Team und dann Verlauf anzeigen
  • Klicken Sie dann mit der rechten Maustaste auf den Master und wählen Sie Auschecken
  • Wenn Eclipse Ihnen sagt, dass es zwei Master gibt, eine lokale und eine Fernbedienung, wählen Sie die Fernbedienung

Danach sollten Sie wieder mit dem Ursprungsmaster verbunden werden können.

Junchen Liu
quelle
-1

Ich hatte das gleiche Problem. Ich habe meine Änderungen mit gespeichert git stashund den Zweig in local auf ein vorheriges Commit zurückgesetzt (ich dachte, das hat das verursacht), dann habe git pullich ein und ich bekomme diesen Kopf jetzt nicht losgelöst. Vergessen Sie nicht git stash apply, Ihre Änderungen erneut vorzunehmen.

SamL
quelle
-2
git checkout checksum  # You could use this to peek previous checkpoints
git status # You will see HEAD detached at checksum
git checkout master # This moves HEAD to master branch
David Yang
quelle