it-swarm.com.de

git cherry-pick sagt "... 38c74d ist eine Zusammenführung, aber es wurde keine Option -m angegeben"

Ich habe einige Änderungen in meinem Master-Zweig vorgenommen und möchte diese in den Upstream bringen. Wenn ich die folgenden Commits als Kirschpickel auswähle, stecke ich aber auf fd9f578, wo git sagt:

$ git cherry-pick fd9f578
fatal: Commit fd9f57850f6b94b7906e5bbe51a0d75bf638c74d is a merge but no -m option was given.

Was versucht git mir zu sagen und ist Cherry-Pick das Richtige, um hier verwendet zu werden? Der Master-Zweig enthält Änderungen an Dateien, die im Upstream-Zweig geändert wurden. Ich bin sicher, dass es einige Konflikte bei der Zusammenführung geben wird. Ich weiß, welche Änderungen wo nötig sind.

Dies sind die Verpflichtungen, die ich vorwärts bringen möchte.

e7d4cff added some comments...
23e6d2a moved static strings...
44cc65a incorporated test ...
40b83d5 whoops delete whitspace...
24f8a50 implemented global.c...
43651c3 cleaned up ...
068b2fe cleaned up version.c ...
fd9f578 Merge branch 'master' of ssh://extgit/git/sessions_common
4172caa cleaned up comments in sessions.c ...
376
wufoo

Die Art und Weise, wie ein Kirschpickel funktioniert, besteht darin, den Unterschied, den eine Änderungsmenge darstellt (den Unterschied zwischen dem Arbeitsbaum an diesem Punkt und dem Arbeitsbaum des übergeordneten Elements), auf den aktuellen Zweig anzuwenden.

Wenn ein Commit zwei oder mehr Eltern hat, stellt es auch zwei oder mehr Unterschiede dar - welcher sollte angewendet werden?

Du versuchst, fd9f578, einen Zusammenschluss mit zwei Eltern, zu wählen. Sie müssen also dem Cherry-Pick-Befehl mit der -m-Option mitteilen, gegen welchen Befehl der Diff berechnet werden soll. Beispielsweise git cherry-pick -m 1 fd9f578, um übergeordnetes 1 als Basis zu verwenden.

Ich kann für Ihre spezielle Situation nicht sicher sagen, aber die Verwendung von git merge anstelle von git cherry-pick ist generell ratsam. Wenn Sie ein Merge-Commit auswählen, reduziert es all die im übergeordneten Element vorgenommenen Änderungen, die Sie nicht für -m angegeben haben, in das ein Commit . Sie verlieren alle ihre Geschichte und glom all ihre Unterschiede. Ihr Anruf.

464
Borealid

@ Borealids Antwort ist richtig, aber nehmen Sie an, Sie möchten die exakte Zusammenführungshistorie eines Zweigs nicht beibehalten und möchten nur eine linearisierte Version davon auswählen. Hier ist eine einfache und sichere Möglichkeit, dies zu tun:

Ausgangszustand: Sie befinden sich im Zweig X und möchten die Commits Y..Z auswählen.

  1. git checkout -b tempZ Z
  2. git rebase Y
  3. git checkout -b newX X
  4. git cherry-pick Y..tempZ
  5. (optional) git branch -D tempZ

Dies bewirkt, dass ein Zweig tempZ auf der Grundlage von Z erstellt wird, der Verlauf jedoch ab Y linearisiert wird und dann auf einer Kopie von X mit dem Namen newX aufgegriffen wird. (Es ist sicherer, dies auf einem neuen Zweig zu tun, als X zu mutieren.) Natürlich können in Schritt 4 Konflikte auftreten, die Sie auf die übliche Art und Weise lösen müssen (cherry-pick arbeitet in dieser Hinsicht sehr ähnlich wie rebase). Schließlich löscht es den temporären Zweig tempZ.

Wenn in Schritt 2 die Meldung "Current Branch TempZ ist auf dem neuesten Stand" angezeigt wird, war Y..Z bereits linear. Ignorieren Sie diese Nachricht einfach und fahren Sie mit Schritt 3 fort.

Dann newX durchsehen und sehen, ob das getan wurde, was Sie wollten.

