Cherry-pick — este o comandă Git care aplică modificările dintr-un commit specificat în ramura curentă, fără a transfera întreaga istorie a ramurii sursă. Spre deosebire de merge sau rebase, cherry-pick lucrează cu fiecare commit individual: dezvoltatorul selectează un anumit commit după hash și transferă doar modificările sale. Conform documentației Git (2026), cherry-pick este deosebit de util pentru transferul punctual al corecțiilor între ramurile de release, când un merge complet este inutil sau periculos. Comanda creează un commit nou cu un hash nou, dar păstrează mesajul original și autorul.
Principalele
Cherry-pick — este comanda git cherry-pick care preia modificările dintr-un commit existent și le aplică ca un commit nou în ramura curentă. Commitul original rămâne pe loc în ramura sa, iar în ramura țintă se creează o copie a modificărilor. Comanda este utilă când trebuie să transferați o corecție specifică, fără a muta întreaga ramură.
Sinaxa: git cherry-pick <commit-hash>. Git analizează diferența (diff) a commitului specificat cu părintele său și aplică această diferență la ramura curentă. Dacă modificările sunt în mai multe fișiere — toate sunt transferate împreună. Comanda acceptă, de asemenea, intervale: git cherry-pick A..B — toate commiturile de la A la B, excluzând A.
Flagurile extind capacitățile: -n (--no-commit) aplică modificările la directorul de lucru și index fără a crea un commit — util când trebuie să combinați modificările mai multor commituri într-unul singur. Flagul -x adaugă în mesajul commitului linia (cherry picked from commit ...), ceea ce simplifică urmărirea originii modificărilor în istoric.
# Cherry-pick un singur commit după hash
git cherry-pick a1b2c3d
# Cherry-pick mai multe commituri (secvențial)
git cherry-pick a1b2c3d e4f5g6h i6j7k8l
# Cherry-pick fără auto-commit
git cherry-pick -n a1b2c3d
# Flagul -x adaugă referință la commitul original
git cherry-pick -x a1b2c3d
Scenariul principal — transferul corecțiilor între ramurile de release. Imaginați-vă: în develop s-a găsit și s-a reparat o eroare critică. Ramura de release release/v2.1 este deja separata și această eroare există și în ea. Un merge complet al develop în release va transfera mult cod neterminat, în timp ce cherry-pick al unui singur commit cu corecția este o soluție sigură și precisă.
Al doilea scenariu — anularea modificărilor (revert) cu restaurarea ulterioară. Dacă un commit a fost anulat prin git revert, iar apoi s-a dovedit că anularea a fost eronată — cherry-pick al commitului anulat restaurează modificările. Aceasta este mai corectă decât anularea revertului, deoarece nu creează conflicte repetate.
Al treilea scenariu — combinarea commiturilor din diferite ramuri feature într-o singură ramură de test pentru testarea integrării. În loc să uniți mai multe ramuri neterminate (cu cod neterminat), puteți selecta doar commiturile gata din fiecare și testa funcționarea lor comună.
Cherry-pick se deosebește de rebase și merge prin faptul că lucrează la nivelul commiturilor individuale, nu al întregii ramuri. În timp ce rebase transferă toate commiturile ramurii, iar merge unește două ramuri, cherry-pick selectează doar pe cele necesare. Aceasta îl face un instrument mai precis, dar și mai manual.
O altă diferență — autoratul. La cherry-pick, Git păstrează implicit autorul commitului original (Author), dar committerul (Committer) devine utilizatorul curent. În mesajul commitului se poate urmări originea prin flagul -x. La rebase, atât autorul, cât și committerul — ambii sunt utilizatorul curent cu un hash nou.
Performanța: cherry-pick al unui singur commit se execută mai rapid decât merge a două ramuri cu un număr mare de commituri. Dar dacă trebuie să transferați zeci de commituri, este mai bine să creați o ramură temporară și să executați rebase — aceasta va fi mai eficientă și nu va necesita specificarea a zeci de hashuri.
| Operație | Domeniul de aplicare | Efecte secundare |
|---|---|---|
| Cherry-pick | Commituri individuale | Hash nou, duplicare cod |
| Rebase | Toate commiturile ramurii | Rescriere istorie, hashuri noi |
| Merge | Unirea completă a ramurilor | Merge-commit, păstrare istorie |
Mai multe commituri pot fi transferate cu o singură comandă, enumerând hashurile lor separate prin spațiu: git cherry-pick A B C. Git aplică commiturile secvențial în ordinea specificată. Dacă vreunul dintre commituri provoacă un conflict, cherry-pick este suspendat, iar dezvoltatorul trebuie să rezolve conflictul, după care să continue cu comanda git cherry-pick --continue.
Interval de commituri: git cherry-pick A..B (toate commiturile după A până la B, excluzând A) și git cherry-pick A^..B (toate commiturile de la A inclusiv până la B). Intervalele sunt convenabile când trebuie să transferați toate commiturile dintr-o ramură, dar fără legătura de părinte — de exemplu, la transferul unei funcții gata dintr-o ramură veche într-una nouă.
Flagul --strategy determină cum va aplica Git modificările. Implicit se utilizează strategia recursive, dar se poate indica ours sau theirs pentru selectarea automată a părții conflictului. Flagul --mainline se utilizează la cherry-pick al unui merge-commit — indică numărul părintelui (1 sau 2) față de care se calculează diff-ul.
# Interval de commituri cherry-pick
git cherry-pick develop~5..develop~2
# Cherry-pick merge-commit (specifică părintele)
git cherry-pick -m 1 m9n0o1p
# Utilizează strategia theirs
git cherry-pick --strategy=recursive \
--strategy-option=theirs a1b2c3d
# Continuă după rezolvarea conflictului
git cherry-pick --continue
Conflictele la cherry-pick apar atunci când modificările commitului transferat afectează aceleași linii care au fost modificate în ramura țintă. Git suspendă execuția, marchează fișierele conflictuale și așteaptă rezolvarea. În status, astfel de fișiere sunt afișate ca both modified.
Ordinea acțiunilor la conflict: deschideți fișierul conflictual, găsiți markerii de conflict (<<<<<<<, =======, >>>>>>>), editați conținutul, îndepărtați markerii, executați git add pentru fișierele rezolvate și rulați git cherry-pick --continue. Dacă conflictul este de nerezolvat — git cherry-pick --abort anulează întreaga operație cherry-pick, readucând ramura la starea inițială.
O problemă frecventă: commitul conține deja modificări echivalente celor existente. În acest caz, Git raportează «nothing to commit» sau «empty commit» la încercarea de cherry-pick. Flagurile --keep-redundant-commits și --empty=keep îl obligă pe Git să creeze un commit gol pentru păstrarea secvenței, iar --skip permite omiterea unui astfel de commit.
# Conflict în timpul cherry-pick — oprește
git cherry-pick a1b2c3d
# eroare: nu s-a putut aplica a1b2c3d... mesaj commit
# Rezolvă conflictul → adaugă la index
git add src/conflicted_file.swift
git cherry-pick --continue
# Omite commitul gol (deja aplicat)
git cherry-pick --skip
# Anulare completă
git cherry-pick --abort
Prima regulă: verificați întotdeauna dacă commitul transferat este autosuficient. Dacă commitul A depinde de modificările din commitul B care nu se transferă, cherry-pick al lui A poate strica compilarea. Înainte de cherry-pick, este util să verificați ce fișiere a modificat commitul prin git show --stat <hash>.
Regula a doua: documentați cherry-pick. Utilizați flagul -x pentru a păstra în mesajul commitului o referință la commitul sursă. Acest lucru va ajuta la analiza ulterioară a istoricului pentru a determina de unde provine modificarea. Fără -x, cherry-pick arată ca un commit obișnuit, iar originea sa poate fi stabilită doar prin git log --graph.
Regula a treia: evitați cherry-pick între ramuri care au divergut prea mult. Dacă de la crearea commitului a trecut mult timp și baza de cod s-a schimbat semnificativ, conflictele vor fi numeroase și complexe. În astfel de cazuri, este mai bine să faceți corecția din nou în ramura țintă — aceasta va dura mai puțin timp decât rezolvarea a zeci de conflicte.
Întrebări frecvente
A face cherry-pick — să aplici modificările commitului specificat în ramura curentă prin git cherry-pick. Comanda creează un commit nou cu aceleași modificări, dar cu un hash nou. Commitul original rămâne neschimbat în ramura sa. Aceasta este o alternativă la unirea întregii ramuri, atunci când este necesar doar un singur commit specific.
Cherry-pick este ales atunci când trebuie să transferați unul sau mai multe commituri specifice fără a transfera întreaga ramură. Merge se aplică pentru unirea completă a ramurilor. Scenariul tipic pentru cherry-pick — transferul unui hotfix din ramura de dezvoltare în ramura de release, în care celelalte modificări nu sunt încă gata.
Înainte de finalizare — git cherry-pick --abort anulează complet operația. După finalizarea cu succes — git revert <hash> creează un commit care anulează modificările cherry-pick. Diferența față de --abort: revert nu șterge commitul din istoric, ci creează un nou commit de anulare.
Un commit gol apare atunci când modificările sunt deja prezente în ramura țintă. Utilizați git cherry-pick --skip pentru a omite un astfel de commit, sau git cherry-pick --keep-redundant-commits pentru a crea un commit gol pentru păstrarea secvenței hashurilor.
Cherry-pick transferă commiturile selectate (unul sau o listă) în ramura curentă. Rebase transferă toate commiturile ramurii pe o nouă bază. Cherry-pick nu modifică ramura sursă, rebase rescrie istoricul. Cherry-pick este precis, dar manual; rebase este automat, dar periculos pentru ramurile publice.
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