git cherry-pick
Änderungen bestimmter Commits auf den aktuellen Branch anwenden
Der Befehl 'git cherry-pick' wendet die Änderungen eines oder mehrerer vorhandener Commits auf den aktuellen Branch an und erzeugt für jeden einen neuen Commit. Anders als merge oder rebase, die mit ganzen Branches arbeiten, kopiert cherry-pick gezielt einzelne Commits. Das ist unbezahlbar, um Hotfixes auf Release-Branches zurückzuportieren, verlorene Commits zu retten oder bestimmte Features von einem Branch auf einen anderen zu bringen, ohne alles zu mergen. Jeder cherry-gepickte Commit bekommt einen neuen SHA – es ist eine Kopie, kein Verschieben. Cherry-pick arbeitet chirurgisch präzise und gibt dir feine Kontrolle darüber, welche Änderungen auf deinem Branch landen.
Syntax
git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] [-S[<keyid>]] <commit>...
git cherry-pick (--continue | --skip | --abort | --quit)Optionen
Die richtige Option wählen
git cherry-pick im Vergleich mit verwandten Befehlen
Verstehen, wann cherry-pick statt merge, rebase oder revert passt
| Befehl | Aspekt | Cherry-Pick | Anderer Befehl |
|---|---|---|---|
Scope | Nur bestimmte Commits | Merge: ganzer Branch / Rebase: ganzer Branch | |
Creates new commits | Ja – neuer SHA, gleicher Inhalt | Merge: Merge-Commit / Rebase: schreibt alles um | |
Original stays | Ja – Original unberührt | Merge: ja / Rebase: verwaist | |
Use case | Backports, gezieltes Portieren | Ganze Branches integrieren | |
History effect | Erzeugt doppelte Änderungen | Bewahrt oder linearisiert | |
Conflicts | Pro Commit während des Picks | Am Merge-Punkt oder pro Rebase-Commit |
Workflow-Beispiele
git checkout release-1.0Auf den Release-Branch wechseln
git log main --onelineDen Commit-Hash des Fixes finden
git cherry-pick -x abc123Den Fix mit Herkunftsverweis anwenden
git push origin release-1.0Den zurückportierten Fix pushen
git checkout mainAuf den Branch main wechseln
git log feature --onelineCommits auf dem Feature-Branch prüfen
git cherry-pick abc123 def456Nur die fertigen Commits picken
git push origin mainDie ausgewählten Commits pushen
git reflogDen Commit-Hash im Reflog finden
git checkout mainAuf den Ziel-Branch wechseln
git cherry-pick abc123Den verwaisten Commit anwenden
git checkout target-branchAuf den Ziel-Branch wechseln
git cherry-pick A^..CCommits A bis C (einschließlich) anwenden
git log --onelinePrüfen, dass die Commits angewendet wurden
Fehlerbehebung
"commit is a merge but no -m option was given"
Ursache: Du versuchst, einen Merge-Commit zu cherry-picken, ohne den Elternteil anzugeben
Gib mit -m 1 oder -m 2 den Hauptlinien-Elternteil an
git cherry-pick -m 1 <merge-commit>Konflikte beim Cherry-Pick
Ursache: Die Änderungen kollidieren mit deinem aktuellen Branch
Löse die Konflikte in den Dateien, führe git add aus, dann git cherry-pick --continue. Oder brich mit --abort ab
git add <resolved-files> && git cherry-pick --continue"The previous cherry-pick is now empty"
Ursache: Die Änderungen des Commits sind schon in deinem Branch
Führe 'git commit --allow-empty' aus, um ihn trotzdem festzuhalten, oder 'git cherry-pick --skip', um ihn zu überspringen
git cherry-pick --skipCherry-pick hat doppelte Commits erzeugt
Ursache: Dieselben Änderungen existieren jetzt als verschiedene Commits auf verschiedenen Branches
Das ist erwartetes Verhalten. Nutze die Option -x, um die Beziehung zu dokumentieren
git cherry-pick -x <commit>Der falsche Commit wurde cherry-gepickt
Ursache: Den falschen Commit-SHA gewählt
Wenn nicht gepusht: git reset --hard HEAD~1. Wenn gepusht: git revert auf den cherry-gepickten Commit
git reset --hard HEAD~1Cherry-pick scheint nichts zu bewirken
Ursache: Der Commit ist vielleicht leer oder seine Änderungen sind schon angewendet
Sieh mit git diff HEAD~1 nach, was sich tatsächlich geändert hat
git diff HEAD~1Tipps & Stolperfallen
Best Practices
- ✓Nutze -x bei Backports, um den Verweis '(cherry picked from commit ...)' in die Commit-Nachricht zu schreiben
- ✓Cherry-picke in chronologischer Reihenfolge – abhängige Commits müssen vom ältesten zum neuesten angewendet werden, um Konflikte zu vermeiden
- ✓Nutze bei geteilten Branches lieber merge – cherry-pick erzeugt doppelte Commits, merge bewahrt die Historie
- ✓Teste nach dem Cherry-Pick – der Commit kann im ursprünglichen Kontext funktionieren und im neuen scheitern
- ✓Dokumentiere Cherry-Picks mit der Option -e in der Commit-Nachricht und erkläre, warum der Commit kopiert wurde
- ✓Nutze --no-commit, um zusammengehörige Picks zu einem saubereren Commit zu bündeln
- ✓Nutze lieber git cherry statt log, um noch nicht angewendete Commits zu finden
- ✓Nimm bei Backports immer den Hash des Original-Commits in die Nachricht auf, damit er nachvollziehbar bleibt
Häufige Fehler
- ✗-m bei Merge-Commits vergessen. Einen Merge-Commit ohne '-m 1' oder '-m 2' zu cherry-picken scheitert – du musst angeben, gegen welchen Elternteil verglichen wird.
- ✗Gelöste Dateien vor --continue nicht stagen. Du musst 'git add' auf gelöste Dateien ausführen, bevor du 'git cherry-pick --continue' startest.
- ✗Denselben Commit-Hash erwarten. Cherry-pick erzeugt NEUE Commits mit neuen SHAs – es kopiert Änderungen, es verschiebt keine Commits.
- ✗Commits cherry-picken, die schon angewendet sind. Das führt zu Konflikten oder leeren Commits – prüfe vorher mit 'git log'.
- ✗Commits in falscher Reihenfolge picken. Abhängige Commits müssen vom ältesten zum neuesten gepickt werden, sonst gibt es Konflikte.
- ✗Cherry-pick auf öffentlichen Branches erzeugt doppelte Commits, wenn andere das Original haben – nutze bei geteilten Branches lieber merge.
FAQ
Nein. Cherry-pick erzeugt einen NEUEN Commit mit denselben Änderungen, aber einem anderen SHA. Der Original-Commit bleibt, wo er war.
Git-Commit-Hashes beruhen auf Inhalt, Elternteil, Autor, Datum und Nachricht. Cherry-pick behält Autor und Autorendatum, aber Elternteil und Committer-Datum unterscheiden sich, also ändert sich der Hash, auch wenn die Änderungen identisch sind.
Ja! Zähle sie auf: git cherry-pick A B C, oder nutze Bereiche: git cherry-pick A^..C (schließt A und C ein).
Nutze die Option -m: git cherry-pick -m 1 <merge-commit>. Die Zahl gibt an, welcher Elternteil die Hauptlinie ist (meist 1).
A..B schließt A aus (Commits nach A bis B). A^..B schließt A ein (Commits von A bis einschließlich B).
Wenn nicht gepusht: git reset --hard HEAD~1. Wenn gepusht: git revert <commit>, um einen Rückgängig-Commit zu erzeugen.
Cherry-pick für bestimmte Commits. Rebase, um ganze Branches zu verschieben. Wenn du die meisten Commits eines Branches brauchst, ist rebase sauberer.