Git und "Der Zweig 'x' ist nicht vollständig zusammengeführt" Fehler

294

Hier sind die Befehle, die ich vom Hauptzweig verwendet habe

git branch experiment
git checkout experiment

Dann habe ich einige Änderungen an meinen Dateien vorgenommen, die Änderungen festgeschrieben und den neuen Zweig an GitHub gesendet.

git commit . -m 'changed files'
git push -u origin experiment

Später beschloss ich, meinen Experimentierzweig mit dem Hauptzweig zusammenzuführen.

git checkout master
git merge experiment

Schließlich habe ich die Änderungen an GitHub übertragen.

git push -u origin master

Alles lief gut, bis ich versuchte, meinen Experimentzweig mit zu löschen

git branch -d experiment

Ich habe die Fehlermeldung erhalten, dass error: The branch 'experiment' is not fully merged.ich ein bisschen neu in Git bin, und ich weiß nicht, wie viel mehr ich möglicherweise die beiden Zweige zusammenführen könnte. Was vermisse ich hier?

Mellowsoon
quelle
2
Hilft Ihnen dieser Beitrag? stackoverflow.com/questions/1710894/…
Chrisdigital
2
Dies kommt manchmal vor, wenn ich eingit commit --amend
Arcolye
12
Auch - Beachten Sie, dass diese Nachricht nach einem squash: stackoverflow.com/q/41946475/109941
Jim G.
Ich denke, das häufigste Szenario ist, dass Sie nur Ihre neu zusammengeführten Änderungen abrufen müssen, bevor Sie den Zweig lokal löschen.
RaisinBranCrunch

Antworten:

313

Hinweis Der Wortlaut wurde aufgrund der Kommentare geändert. Danke @slekse
Das ist kein Fehler, es ist eine Warnung. Dies bedeutet, dass der Zweig, den Sie löschen möchten, Commits enthält, die von keinem der folgenden Bereiche erreichbar sind: dem Upstream-Zweig oder HEAD (derzeit ausgecheckte Revision). Mit anderen Worten, wenn Sie Commits verlieren könnten¹.

In der Praxis bedeutet dies, dass Sie Commits wahrscheinlich geändert, neu basiert oder gefiltert haben und sie nicht identisch zu sein scheinen .

Daher können Sie die Warnung vermeiden, indem Sie einen Zweig auschecken , der die Commits enthält, die Sie nicht referenzieren möchten, indem Sie diesen anderen Zweig löschen.²

Sie sollten sicherstellen, dass Sie tatsächlich keine wichtigen Commits verpassen:

git log --graph --left-right --cherry-pick --oneline master...experiment

Dadurch erhalten Sie eine Liste aller zwischen den Zweigen nicht freigegebenen Elemente. Wenn Sie neugierig sind, gibt es möglicherweise einen Unterschied ohne --cherry-pickund dieser Unterschied könnte der Grund für die Warnung sein, die Sie erhalten:

--cherry-pick

Lassen Sie jedes Commit aus, das dieselbe Änderung wie ein anderes Commit auf der "anderen Seite" einführt, wenn die Anzahl der Commits mit symmetrischen Unterschieden begrenzt ist. Wenn Sie beispielsweise zwei Zweige haben, A und B, können Sie alle Festschreibungen normalerweise nur auf einer Seite auflisten - links - rechts, wie im obigen Beispiel in der Beschreibung dieser Option. Es werden jedoch die Commits angezeigt, die aus dem anderen Zweig ausgewählt wurden (z. B. kann "3rd on b" aus Zweig A ausgewählt werden). Mit dieser Option werden solche Commit-Paare von der Ausgabe ausgeschlossen.


¹ Sie sind standardmäßig nur Müll, der nach einer Weile gesammelt wird. Außerdem git-branchüberprüft der Befehl nicht den Revisionsbaum aller Zweige . Die Warnung soll offensichtliche Fehler vermeiden.

