← Zurück zum Blog

Git cherry-pick erklärt: wann Sie es nutzen (und wann nicht)

tutorial git

Was ist Git Cherry-Pick?

Ein kritischer Bugfix ist gerade auf Ihrer Entwicklungs-Branch gelandet -- aber derselbe Bug ist auch in Produktion. Sie können nicht die gesamte Entwicklungs-Branch in die Release-Branch mergen, denn sie ist voller halbfertiger Features. Was Sie wirklich brauchen: genau diesen einen Commit nehmen und woanders anwenden. Genau das macht git cherry-pick.

Cherry-Picking nimmt die Änderungen eines bestehenden Commits und spielt sie auf Ihrer aktuellen Branch als brandneuen Commit ein. Der neue Commit enthält denselben Diff und standardmäßig dieselbe Message, hat aber einen anderen Parent und damit einen anderen SHA. Dieses Detail ist wichtiger, als es scheint: Git identifiziert Commits über ihren SHA, also enthält Ihr Repository nach einem Cherry-Pick zwei verschiedene Commits, die zufällig dieselbe Änderung einführen. Behalten Sie das im Hinterkopf -- es erklärt sowohl, warum Cherry-Pick so nützlich ist, als auch, warum übermäßiger Einsatz später Probleme verursacht.

Wann Cherry-Pick das richtige Werkzeug ist

Einen Hotfix auf eine Release-Branch zurückportieren

Das ist der Klassiker. Sie haben einen Bug auf main behoben, aber Ihre Nutzer verwenden Version 2.3 und brauchen den Fix sofort. Cherry-picken Sie den Fix auf die Release-Branch:

git switch release/2.3
git cherry-pick a1b2c3d

Die Release-Branch bekommt genau diesen Fix, und nichts anderes von main kommt ungewollt mit.

Ein Commit ist auf der falschen Branch gelandet

Sie wollten auf Ihrer Feature-Branch committen, waren aber auf main. Cherry-Pick bietet einen sauberen Ausweg: Wechseln Sie auf die Branch, wo der Commit hingehört, cherry-picken Sie ihn dort, und entfernen Sie ihn anschließend von der Branch, auf der er nichts zu suchen hat. Wenn Sie sich beim Entfernen unsicher sind: Unser Leitfaden, wie man einen Git-Commit rückgängig macht, erklärt jede Option im Detail.

Einen Fix aus einer aufgegebenen Branch retten

Manchmal führt ein Experiment ins Leere, aber ein Commit mitten in der Branch hat einen echten Bug behoben. Statt eine Sackgassen-Branch zu mergen, cherry-picken Sie den einen wertvollen Commit auf Ihre aktive Branch und lassen den Rest des Experiments in Frieden gelöscht werden.

Grundlegende Verwendung

Die einfachste Form nimmt einen einzelnen Commit:

git cherry-pick a1b2c3d

Git wendet die Änderungen dieses Commits an und erstellt sofort einen neuen Commit auf Ihrer aktuellen Branch, wobei die ursprüngliche Message wiederverwendet wird. Sie können auch mehrere Commits auf einmal angeben, und Git wendet sie nacheinander an, in der Reihenfolge, in der Sie sie auflisten:

git cherry-pick a1b2c3d f4e5d6c

Praktische Optionen, die Sie kennen sollten

-x: die Herkunft des Commits festhalten

Beim Zurückportieren wollen Sie später wissen, woher ein Commit stammt. Die Option -x hängt eine Zeile wie (cherry picked from commit a1b2c3d...) an die Message des neuen Commits an:

git cherry-pick -x a1b2c3d

Machen Sie das zur Gewohnheit bei jedem Cherry-Pick zwischen langlebigen öffentlichen Branches. In sechs Monaten verrät Ihnen diese eine Zeile sofort, ob ein Fix es in ein Release geschafft hat und woher er kam.

Einen Bereich von Commits übernehmen

Mit der Zwei-Punkte-Syntax können Sie einen ganzen Bereich cherry-picken:

git cherry-pick A..B

Vorsicht: Das wendet die Commits nach A an, bis einschließlich B. A selbst ist ausgeschlossen. Wenn A enthalten sein soll, schreiben Sie:

git cherry-pick A^..B

Das ^ bedeutet "der Parent von A", wodurch A wieder im Bereich enthalten ist. Diese beiden Syntaxen zu verwechseln ist einer der häufigsten Cherry-Pick-Fehler.

--no-commit: anwenden ohne zu committen

Manchmal wollen Sie die Änderungen, aber keinen automatischen Commit -- etwa um mehrere übernommene Commits zu einem einzigen zusammenzufassen oder das Ergebnis vor dem Committen anzupassen:

git cherry-pick --no-commit a1b2c3d

Die Änderungen landen in Ihrem Arbeitsverzeichnis und in der Staging-Area, und Sie erstellen den Commit selbst, wenn Sie bereit sind.

Konflikte während eines Cherry-Picks behandeln

Ein Cherry-Pick kann aus demselben Grund Konflikte erzeugen wie ein Merge: Der Commit, den Sie übernehmen, wurde gegen Code geschrieben, der anders aussieht als Ihre aktuelle Branch. In diesem Fall stoppt Git mitten in der Operation und markiert die Dateien mit Konflikten:

error: could not apply a1b2c3d... fix login timeout
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue"

