El rebase i el rebase interactiu treballen amb el conjunt de commits d'una branca: els descomponen, els reordenen, els reapliquen. git cherry-pick fa una cosa molt més quirúrgica: agafa un commit concret, sigui on sigui, i aplica el seu canvi sobre la branca on ets ara, creant un commit nou.

El nom ho diu tot: el cherry-picking és escollir les cireres una a una. I com tota eina quirúrgica, és excel·lent en mans que saben quan fer-la servir i perillosa en mans que la fan servir per costum. Un cherry-pick mal posat duplica feina, confon l'historial i provoca conflictes absurds mesos després.

L'Ana ho necessita avui. Ha corregit a main la fallada que fa que el focus es perdi en esborrar una tasca, i la versió 1.x que continua desplegada al client té la mateixa fallada però viu en una branca de manteniment a part, que no pot rebre tot el que hi ha a main. Vol aquell commit i res més.

Contingut

  1. Què fa git cherry-pick
  2. El cas de l'Ana: portar una correcció a manteniment
  3. Diversos commits i rangs
  4. Opcions útils: -n, -x, -e, -s
  5. Conflictes en fer cherry-pick
  6. Rescatar un commit d'una branca abandonada
  7. El problema dels duplicats
  8. Detectar duplicats: git cherry i --cherry-mark
  9. Quan NO fer servir el cherry-pick

  1. Què fa git cherry-pick

git cherry-pick <sha>

Git pren el diff que introdueix <sha> (és a dir, la diferència entre aquell commit i el seu pare), l'aplica sobre l'estat actual de la teva branca i crea un commit nou amb aquell canvi.

La paraula clau, un altre cop, és nou. Igual que al rebase (lliçó 05-01), i pel mateix motiu del model de dades de la lliçó 01-04: el commit resultant té un altre pare, per tant un altre contingut, per tant un altre hash. No és «el mateix commit en dues branques»: són dos commits diferents que casualment introdueixen el mateix canvi.

gitGraph
   commit id: "1a4c8d6"
   commit id: "8b6d3c2"
   branch manteniment/1.x
   commit id: "e4f7b91"
   checkout main
   commit id: "c5d9b1e"
   commit id: "7d3a8f4"
   checkout manteniment/1.x
   cherry-pick id: "7d3a8f4"

El diagrama menteix una mica expressament, perquè gitGraph reutilitza l'etiqueta del commit original. En realitat, a manteniment/1.x hi apareix un commit diferent, amb hash b9e2c17, que introdueix el mateix canvi que 7d3a8f4. Recorda-ho cada vegada que vegis un diagrama de cherry-pick: la fletxa puntejada significa «el mateix canvi», mai «el mateix objecte».

Què es conserva i què no, per completar la taula mental que vas començar a 05-01:

Element Es conserva?
Missatge Sí (editable amb -e)
Autor i correu : continua sent de qui el va escriure
Data d'autoria
Confirmador i la seva data No: passes a ser-ho tu, ara
Contingut del canvi Sí, si no hi ha conflicte
Pare i hash No

Que es conservi l'autoria és important: quan portes la correcció d'un company a una altra branca, el mèrit continua sent seu.

  1. El cas de l'Ana: portar una correcció a manteniment

El repositori de gestor-tasques té dues línies vives:

  • main, on es desenvolupa la versió 2.
  • manteniment/1.x, que reprodueix el que està desplegat al client i només rep correccions.

L'Ana va corregir la fallada del focus a main:

git switch main
git log --oneline -3
7d3a8f4 (HEAD -> main, origin/main) Retorna el focus al camp de text després d'esborrar una tasca
c5d9b1e Extreu la creació de l'element de tasca a la seva funció
8b6d3c2 Desa les tasques a localStorage

El commit és petit i autocontingut, que és exactament el que fa que un commit sigui bon candidat per al cherry-pick:

git show 7d3a8f4
commit 7d3a8f4...
Author: Ana Ferrer <[email protected]>
Date:   Wed Jul 29 11:42:08 2026 +0200

    Retorna el focus al camp de text després d'esborrar una tasca

