Cherry-pick — este o comandă Git care aplică modificări dintr-unul sau mai multe commituri existente în ramura curentă. Spre deosebire de Merge (transferă întreaga ramură) și Rebase (transferă o secvență de commituri), cherry-pick selectează doar commiturile specificate. Potrivit git-scm.com, 2025, cherry-pick este cel mai solicitat în scenariile de transfer al corecțiilor între ramurile de release.
Principalele puncte
Cherry-pick — este o comandă Git care copiază modificări dintr-un commit specificat și le aplică ca un nou commit în ramura curentă. Numele provine de la metafora „a culege cireșe”: dezvoltatorul selectează doar commiturile de care are nevoie, ignorând restul.
Spre deosebire de Merge, cherry-pick nu creează un merge commit și nu necesită îmbinarea completă a ramurilor. Spre deosebire de Rebase, cherry-pick nu transferă o secvență de commituri — doar pe cele specificate. Acest lucru face din cherry-pick un instrument ideal pentru transferul precis al corecțiilor.
Potrivit datelor Atlassian, 2025, cherry-pick este utilizat în 47% dintre echipele care lucrează simultan cu mai multe ramuri de release. Cherry-pick este deosebit de solicitat în dezvoltarea mobilă, unde sunt suportate simultan mai multe versiuni ale aplicației (release-uri LTS) și este necesar transferul corecțiilor între ele.
La executarea cherry-pick, Git calculează diff între commitul specificat și părintele său, apoi aplică acest diff ramurii curente. Dacă modificările s-au aplicat fără conflict — Git creează un nou commit cu același mesaj, dar cu un SHA nou. Dacă există un conflict — cherry-pick este suspendat pentru rezolvarea manuală.
Sintaxa cherry-pick este simplă: specificați hash-ul commitului pe care doriți să-l transferați. Git va copia modificările în ramura curentă ca un nou commit. Este suportat transferul mai multor commituri simultan și al intervalelor întregi.
# Transferul unui commit în ramura curentă
git cherry-pick a1b2c3d4
# Transferul mai multor commituri
git cherry-pick a1b2c3d4 e5f6g7h8
# Transferul unui interval de commituri (de la a1b2 la f9e8, neincluzând a1b2)
git cherry-pick a1b2c3d4..f9e8d7c6
După executarea cherry-pick, ramura curentă primește un nou commit cu modificări din original. Mesajul commitului este copiat implicit din original, dar poate fi modificat cu flag-ul -n (nu crea commit) sau --edit (editează mesajul).
Să considerăm scenariul tipic: în develop a fost găsită și corectată o eroare critică, care este prezentă și în ramura de release release/v2.0. Trebuie transferată doar această corecție, fără a îmbina întregul develop în ramura de release.
# Găsiți hash-ul commitului cu corecția în develop
git log --oneline develop
# a1b2c3d fix: null check in payment processing
# Comutați pe ramura de release
git checkout release/v2.0
# Aplicați corecția
git cherry-pick a1b2c3d4
# Dacă există conflict — rezolvați și continuați
git add src/payment/PaymentProcessor.kt
git cherry-pick --continue
Flag-ul -x adaugă în mesajul commitului o referință la SHA-ul original: „(cherry picked from commit a1b2c3d4)”. Acest lucru facilitează urmărirea de unde a fost transferat commitul. Se recomandă utilizarea -x în toate scenariile, cu excepția ciornelor temporare.
La conflict, cherry-pick se comportă ca merge: Git se oprește și marchează fișierele cu conflict. Dezvoltatorul rezolvă conflictul, execută git add și apoi git cherry-pick --continue. Pentru anulare — git cherry-pick --abort. Flag-ul --strategy permite specificarea strategiei de îmbinare (de exemplu, recursive cu opțiuni).
# Rezolvarea conflictului la cherry-pick
# Git arată fișierele cu conflict
git status
# Rezolvați manual, apoi:
git add razreshennyy_fayl.kt
git cherry-pick --continue
# Sau anulați cherry-pick:
git cherry-pick --abort
Cherry-pick este optim în scenarii unde este necesar transferul precis al modificărilor fără îmbinarea ramurilor întregi. Să analizăm cinci cazuri principale în care cherry-pick devine cea mai bună alegere.
Pentru dezvoltarea mobilă, cherry-pick este critic la suportul mai multor versiuni ale aplicației. De exemplu, dacă o eroare a fost găsită în versiunea 3.2 deja lansată în Google Play, iar develop conține cod pentru versiunea 4.0 — cherry-pick permite transferul corecției în ramura v3.x fără îmbinarea tuturor breaking changes. Acest lucru este deosebit de relevant pentru proiecte unde sunt suportate simultan două sau mai multe versiuni majore cu API-uri și dependențe diferite.
Exemplu din practică: într-o aplicație mobilă a fost descoperit un crash la autentificarea prin Google Sign-In pe Android 12. Corecția a fost introdusă în develop și a trecut de review. Însă ramura de release curentă v2.5 este deja în faza de testare beta. Cherry-pick al commitului corecției din develop în release/v2.5 permite includerea corecției în următorul release, fără a transfera restul modificărilor care nu sunt încă pregătite pentru lansare.
La utilizarea cherry-pick în proiecte mobile este important să se țină cont de dependențe: dacă corecția afectează fișiere care au fost modificate în develop după punctul de divergență al ramurii de release, cherry-pick poate aduce un set incomplet de modificări. În astfel de cazuri, trebuie verificat că toate modificările conexe au fost, de asemenea, transferate, altfel aplicația s-ar putea să nu se compileze sau să funcționeze incorect. Verificați întotdeauna compilarea după cherry-pick înainte de a trimite modificările în ramura comună.
Trei instrumente principale de integrare a modificărilor în Git — merge, rebase și cherry-pick — rezolvă sarcini diferite. Alegerea depinde de ce volum de modificări trebuie transferat și cum ar trebui să arate istoricul.
| Criteriu | Merge | Rebase | Cherry-pick |
|---|---|---|---|
| Volum | Întreaga ramură | Serie de commituri | Commituri selectate |
| Istoric | Păstrează ramificarea | Liniar | Liniar |
| Merge commit | Da (în afară de ff) | Nu | Nu |
| Automatizare | Completă | În lanț | Doar specificate |
| Pentru ramuri publice | Sigur | Periculos | Sigur |
Merge — când trebuie îmbinate două ramuri în întregime și păstrată informația despre ramificare. Rebase — când trebuie actualizată o ramură personală la starea curentă cu un istoric curat. Cherry-pick — când este necesar doar un commit sau câteva commituri selectate.
În practică, aceste instrumente sunt combinate: funcționalitatea este dezvoltată cu rebase periodic pe develop, apoi îmbinată prin --no-ff merge, iar la necesitatea transferării corecției în altă ramură se folosește cherry-pick. Fiecare instrument își rezolvă sarcina în etapa sa.
Cherry-pick — un instrument util, dar potențial periculos la utilizarea incorectă sau excesivă. Riscurile principale sunt legate de duplicarea commiturilor, pierderea contextului și conflictele la îmbinările ulterioare.
Recomandări pentru minimizarea riscurilor: utilizați întotdeauna flag-ul -x pentru a indica SHA-ul original, documentați motivul cherry-pick în mesajul commitului și, pe cât posibil, utilizați merge în loc de cherry-pick când contextul permite. Dacă cherry-pick-urile devin prea multe — luați în considerare restructurarea ramurilor.
Pipeline-urile CI trebuie să ia în considerare cherry-pick ca un scenariu separat. Se recomandă configurarea unei verificări automate: la crearea unui commit cherry-pick, CI verifică dacă fișierele modificate corespund setului așteptat și lansează teste pentru modulele afectate. Acest lucru reduce riscul de regresie la transferul precis al modificărilor între ramuri.
Întrebări frecvente
Cherry-pick transferă modificări dintr-un commit în altă ramură. Revert creează un nou commit care anulează modificările commitului specificat în aceeași ramură. Revert nu șterge istoricul — adaugă o modificare inversă.
Da: git cherry-pick A B C — transferul commiturilor A, B și C în ordine. Sau git cherry-pick A..C — transferul tuturor commiturilor de la A la C (neincluzând A). Ordinea transferului corespunde ordinii din comandă.
Implicit, cherry-pick nu funcționează cu merge commituri, deoarece un merge commit are doi părinți. Utilizați flag-ul -m 1 pentru a specifica cu care părinte să comparați. -m 1 ia diff-ul relativ la primul părinte.
Anularea cherry-pick se poate face prin git reset --hard HEAD~1, dacă acesta este ultimul commit. Dacă commitul a fost deja trimis — utilizați git revert <SHA> pentru a crea un commit de anulare.
Nu are sens, dar tehnic este posibil. Dacă commitul există deja în ramură, Git va detecta că modificările au fost deja aplicate și va raporta: „The previous cherry-pick is now empty, possibly due to conflict resolution.” Commitul nu va fi creat din nou.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și