Sie haben jetzt drei Auswege:

  • git cherry-pick --continue -- nachdem Sie die Konfliktdateien bearbeitet und mit git add in die Staging-Area aufgenommen haben, schließt dieser Befehl den Cherry-Pick ab und erstellt den Commit.
  • git cherry-pick --abort -- bricht die gesamte Operation ab und versetzt Ihre Branch exakt in den Zustand zurück, in dem sie vor dem Start war. Nichts geht verloren, nichts wird angewendet.
  • git cherry-pick --skip -- überspringt beim Übernehmen mehrerer Commits den aktuellen und macht mit dem nächsten weiter. Nützlich, wenn sich ein Commit im Bereich als bereits angewendet oder irrelevant herausstellt.

Das Auflösen der Konflikte selbst funktioniert genau wie bei einem Merge-Konflikt: Öffnen Sie jede Konfliktdatei, wählen Sie zwischen den konkurrierenden Hunks (oder kombinieren Sie sie), entfernen Sie die Konfliktmarker und nehmen Sie die Datei in die Staging-Area auf. Wenn Konfliktmarker noch einschüchternd wirken: Unsere Anleitung zum visuellen Auflösen von Git-Merge-Konflikten gilt auch für Cherry-Picks.

Was Sie mit Cherry-Pick NICHT tun sollten

Cherry-picken Sie keine ganzen Branches

Wenn Sie sich dabei ertappen, fünf, zehn, zwanzig Commits von einer Branch auf eine andere zu cherry-picken: Stopp. Dafür gibt es merge und rebase. Beide bewegen Arbeit zwischen Branches, während Git die Beziehung zwischen ihnen versteht, was zukünftige Operationen einfach und konfliktfrei hält. Wenn Sie unsicher sind, welches von beiden zu Ihrem Workflow passt, geht unser Vergleich rebase vs merge die Abwägungen durch.

Duplizierte Historie rächt sich später

Denken Sie daran: Ein Cherry-Pick erstellt einen neuen Commit mit neuem SHA, und Git hält nirgendwo formal fest, dass beide Commits "dieselbe Änderung" darstellen. Wenn Sie Commits von einer Feature-Branch nach main cherry-picken und die Feature-Branch später trotzdem mergen, muss Git zwei Kopien derselben Änderungen miteinander vereinbaren. Oft gelingt das stillschweigend. Aber sobald eine der Kopien nachträglich verändert wurde, bekommen Sie verwirrende Konflikte, bei denen beide Seiten fast identisch aussehen -- und Ihre Historie zeigt dieselbe Änderung zweimal, mit zwei Daten und zwei SHAs, was Werkzeuge wie git log und git bisect schwerer nachvollziehbar macht.

Eine gute Faustregel: Cherry-Pick ist für Ausnahmen da -- ein Hotfix, ein verirrter Commit, ein geretteter Fix. Sobald es zu Ihrer Routinemethode wird, Arbeit zwischen Branches zu bewegen, sagt Ihnen Ihre Historie, dass die Branching-Strategie überdacht werden sollte.

Cherry-Picking in GitSquid

In GitSquid finden Sie Cherry-Pick genau dort, wo Sie es erwarten würden: Rechtsklick auf einen beliebigen Commit im Commit-Graphen, dann die Cherry-Pick-Option im Kontextmenü wählen. Kein Hin- und Herkopieren von SHAs zwischen Log und Terminal.

Der größere Gewinn ist zu wissen, worauf Sie sich einlassen. GitSquids Conflict Predictor -- kostenlos für alle -- zeigt exakt, welche Dateien Konflikte verursachen werden, bevor Sie einen Merge, Rebase oder Cherry-Pick ausführen, mit Hunk-Vorschauen und Syntax-Highlighting. Statt Konflikte mitten in einer Operation zu entdecken, sehen Sie sie vorab und können entscheiden, ob Sie fortfahren, einen anderen Commit wählen oder die Auflösung in Ruhe vorbereiten.

Und wenn ein Pick doch Konflikte erzeugt, öffnet "Resolve in scratch worktree" einen temporären Worktree als neuen Tab, sodass Sie alles dort auflösen können, während Ihr aktiver Checkout unberührt bleibt.

Schnellreferenz

Befehl Was er macht
git cherry-pick <sha> Einen Commit auf die aktuelle Branch anwenden
git cherry-pick <sha1> <sha2> Mehrere Commits der Reihe nach anwenden
git cherry-pick -x <sha> Den Quell-SHA an die Commit-Message anhängen
git cherry-pick A..B Commits nach A bis B übernehmen (A ausgeschlossen)
git cherry-pick A^..B Den Bereich einschließlich A übernehmen
git cherry-pick --no-commit <sha> Die Änderungen anwenden, ohne zu committen
git cherry-pick --continue Den Pick nach der Konfliktauflösung abschließen
git cherry-pick --abort Abbrechen und die Branch wiederherstellen
git cherry-pick --skip Aktuellen Commit überspringen, mit dem Rest fortfahren

Cherry-Pick ist ein Skalpell, keine Schaufel. Für die gelegentliche präzise Extraktion eingesetzt -- ein Hotfix-Backport, ein verirrter Commit, ein geretteter Fix -- ist es einer der befriedigendsten Befehle in Git. Als Ersatz fürs Mergen verwendet, füllt es Ihre Historie still mit Duplikaten, die später zurückkommen, um Sie heimzusuchen. Kennen Sie den Unterschied, fügen Sie beim Zurückportieren -x hinzu und behalten Sie --abort als Notausgang im Hinterkopf.

Möchten Sie sehen, welche Dateien Konflikte verursachen, bevor Sie überhaupt anfangen? Laden Sie GitSquid kostenlos herunter und lassen Sie den Conflict Predictor das Rätselraten aus Ihrem nächsten Cherry-Pick nehmen.