diff --git a/app.js b/app.js
--- a/app.js
+++ b/app.js
@@ -48,6 +48,7 @@ function esborraTasca(id) {
   tasques = tasques.filter(function (t) { return t.id !== id; });
   desaTasques();
   pintaLlista();
+  document.getElementById('nova-tasca').focus();
 }

Ara, el trasplantament:

# 1. Situar-se a la branca de destinació
git switch manteniment/1.x
git log --oneline -2
e4f7b91 (HEAD -> manteniment/1.x, origin/manteniment/1.x) Corregeix el format de la data al llistat
8b6d3c2 Desa les tasques a localStorage
# 2. Portar només aquell commit, deixant constància de l'origen
git cherry-pick -x 7d3a8f4
[manteniment/1.x b9e2c17] Retorna el focus al camp de text després d'esborrar una tasca
 Date: Wed Jul 29 11:42:08 2026 +0200
 1 file changed, 1 insertion(+)
# 3. Comprovar el resultat
git show b9e2c17
commit b9e2c17...
Author: Ana Ferrer <[email protected]>
Date:   Wed Jul 29 11:42:08 2026 +0200

    Retorna el focus al camp de text després d'esborrar una tasca

    (cherry picked from commit 7d3a8f4c9b1e5d2a8f7c3b6e9d4a1c8f5b2e7d3a)

diff --git a/app.js b/app.js
...

Hash nou (b9e2c17), autoria de l'Ana intacta, canvi idèntic, i una línia al final del missatge que diu d'on va venir. Aquesta línia l'ha posada -x, i es mereix el seu apartat.

  1. Diversos commits i rangs

git cherry-pick accepta diversos commits solts i rangs.

# Diversos commits solts, en l'ordre indicat
git cherry-pick 7d3a8f4 c5d9b1e 4e7f2a9

S'apliquen en l'ordre en què els escrius, no en ordre cronològic. Si depenen els uns dels altres, escriu-los en l'ordre en què es van fer o tindràs conflictes evitables.

Els rangs fan servir la mateixa notació de dos punts de la lliçó 02-06, i amb el mateix parany:

# Del commit SEGÜENT a A, fins a B (tots dos inclosos llevat d'A)
git cherry-pick A..B

# Des d'A INCLÒS fins a B
git cherry-pick A^..B
Expressió Commits aplicats
A..B Els posteriors a A fins a B. A NO s'hi inclou
A^..B Igual, però A sí que s'hi inclou
B Només B
B~3..B Els tres últims fins a B
--stdin Els que li passis per l'entrada estàndard, un per línia

Exemple amb noms reals: en Bruno vol portar a manteniment els tres commits de correccions que va fer a funcionalitat/exportacio-csv, que van de 6e1d9f3 a 9c7e5a1:

git switch manteniment/1.x
git cherry-pick -x 6e1d9f3^..9c7e5a1
[manteniment/1.x 3a8f2d5] Afegeix la conversió de tasques a format CSV
[manteniment/1.x 7b4e9c1] Descarrega el CSV generat des del navegador
[manteniment/1.x d62a4f8] Afegeix el botó d'exportar a la barra d'accions

Tres commits nous amb tres hashos nous, en l'ordre correcte.

Un avís important: un rang de cherry-pick no inclou els commits de fusió. Si el rang conté una fusió, Git la salta silenciosament (o falla, segons el cas). Trasplantar un commit de fusió requereix -m per triar el pare respecte al qual calcular el diff, igual que a revert (lliçó 05-06), i gairebé mai no és el que vols. Si el teu rang té fusions, probablement el que buscaves era un merge o un rebase.

  1. Opcions útils: -n, -x, -e, -s