² (Ich bevorzuge es, stattdessen nur das Löschen zu erzwingen, aber Sie möchten möglicherweise die zusätzliche Sicherheit haben).

sehe sehen
quelle
24
Vielen Dank. Der Schlüsselbegriff lautete "enthält Commits, die von keinem anderen Ref-Kopf aus erreichbar sind". Obwohl ich den Experimentzweig nicht mehr brauchte und ihn bereits in master zusammengeführt hatte und vorhatte, ihn aus dem Ursprung zu löschen, würde git nicht glücklich sein, bis ich die Änderungen an experiment auf origin verschoben hatte. Ich denke, diese Warnung war eine Art Überprüfung der geistigen Gesundheit.
Mellowsoon
35
-1 "Dies bedeutet, dass der Zweig, den Sie löschen möchten, Commits enthält, die von keinem anderen Referenzkopf aus erreichbar sind." Das ist nicht richtig. Die Warnung bedeutet, dass der Zweig weder von seinem Upstream (falls vorhanden) noch vom aktuellen HEAD aus erreichbar ist. Siehe Manpage von Git-Branch.
Sleske
3
@TachyonVortex Netter Link. Der Befehl git branch -vv hat wirklich klargestellt, was für mich los war.
Jason Massey
11
@sleske Danke für den Kommentar - diese Antwort sollte wirklich bearbeitet werden. Es ist eine Schande, dass es sehr positiv bewertet wird, weil der wichtigste erklärende Satz falsch ist. Ich hatte gerade dieses Problem und verbrachte eine ärgerlich lange Zeit damit, herauszufinden, was das Problem war, und es war nur so, dass der Fernverfolgungszweig als Teil der Pull-Anforderung gelöscht worden war und in der Zeit, seit ich Änderungen vom Master abgerufen hatte auf der lokalen Niederlassung. Das einzige Problem bestand darin, den gelöschten Remote-Tracking-Zweig nicht zu finden (und ich habe aus demselben Grund versucht, den lokalen Zweig zu löschen).
Ely
3
Ja, dies kann nur passieren, wenn Sie versuchen, einen lokalen Zweig zu löschen, wenn Sie sich in einem anderen Zweig befinden als dem, in dem Sie ihn erstellt haben. "Commits, die von keinem anderen Schiedsrichter aus erreichbar sind" ist falsch und unnötig beängstigend!
Amalgovinus
80

Wie Drew Taylor betonte, berücksichtigt das Löschen von Zweigen mit -d nur den aktuellen HEAD, um festzustellen, ob der Zweig "vollständig zusammengeführt" ist. Es wird sich beschweren , auch wenn der Zweig ist mit einem anderen Zweig verschmolzen. Die Fehlermeldung könnte in dieser Hinsicht definitiv klarer sein ... Sie können entweder den zusammengeführten Zweig vor dem Löschen auschecken oder einfach den Git-Zweig -D verwenden. Das Großbuchstaben -D überschreibt den Scheck vollständig.

drwowe
quelle
2
Der Teil über den aktuellen HEAD hat das für mich behoben. Mein Master war anders als der Feature-Zweig, von dem ich den widersprüchlichen Zweig erstellt habe: D
viki.omega9
1
Für jemanden, der Git lernt, scheint das Wort "aktuell" mit "KOPF" überflüssig zu sein? Es gibt nicht so etwas wie eine uncurrent HEAD - das HEAD definitionsgemäß ist der aktuelle Zweig. Vermisse ich etwas Ich nehme an, Sie könnten "aktueller Zweig" oder "KOPF" sagen, aber nicht "aktueller KOPF".
Mark Lakata
Gibt es eine Möglichkeit, dies zu ändern / zu konfigurieren (z. B. immer prüfen origin/master?) Ich denke, das Auschecken origin/masterzuerst ist nicht zu lästig, aber es fühlt sich einfach wie ein seltsamer Ablauf an - warum muss ich origin/masterlokal auschecken Nur damit Sie überprüfen können, ob meine Änderungen dort zusammengeführt werden?
Alec
15

