git cherry-pick
Lerne den Befehl git cherry-pick kennen: einzelne Commits zwischen Branches kopieren, Konflikte lösen und Optionen nutzen.
Was git cherry-pick macht
Der Befehl git cherry-pick übernimmt die Änderung eines oder mehrerer vorhandener Commits und wendet sie auf deinen aktuellen Branch als neuen Commit an. Während git merge und git rebase ganze Historienlinien auf einmal verschieben, erlaubt cherry-pick, einen einzelnen Commit zu greifen und ihn genau dort einzufügen, wo du ihn brauchst.
Diese Seite erklärt, wie cherry-pick intern funktioniert, wie du einen einzelnen Commit oder einen Bereich auswählst, welche Optionen du wirklich benötigst, wie du Konflikte löst und wann du cherry-pick statt einem Merge oder git revert einsetzen solltest.
So funktioniert es
Ein Commit ist ein Snapshot, aber cherry-pick behandelt ihn als Patch: Es berechnet den Diff zwischen dem Commit und seinem Eltern-Commit, wendet diesen Diff auf die Spitze des aktuellen Branches an und erzeugt einen neuen Commit. Der neue Commit behält die originale Nachricht, den Autor und das Datum, erhält jedoch einen neuen Hash und einen neuen Eltern-Commit, da er nun an einer anderen Stelle in der Historie liegt.
Dieser Unterschied ist das zentrale Konzept: cherry-pick kopiert eine Änderung, verschiebt sie nicht. Der Quell-Commit bleibt unverändert auf seinem ursprünglichen Branch.
git switch main
git cherry-pick a1b2c3dDie Änderung aus Commit a1b2c3d befindet sich nun als neuer Commit auf main.
Ein konkretes Beispiel
Angenommen, ein Hotfix wurde auf feature committet, gehört aber eigentlich auf main. Suche zuerst den Commit-Hash mit git log:
git switch feature
git log --oneline
# d9ae654 fix login redirect
# 7c1a902 work in progress
# fa42ab5 baseWechsle nun zu main und kopiere nur diesen einen Commit:
git switch main
git cherry-pick d9ae654[main 02bbf3e] fix login redirect
1 file changed, 1 insertion(+)Beachte den neuen Hash 02bbf3e — der Fix befindet sich jetzt auf main als brandneuer Commit, während d9ae654 unverändert auf feature weiterexistiert.
Einen Bereich von Commits auswählen
Du kannst mehrere Commits auf einmal anwenden. Ein Bereich kopiert jeden Commit nach dem ersten bis einschließlich des letzten:
git cherry-pick a1b2c3d..f4e5d6cDabei wird a1b2c3d selbst ausgeschlossen. Um den Bereich so zu machen, dass der Startcommit einbezogen wird, füge das Suffix ^ hinzu, damit der Bereich beim Eltern-Commit beginnt:
git cherry-pick a1b2c3d^..f4e5d6cDie Commits werden der Reihe nach einzeln angewendet. Entsteht bei einem Commit ein Konflikt, hält cherry-pick dort an, damit du ihn beheben kannst, bevor du fortfährst.
Häufig genutzte Optionen
| Befehl | Beschreibung |
|---|---|
git cherry-pick <commit> | Wendet die Änderung aus <commit> als neuen Commit auf den aktuellen Branch an. |
git cherry-pick -n <commit> | Wendet die Änderung an, committet aber nicht, sodass du sie überprüfen oder anpassen kannst. |
git cherry-pick -x <commit> | Fügt eine Zeile (cherry picked from commit …) zur Nachricht hinzu – praktisch bei öffentlichen Branches, um die Herkunft nachvollziehen zu können. |
git cherry-pick -e <commit> | Öffnet deinen Editor, damit du die Commit-Nachricht vor der Aufzeichnung ändern kannst. |
git cherry-pick --continue | Setzt die Operation fort, nachdem du Konflikte aufgelöst hast. |
git cherry-pick --skip | Überspringt den aktuellen Commit (z. B. wenn seine Änderung bereits vorhanden ist) und fährt fort. |
git cherry-pick --abort | Bricht die Operation ab und stellt den Branch in seinen ursprünglichen Zustand zurück. |
Mit -x sieht die aufgezeichnete Nachricht so aus:
fix login redirect
(cherry picked from commit d9ae65426adbde425c3e386a32297e9e833d8816)Konflikte behandeln
Wenn die Änderung nicht sauber angewendet werden kann, hält cherry-pick ähnlich wie ein Merge an und hinterlässt Konfliktmarker in den betroffenen Dateien. Du siehst:
CONFLICT (content): Merge conflict in app.js
error: could not apply d9ae654... fix login redirect
hint: ... fix conflicts and then run "git cherry-pick --continue".Löse die Konflikte in den betroffenen Dateien manuell, stage sie mit git add und fahre dann fort:
git add app.js
git cherry-pick --continueAn diesem Punkt stehen drei Auswege zur Verfügung:
git cherry-pick --continue— abschließen, nachdem Konflikte aufgelöst wurden.git cherry-pick --skip— den aktuellen Commit verwerfen und zum nächsten im Bereich übergehen.git cherry-pick --abort— vollständig abbrechen und den Branch zurücksetzen.
Verwende git status jederzeit, um zu sehen, welche Dateien noch Konflikte aufweisen.
Wann du es verwenden solltest
Cherry-pick eignet sich besonders, wenn:
- Ein Fix auf dem falschen Branch gelandet ist und du ihn woanders benötigst.
- Du einen einzelnen Patch rückportierst auf einen Release- oder Wartungs-Branch.
- Du einen einzelnen Commit aus einem Feature-Branch möchtest, ohne den gesamten Branch zu mergen.
Cherry-pick vs. merge, rebase und revert
| Ziel | Verwende |
|---|---|
| Einen (oder wenige) spezifische Commits auf einen anderen Branch kopieren | git cherry-pick |
| Die gesamte Historie eines Branches integrieren | git merge |
| Die Commits eines Branches auf eine neue Basis verschieben | git rebase |
| Einen Commit durch einen entgegengesetzten Commit rückgängig machen | git revert |
Fallstricke
- Duplikate in gemeinsamer Historie. Wenn du cherry-pick auf einen Branch anwendest, der später wieder in den Quell-Branch gemergt wird, entstehen zwei Commits mit derselben Änderung. Git ist meist clever genug, das Duplikat beim Merge zu übergehen, aber es kann die Historie verkomplizieren — bevorzuge Merge oder Rebase, wenn du den gesamten Branch möchtest.
- Leere Ergebnisse. Wenn die Änderung auf dem Ziel-Branch bereits vorhanden ist, hält cherry-pick mit
The previous cherry-pick is now emptyan. Verwendegit cherry-pick --skip, um fortzufahren, oder--abort, um abzubrechen. - Neuer Hash, nicht der ursprüngliche. Da der Commit neu erstellt wird, ändert sich sein Hash. Füge
-xhinzu, damit die Nachricht festhält, woher er stammt.