Opció Nom llarg Què fa
-n --no-commit Aplica els canvis al directori de treball i a l'índex, sense confirmar
-x Afegeix (cherry picked from commit <sha>) al missatge
-e --edit Obre l'editor per modificar el missatge
-s --signoff Afegeix una línia Signed-off-by: Nom <correu>
--ff Si el commit és fill directe de HEAD, fa fast-forward en lloc de crear-ne un de nou
--strategy-option -X ours / -X theirs Resolució automàtica de conflictes per una banda
--allow-empty Permet crear el commit encara que no aporti canvis

-n (--no-commit) serveix per agrupar. Si vols que cinc commits petits arribin a la branca de destinació com un de sol:

git cherry-pick -n 6e1d9f3 b8c2a70 9c7e5a1
git status --short
M  app.js
M  index.html
M  estils.css
git commit -m "Porta les correccions de l'exportació CSV a la branca 1.x"

Els tres canvis queden preparats a l'índex i tu decideixes quan i amb quin missatge confirmar-los. Si te'n penedeixes a mitges, git cherry-pick --abort desfà tot l'acumulat.

-x és fonamental a les branques de manteniment i és la raó per la qual existeix l'opció. Deixa una nota al missatge que permet, mesos després, contestar la pregunta «d'on va sortir aquest commit?»:

Retorna el focus al camp de text després d'esborrar una tasca

(cherry picked from commit 7d3a8f4c9b1e5d2a8f7c3b6e9d4a1c8f5b2e7d3a)

Amb aquesta línia, git show 7d3a8f4 et porta a l'original i en pots veure el context complet. Sense ella, el commit apareix a la branca de manteniment sense cap explicació possible.

Compte amb un matís: -x només té sentit quan el commit d'origen és públic. Si copies un commit d'una branca local que esborraràs, la referència apuntarà a un hash que ningú més no pot resoldre, i la nota confon més que no pas ajuda. La documentació de Git és explícita en això: fes-lo servir per copiar d'una branca pública a una altra.

-s afegeix la línia Signed-off-by:, una convenció de projectes que exigeixen certificar l'origen de les aportacions (el Developer Certificate of Origin del nucli de Linux és el cas canònic). No és cap signatura criptogràfica; això són les etiquetes i els commits signats amb GPG, que es veuen a la lliçó 08-05.

  1. Conflictes en fer cherry-pick

Un cherry-pick aplica un pedaç sobre un context que pot haver canviat. És molt normal que hi hagi conflicte, sobretot quan la branca de destinació ha divergit molt.

git cherry-pick -x 7d3a8f4
Auto-merging app.js
CONFLICT (content): Merge conflict in app.js
error: could not apply 7d3a8f4... Retorna el focus al camp de text després d'esborrar una tasca
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".

La mecànica de resolució —marcadors, git status, editar, git add— és la de la lliçó 03-05 i no canvia. L'específic és com se'n surt:

Ordre Què fa
git cherry-pick --continue Confirma el commit amb la teva resolució i continua amb el següent del rang
git cherry-pick --skip Descarta aquell commit i continua amb la resta
git cherry-pick --abort Cancel·la tota l'operació i retorna la branca al seu estat inicial
git cherry-pick --quit Surt de l'estat de cherry-pick però conserva el que ja s'ha aplicat

I aquí, bona notícia: en un cherry-pick, ours i theirs NO estan invertits. ours és la teva branca de destinació (on ets) i theirs és el commit que estàs portant, que és l'intuïtiu. La inversió de la lliçó 05-01 és una peculiaritat del rebase, no una regla general.

# Durant un conflicte de cherry-pick
git checkout --ours app.js      # la versió de la meva branca de destinació
git checkout --theirs app.js    # la versió del commit que porto

Si el conflicte et sembla molt gros per a la mida del canvi, és un senyal: probablement estàs portant un commit que depèn d'un altre que no has portat. Mira git log --oneline <origen> al voltant del commit i comprova si hi ha un commit previ que també cal.

Quan el commit entra en conflicte perquè el seu canvi ja està aplicat a la branca de destinació, Git t'ho diu d'una altra manera:

The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:

    git commit --allow-empty