Ich habe die Antwort von sehe ausprobiert und es hat nicht funktioniert.

Um die Commits zu finden, die nicht zusammengeführt wurden, verwenden Sie einfach:

git log feature-branch ^master --no-merges
qwertzguy
quelle
14

Das ist mir heute passiert, als ich meinen ersten Feature-Zweig wieder in Master zusammenführte. Wie einige in einem Thread an anderer Stelle auf SO sagten, bestand der Trick darin, wieder zum Master zu wechseln, bevor versucht wurde, den Zweig zu löschen. Als Git wieder im Master war, war es glücklich, den Zweig ohne Warnungen zu löschen.

Drew Taylor
quelle
7
Sieht nicht so aus, als wäre das hier das spezifische Problem, aber ich bin auf das Problem gestoßen, das Sie gerade beschrieben haben, also danke!
Daniel Buckmaster
4

Git warnt Sie, dass Sie möglicherweise den Verlauf verlieren, wenn Sie diesen Zweig löschen. Auch wenn keine Commits sofort gelöscht werden, sind einige oder alle Commits in der Verzweigung nicht mehr erreichbar, wenn sie nicht auch Teil einer anderen Verzweigung sind.

Damit der Zweig experimentvollständig mit einem anderen Zweig zusammengeführt werden kann, muss sein Tip-Commit ein Vorfahr des Tip des anderen Zweigs sein, sodass die Commits in experimenteiner Teilmenge des anderen Zweigs ausgeführt werden. Dies macht das Löschen sicher experiment, da alle Commits über den anderen Zweig Teil des Repository-Verlaufs bleiben. Es muss "vollständig" zusammengeführt werden, da es möglicherweise bereits mehrmals zusammengeführt wurde, aber jetzt seit der letzten Zusammenführung Commits hinzugefügt wurden, die nicht in der anderen Verzweigung enthalten sind.

Git überprüft jedoch nicht jeden anderen Zweig im Repository. nur zwei:

  1. Der aktuelle Zweig (HEAD)
  2. Der vorgelagerte Zweig, falls vorhanden

Die "Upstream-Niederlassung" für experiment, wie in Ihrem Fall, ist wahrscheinlich origin/experiment. Wenn experimentder aktuelle Zweig vollständig zusammengeführt ist, löscht Git ihn ohne Beanstandung. Wenn dies nicht der Fall ist, es jedoch vollständig in seinem Upstream-Zweig zusammengeführt ist, fährt Git mit einer Warnung fort, die wie folgt aussieht:

warning: deleting branch 'experiment' that has been merged
to 'refs/remotes/origin/experiment', but not yet merged to
HEAD.
Deleted branch experiment (was xxxxxxxx).

Wobei xxxxxxxxeine Commit-ID angibt. Eine vollständige Zusammenführung im Upstream zeigt an, dass die Commits in experimentdas Ursprungs-Repository verschoben wurden, sodass sie, selbst wenn Sie sie hier verlieren, zumindest an anderer Stelle gespeichert werden können.

Da Git andere Zweige nicht überprüft, kann es sicher sein, einen Zweig zu löschen, da Sie wissen, dass er vollständig mit einem anderen zusammengeführt ist. Sie können dies mit der angegebenen -DOption tun oder zuerst zu diesem Zweig wechseln und Git den vollständig zusammengeführten Status für Sie bestätigen lassen.

troore
quelle
1
Der Schlüssel ist "vollständig im aktuellen Zweig zusammengeführt". Ich hatte einen Zweig X 'von X vollständig wieder in X zusammengeführt und hatte bereits origin / X' gelöscht. Aber als Y ausgecheckt war, bekam ich diese Warnung. Beim Auschecken konnte XI X 'löschen. Es ist ziemlich dumm, denke ich.
Lawrence Dol
2
Diese Antwort wird von hier ohne Namensnennung plagiiert chimera.labs.oreilly.com/books/1230000000561/…
Mark Lakata
3