(Hinweis: Dies ist nicht gleichbedeutend mit einem einfachen git rebase X in Verzweigung Z, da dies in keiner Weise von der Beziehung zwischen X und Y abhängt; es können Commits zwischen dem gemeinsamen Vorfahren und Y auftreten, die Sie nicht wollten .)

20
Daira Hopwood

Hier ist eine Neufassung der akzeptierten Antwort, die idealerweise die Vorteile/Risiken möglicher Ansätze verdeutlicht:

Sie versuchen, Fd9f578 zu pflücken, was mit zwei Eltern zusammengeführt wurde.

Anstatt eine Zusammenführung mit Kirschen auszuwählen, ist es am einfachsten, die Commits auszuwählen, die Sie eigentlich von jedem Zweig in der Zusammenführung wünschen.

Da Sie bereits zusammengeführt wurden, befinden sich wahrscheinlich alle gewünschten Commits in Ihrer Liste. Wählen Sie die Kirschen direkt aus und Sie müssen sich nicht mit dem Merge-Commit befassen.

erläuterung

Die Art und Weise, wie ein Cherry-Pick funktioniert, besteht darin, den Unterschied, den eine Änderungsmenge darstellt (den Unterschied zwischen dem Arbeitsbaum an diesem Punkt und dem Arbeitsbaum des übergeordneten Elements) zu nehmen, und den Änderungssatz auf Ihren aktuellen Zweig anzuwenden. 

Wenn ein Commit zwei oder mehr Eltern hat, wie dies bei einer Zusammenführung der Fall ist, repräsentiert dieses Commit auch zwei oder mehr Unterschiede. Der Fehler tritt aufgrund der Ungewissheit auf, welcher Unterschied gelten sollte.

alternativen

Wenn Sie feststellen, dass Sie die Zusammenführung im Vergleich zur Kirschpicking-Verknüpfung der zugehörigen Commits verwenden müssen, haben Sie zwei Möglichkeiten:

  1. (Komplizierter und unklarer; verwirft auch den Verlauf) Sie können angeben, welcher Elternteil gelten soll.

    • Verwenden Sie dazu die Option -m. Beispielsweise verwendet git cherry-pick -m 1 fd9f578 das erste in der Zusammenführung aufgelistete übergeordnete Element als Basis.

    • Berücksichtigen Sie auch, dass wenn Sie eine Zusammenführungsübernahme auswählen, all die Änderungen, die Sie im übergeordneten Element vorgenommen haben, die Sie nicht für -m angegeben haben, in one commit reduzieren. Sie verlieren alle ihre Geschichte und glom all ihre Unterschiede. Ihr Anruf.

  2. (Einfacher und bekannter; Historie wird beibehalten) Sie können statt git mergegit cherry-pick verwenden.

    • Wie bei git merge üblich, wird versucht, alle Commits anzuwenden, die in dem Zweig vorhanden sind, den Sie zusammenführen, und sie einzeln in Ihrem Git-Protokoll auflisten.
5
Kay V

-m steht für die übergeordnete Nummer.

Aus dem git doc: 

Normalerweise können Sie keine Zusammenführung auswählen, da Sie nicht wissen, welche Seite der Zusammenführung als Hauptlinie betrachtet werden soll. Diese Option gibt die übergeordnete Nummer (beginnend mit 1) der Hauptlinie an und ermöglicht es Cherry-Pick, die Änderung relativ zu dem angegebenen übergeordneten Element abzuspielen.

Zum Beispiel, wenn Ihr Commit-Baum wie folgt aussieht:

- A - D - E - F -   master
   \     /
    B - C           branch one

dann wird git cherry-pick E das Problem anzeigen, mit dem Sie konfrontiert sind.

git cherry-pick E -m 1 bedeutet die Verwendung von D-E, während git cherry-pick E -m 2 die Verwendung von B-C-E bedeutet.

3
gavincook

Vereinfachung der @Daira-Hopwood-Methode, die sich für ein einzelnes Commit eignet. Brauchen Sie keine temporären Zweige.

Im Falle des Autors:

  • Z wird gesucht (fd9f578) 
  • Y ist davor begehen 
  • X aktueller Arbeitszweig

dann mach:

git checkout Z   # move HEAD to wanted commit
git reset Y      # have Z as changes in working tree
git stash        # save Z in stash
git checkout X   # return to working branch
git stash pop    # apply Z to current branch
git commit -a    # do commit
0
ephemerr