Aquí, git cherry-pick --skip és la resposta correcta: no hi ha res a aportar.

  1. Rescatar un commit d'una branca abandonada

El segon cas legítim. La Carla va començar funcionalitat/etiquetes-color i l'equip va decidir aparcar-la: l'enfocament no convencia. Però a dins hi havia un commit que sí que valia la pena: una funció que valida el format hexadecimal d'un color i que resulta útil per a una altra cosa.

# 1. Buscar el commit a la branca abandonada
git log --oneline funcionalitat/etiquetes-color
92c7a06 Pinta l'etiqueta de color al llistat
d5e8f31 Afegeix el camp color al model de tasca
5f1c4b8 Afegeix la validació de colors hexadecimals
e91d4a8 Extreu la creació de l'element de tasca a la seva funció
# 2. Veure què fa exactament abans de trasplantar-lo
git show 5f1c4b8 --stat
 app.js | 12 ++++++++++++
 1 file changed, 12 insertions(+)
# 3. Trasplantar-lo a main
git switch main
git cherry-pick 5f1c4b8
[main 8c3e7f1] Afegeix la validació de colors hexadecimals
 1 file changed, 12 insertions(+)

Aquí la Carla no ha fet servir -x, i fa bé: la branca d'origen s'esborrarà, així que deixar al missatge una referència a un hash que quedarà orfe no ajuda ningú. En aquests casos, si vols deixar-ne constància, escriu-la en llenguatge humà amb -e:

git cherry-pick -e 5f1c4b8
Afegeix la validació de colors hexadecimals

Rescatat de la branca funcionalitat/etiquetes-color, que es va descartar
per altres motius. La funció és útil de manera independent.

Un tercer cas, per completar el catàleg d'usos legítims: t'has equivocat de branca. Has fet tres commits a main que havien d'anar en una branca de funcionalitat. La solució clàssica és crear la branca on ets, i tornar main al seu lloc; però si prefereixes no tocar main, un cherry-pick dels tres commits a la branca correcta és una sortida perfectament vàlida. La casuística completa de «he confirmat a la branca equivocada» és a la lliçó 09-01.

  1. El problema dels duplicats

Aquí és on el cherry-pick passa factura, i convé entendre-ho bé perquè és la raó principal per no abusar-ne.

Escenari: en Bruno té funcionalitat/informe-setmanal amb cinc commits. Un d'ells, 4d7c1a9, corregeix una fallada que urgeix a producció ja. En Bruno fa cherry-pick d'aquell commit a main:

git switch main
git cherry-pick 4d7c1a9
[main 2e9b6f3] Corregeix el càlcul de tasques vençudes

Perfecte: la fallada està corregida a main i desplegada. Però ara, al repositori, el mateix canvi existeix dues vegades: com a 4d7c1a9 a la branca d'en Bruno i com a 2e9b6f3 a main.

gitGraph
   commit id: "e91d4a8"
   branch funcionalitat/informe-setmanal
   commit id: "a1c5e83"
   commit id: "4d7c1a9"
   commit id: "6f2b9d4"
   checkout main
   commit id: "2e9b6f3"

Dues setmanes després, en Bruno acaba la funcionalitat i fusiona la seva branca a main. Què passa?

Cas bo. Si ningú no ha tocat aquelles línies des de llavors, la fusió a tres bandes s'adona que el canvi de 4d7c1a9 ja està aplicat a main (el resultat és el mateix per totes dues bandes) i la fusió surt neta. El commit 4d7c1a9 entra a l'historial, però el seu contingut no s'aplica dues vegades. El resultat és correcte; simplement el git log de main mostra dos commits que diuen el mateix.

Cas dolent. Si algú ha modificat aquelles línies a main després del cherry-pick, la fusió veu un canvi a theirs (el de 4d7c1a9) sobre una base que ja no coincideix, i hi ha conflicte. És el conflicte més desconcertant que existeix: els marcadors mostren dues versions gairebé idèntiques d'un codi que tu ja vas arreglar, i no hi ha manera d'entendre per què xoca si no recordes el cherry-pick de fa dues setmanes.