Um Änderungen zu sehen, die nicht zusammengeführt werden, habe ich Folgendes getan:

git checkout experiment
git merge --no-commit master

git diff --cached

Hinweis: Dies zeigt Änderungen an master, die nicht in sind experiment.

Vergiss nicht:

git merge --abort

Wenn du fertig bist, schau.

ThorSummoner
quelle
@IgorGanapolsky Keine Ahnung, obwohl normalerweise man git-resetund die Befehle zum Zurücksetzen von Git ausreichen, um sich von Statusproblemen zu erholen.
ThorSummoner
3

Einfachste Lösung mit Erklärung (doppelt überprüfte Lösung) (das Problem war zuvor aufgetreten)

Das Problem ist:

1- Ich kann keinen Zweig löschen

2- Das Terminal zeigt weiterhin eine Warnmeldung an, dass einige Commits noch nicht genehmigt wurden

3- wissend, dass ich den Master und den Zweig überprüft habe und sie identisch sind (aktuell)

Lösung:

git checkout master
git merge branch_name
git checkout branch_name
git push
git checkout master
git branch -d branch_name

Erläuterung:

Wenn Ihr Zweig mit einem vorgelagerten Remote-Zweig verbunden ist (auf Github, Bitbucket oder was auch immer), müssen Sie ihn in den Master einbinden (pushen) und die neuen Änderungen (Commits) in das Remote-Repo (Github, Bitbucket oder was auch immer) aus der Filiale,

Was ich in meinem Code getan habe, ist, dass ich zum Master gewechselt bin, dann den Zweig darin zusammengeführt habe (um sicherzustellen, dass sie auf Ihrem lokalen Computer identisch sind), dann habe ich wieder zum Zweig gewechselt und die Aktualisierungen oder Änderungen online in die Fernbedienung übertragen Repo mit "Git Push".

Danach wechselte ich wieder zum Master und versuchte, den Zweig zu löschen. Das Problem (Warnmeldung) verschwand und der Zweig wurde erfolgreich gelöscht

Elta3lab
quelle
3

Sie können einfach herausfinden:

Git Log --cherry Master ... experimentell

--cherry Option ist ein Synonym für --right-only --cherry-mark --no-merges

git-log manpage sagte

Es ist nützlich, die Ausgabe auf die Commits auf unserer Seite zu beschränken und diejenigen, die auf die andere Seite eines gegabelten Verlaufs angewendet wurden, mit git log --cherry upstream ... mybranch zu markieren, ähnlich wie git cherry upstream mybranch.

Zu Ihrer Information. --cherry-picklässt gleichwertige Commits aus, --cherry-markstut dies aber nicht. Es ist nützlich, Rebase zu finden und aktualisierte Änderungen zwischen vorgelagerten und kooperierenden öffentlichen Zweigen zu erzwingen

Yongbin
quelle
1

Ich hatte keinen Upstream-Zweig auf meinem lokalen Git. Ich hatte eine lokale Niederlassung von Master, Git Checkout -b Mybranch erstellt. Ich habe einen Zweig mit Bitbucket-GUI auf dem Upstream-Git erstellt und meinen lokalen Zweig (mybranch) auf diesen Upstream-Zweig verschoben. Sobald ich einen Git-Abruf für meinen lokalen Git durchgeführt habe, um den Upstream-Zweig abzurufen, konnte ich einen Git-Zweig -d Mybranch erstellen.

edW
quelle
0

Ich glaube, die Flagge --forceist das, wonach Sie wirklich suchen. Verwenden Sie einfach git branch -d --force <branch_name>, um den Zweig zwangsweise zu löschen.

Sergey Samoylenko
quelle