Cas pitjor. Si el canvi no és idempotent —afegir una línia a una llista, incrementar un comptador, afegir una entrada a un fitxer de configuració—, la fusió el pot aplicar dues vegades sense conflicte. El resultat compila, passa els tests superficials i està malament.

La conclusió és la que dona títol a l'últim apartat: el cherry-pick és per a quan no fusionaràs després, o per a quan fusionar no és una opció (branques que no s'ajunten mai, com main i manteniment/1.x).

  1. Detectar duplicats: git cherry i --cherry-mark

Git té eines per reconèixer commits que introdueixen el mateix canvi amb hashos diferents. Es basen en el patch-id: un hash calculat sobre el contingut del diff, ignorant el context, les línies en blanc i els números de línia. Dos commits amb el mateix patch-id fan el mateix encara que siguin objectes diferents.

git cherry compara dues branques i marca cada commit amb + (no és a l'altra) o - (ja hi és, amb un altre hash):

git cherry -v main funcionalitat/informe-setmanal
+ a1c5e83f2b7d9c4e1a8f6b3d5c2e9a7f4b1d8c6e Afegeix la vista de l'informe setmanal
- 4d7c1a9e8b2f5d3c7a9e1f4b6d8c2a5e3f7b9d1c Corregeix el càlcul de tasques vençudes
+ 6f2b9d4c1e7a3f8b5d2c9e6a4f1b8d3c7e5a2f9b Afegeix el filtre per setmana

El - de la segona línia significa: «aquest commit ja està aplicat a main, encara que allà tingui un altre hash». Exactament el que buscàvem. La sintaxi és git cherry [-v] <upstream> [<head>], i -v hi afegeix l'assumpte de cada commit.

És especialment útil abans de fusionar o abans de portar un lot de commits a manteniment: et diu què queda realment per portar.

git log --cherry-mark fa el mateix dins d'un log, sobre un rang de tres punts:

git log --oneline --cherry-mark --left-right main...funcionalitat/informe-setmanal
> a1c5e83 Afegeix la vista de l'informe setmanal
= 4d7c1a9 Corregeix el càlcul de tasques vençudes
= 2e9b6f3 Corregeix el càlcul de tasques vençudes
> 6f2b9d4 Afegeix el filtre per setmana
Marca Significat
< Només al costat esquerre (main)
> Només al costat dret (la branca)
= Present als dos costats com a canvi equivalent (mateix patch-id)

Aquí els tens, l'un al costat de l'altre, els dos commits que fan el mateix. Variants relacionades:

# Amagar els equivalents: només el que de debò falta per integrar
git log --oneline --cherry-pick --left-right main...funcionalitat/informe-setmanal

# Drecera de l'anterior, només el costat dret
git log --oneline --cherry funcionalitat/informe-setmanal...main

--cherry-pick és el que faràs servir més: filtra el soroll i et deixa només la feina realment pendent.

Una limitació honesta: el patch-id compara el diff. Si en fer el cherry-pick hi va haver un conflicte i vas resoldre d'una altra manera, el diff resultant no serà idèntic i Git no el reconeixerà com a equivalent. La detecció és una ajuda, no cap garantia.

  1. Quan NO fer servir el cherry-pick

Situació Què fer al seu lloc
Vols portar tota una branca a una altra git merge (o rebase si encara no està publicada)
Fusionaràs aquella branca després, més endavant Espera i fusiona: evites els duplicats de l'apartat 7
Necessites més de tres o quatre commits seguits rebase --onto: reaplica un tram complet i no deixa duplicats
Vols posar la teva branca al dia amb main git merge main o git rebase main, mai cherry-picks solts de main
El commit depèn d'altres que no portaràs Portar també les dependències, o refer el canvi a mà
Vols «copiar» un commit a la mateixa branca Gairebé segur que busques revert (05-06) o un rebase interactiu

La regla de decisió, en una frase: si les dues branques acabaran ajuntant-se, no copiïs commits entre elles; fusiona-les. El cherry-pick és per a branques que viuen en paral·lel permanentment (manteniment, versions antigues, entorns separats) o per rescatar alguna cosa d'una branca que morirà.

Sobre la regla d'or: el cherry-pick és, de les tres operacions d'aquest bloc, la menys perillosa, perquè no reescriu res. Afegeix un commit nou a la branca on ets; no toca l'origen ni obliga ningú a forçar un push. El seu perill no és la reescriptura sinó la duplicació, que es paga més tard i en forma de conflictes difícils d'explicar.

Errors Habituals i Consells

Error 1: creure que el cherry-pick «mou» el commit. El copia. L'original continua a la seva branca, tan viu com abans. Si el volies moure, l'has d'esborrar de l'origen amb un rebase interactiu (drop), amb les implicacions de la regla d'or que això comporta.

Error 2: fer cherry-pick de commits d'una branca que després fusionaràs. És la font número u de conflictes incomprensibles. Si la branca hi entrarà sencera, espera.

Error 3: oblidar -x en portar a manteniment. D'aquí a sis mesos, aquell commit sense origen conegut a manteniment/1.x serà un misteri. Costa dos caràcters.

Error 4: fer servir -x copiant d'una branca local que esborraràs. La referència queda apuntant a un hash irresoluble. Allà és millor -e i una nota en llenguatge humà.

Error 5: fer cherry-pick sense mirar el commit abans. git show <sha> costa tres segons i t'estalvia descobrir a mitges del conflicte que el commit tocava sis fitxers i depenia d'uns altres tres.

Error 6: no comprovar el rang. A..B exclou A. Si esperaves que s'apliquessin cinc commits i se n'apliquen quatre, és això. Comprova-ho sempre abans amb git log --oneline A..B.

Error 7: confondre la direcció de git cherry. El primer argument és l'upstream (allò amb què compares, normalment main) i el segon la branca que examines. A l'inrevés et donarà justament el contrari del que esperes.

Consell 1: fes commits petits i autocontinguts. No és un consell sobre el cherry-pick, és el consell que fa possible el cherry-pick. Un commit que fa una sola cosa es trasplanta sense drama; un que en barreja tres, no.

Consell 2: verifica sempre després de portar. Que el pedaç s'apliqui sense conflicte no vol dir que funcioni a l'altra branca. Executa les proves.

Consell 3: fes servir git cherry -v abans d'una campanya de portat. Et dirà exactament què queda per portar i què ja hi és, sense dependre de la teva memòria.

Consell 4: per a lots grans, git rebase --onto en lloc de molts cherry-picks. És la mateixa operació al fons, però d'una sola vegada i amb una llista clara del que s'està reaplicant.

Consell 5: si el cherry-pick es complica, avorta. git cherry-pick --abort deixa el repositori exactament com estava. Refer el canvi a mà a la branca de destinació és de vegades més ràpid i sempre més clar que barallar-se amb un pedaç que no encaixa.

Exercicis

Exercici 1: portar una correcció a manteniment

Munta un repositori amb main i una branca manteniment/1.x que surti d'un commit antic. Afegeix dos commits a main, un d'ells una correcció petita. Després:

  1. Porta només la correcció a manteniment/1.x deixant constància de l'origen.
  2. Demostra que el hash és diferent però el diff és idèntic.
  3. Demostra que l'autor original s'ha conservat.

Exercici 2: el duplicat i la seva detecció

Provoca expressament el problema de l'apartat 7:

  1. Crea una branca amb tres commits.
  2. Fes cherry-pick del segon a main.
  3. Fes servir git cherry -v per demostrar que Git sap que aquell canvi ja és a main.
  4. Fes servir git log --cherry-mark --left-right per veure els dos commits equivalents marcats amb =.
  5. Fusiona la branca a main i observa què passa amb l'historial.

Exercici 3: agrupar diversos commits en un

Amb una branca que tingui quatre commits petits, porta els tres primers a una altra branca com un únic commit amb un missatge propi, fent servir -n. Verifica amb git show --stat que el commit resultant conté els canvis dels tres.

Solucions

Solució 1:

mkdir /tmp/ex-cherry && cd /tmp/ex-cherry
git init -b main
echo "v1" > app.js && git add . && git commit -m "Versio inicial"

git switch -c manteniment/1.x
git switch main

printf 'v1\nfuncionalitat nova\n' > app.js && git commit -am "Afegeix funcionalitat de la versio 2"
printf 'v1\nfuncionalitat nova\ncorreccio\n' > app.js
git -c user.name="Ana Ferrer" -c user.email="[email protected]" commit -am "Corregeix el focus despres d'esborrar"

git log --oneline
5c9e1f4 Corregeix el focus despres d'esborrar
a72b8d3 Afegeix funcionalitat de la versio 2
1e4f7c9 Versio inicial
# 1. Portar només la correcció
git switch manteniment/1.x
git cherry-pick -x 5c9e1f4
Auto-merging app.js
CONFLICT (content): Merge conflict in app.js

(Hi ha conflicte perquè a manteniment/1.x falta la línia de la funcionalitat. Es resol deixant només la correcció.)

printf 'v1\ncorreccio\n' > app.js
git add app.js
git cherry-pick --continue
# 2 i 3. Comparar
git log --oneline -1
git show --pretty='%h | %an | %ad' --date=short HEAD | head -4
git show --pretty='%h | %an | %ad' --date=short 5c9e1f4 | head -4
d81f6a2 Corregeix el focus despres d'esborrar
d81f6a2 | Ana Ferrer | 2026-07-29
5c9e1f4 | Ana Ferrer | 2026-07-29

Hash diferent, mateixa autoria i mateixa data d'autoria. El missatge del nou inclou a més la línia (cherry picked from commit 5c9e1f4...).

Solució 2:

mkdir /tmp/ex-duplicats && cd /tmp/ex-duplicats
git init -b main
printf 'linia 1\n' > f.txt && git add . && git commit -m "Base"

git switch -c funcionalitat/alguna-cosa
printf 'linia 1\nA\n' > f.txt && git commit -am "Commit A"
printf 'linia 1\nA\nB\n' > f.txt && git commit -am "Commit B (la correccio urgent)"
printf 'linia 1\nA\nB\nC\n' > f.txt && git commit -am "Commit C"

git log --oneline
9f2a7c1 Commit C
4d8e3b6 Commit B (la correccio urgent)
c17b5f9 Commit A
2e6a9d4 Base
# 2. Cherry-pick del segon a main
git switch main
git cherry-pick 4d8e3b6
Auto-merging f.txt
CONFLICT (content): Merge conflict in f.txt
printf 'linia 1\nB\n' > f.txt
git add f.txt && git cherry-pick --continue
# 3. git cherry ho detecta
git cherry -v main funcionalitat/alguna-cosa
+ c17b5f9... Commit A
- 4d8e3b6... Commit B (la correccio urgent)
+ 9f2a7c1... Commit C

Només si el diff resultant coincideix; si la teva resolució del conflicte va canviar el pedaç, apareixerà amb +. És la limitació que comentàvem.

# 4. La vista amb marques
git log --oneline --cherry-mark --left-right main...funcionalitat/alguna-cosa
< 7b3e9f1 Commit B (la correccio urgent)
> c17b5f9 Commit A
> 4d8e3b6 Commit B (la correccio urgent)
> 9f2a7c1 Commit C
# 5. La fusió
git merge funcionalitat/alguna-cosa
git log --oneline

Veuràs el commit portat i l'original convivint a l'historial de main, dient el mateix dues vegades. Si el conflicte es va resoldre d'una altra manera, a més hi haurà hagut conflicte en fusionar. Aquest és exactament el preu del cherry-pick prematur.

Solució 3:

mkdir /tmp/ex-agrupar && cd /tmp/ex-agrupar
git init -b main
echo "base" > f.txt && git add . && git commit -m "Base"

git switch -c origen
echo "un" > un.txt && git add . && git commit -m "Un"
echo "dos" > dos.txt && git add . && git commit -m "Dos"
echo "tres" > tres.txt && git add . && git commit -m "Tres"
echo "quatre" > quatre.txt && git add . && git commit -m "Quatre"

git log --oneline origen
8c4f1e7 Quatre
3b9d6a2 Tres
f51e8c4 Dos
a27c9f3 Un
1d6b4e8 Base
git switch main
git cherry-pick -n a27c9f3^..3b9d6a2
git status --short
A  dos.txt
A  tres.txt
A  un.txt
git commit -m "Porta els tres primers passos com un únic canvi"
git show --stat HEAD
commit 6e2d8b5...
    Porta els tres primers passos com un únic canvi

 dos.txt   | 1 +
 tres.txt  | 1 +
 un.txt    | 1 +
 3 files changed, 3 insertions(+)

Fixa't en el rang: a27c9f3^..3b9d6a2 inclou Un, Dos i Tres. Sense el ^ hauries portat només Dos i Tres.

Conclusió

git cherry-pick és l'eina de precisió del mòdul. L'essencial:

  • Copia el canvi d'un commit sobre la teva branca actual creant un commit nou amb un altre hash. Conserva el missatge, l'autor i la data d'autoria; tu passes a ser-ne el confirmador.
  • Accepta commits solts i rangs, amb el parany habitual que A..B exclou A i A^..B no. Els commits de fusió queden fora dels rangs.
  • -x deixa constància de l'origen i és imprescindible en portar a branques de manteniment públiques; -n permet acumular diversos commits i confirmar-los com un de sol; -e edita el missatge i -s hi afegeix el sign-off.
  • Els conflictes es resolen com sempre (lliçó 03-05) i se'n surt amb --continue, --skip o --abort. Aquí ours i theirs NO estan invertits: la inversió era cosa del rebase.
  • Els casos legítims són dos: portar una correcció a una branca que no es fusionarà mai amb l'origen (manteniment, versions antigues), i rescatar un commit d'una branca que s'abandonarà.
  • El preu de l'abús són els duplicats: si copies un commit d'una branca que després fusiones, el mateix canvi acaba dues vegades a l'historial i, en el pitjor dels casos, aplicat dues vegades.
  • git cherry -v i git log --cherry-mark/--cherry-pick detecten canvis equivalents comparant el patch-id, i són la manera de saber què queda realment per portar.
  • Si les dues branques s'ajuntaran, no copiïs: fusiona.

El que ve

Les tres lliçons anteriors han manipulat commits: reaplicant-los, reorganitzant-los, copiant-los. Totes parteixen de la mateixa premissa: que la feina ja està confirmada.

Però el dia a dia té un problema diferent i molt freqüent. Ets a mitges d'alguna cosa, amb el fitxer mig escrit i res confirmable, i arriba una urgència que cal atendre ara. No vols confirmar un wip (encara que sigui corregible amb el que has après a 05-02), no vols perdre el que has fet, i necessites el directori net per canviar de branca.

Git té un calaix per a això, i el portem prometent des de la lliçó 03-02: git stash. L'obrim a la lliçó 05-04: Desant Canvis Temporals.

Dominant Git: De Principiant a Avançat

Mòdul 1: Introducció a Git

Mòdul 2: Operacions Bàsiques de Git

Mòdul 3: Branques i Fusió

Mòdul 4: Treballant amb Repositoris Remots

Mòdul 5: Operacions Avançades de Git

Mòdul 6: Eines i Tècniques de Git

Mòdul 7: Estratègies de Col·laboració i Flux de Treball

Mòdul 8: Bones Pràctiques i Consells de Git

Mòdul 9: Resolució de Problemes i Depuració

Mòdul 10: Git al Món Real

© Copyright 2026. Tots els drets reservats