Salta el contingut
 

Cherry-pick

Joan Puigcerver Ibáñez

j.puigcerveribanez@edu.gva.es

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Cherry-pick

La comanda cherry-pick permet aplicar els canvis d'un commit concret sobre la branca actual.

Aquesta ordre pot ser útil si has realitzat un canvi en una branca incorrecta i vols copiar-lo a la branca correcta sense haver de fusionar les branques.

Documentació oficial de Git

git cherry-pick

La sintaxi és la següent:

git cherry-pick <ref>

  • <ref>: Referència del commit que es vol aplicar.

Funcionament de git cherry-pick

Figura 1. Funcionament de git cherry-pick.

Preparació repositori

Per a aquest exemple, crearem un nou repositori per emmagatzemar begudes i menjars en els seus fitxers corresponents.

Danger

Crea el nou repositori en una carpeta independent per evitar problemes amb els exemples i exercicis anteriors.

setup_cherrypick.sh
#!/bin/bash

# Elimina els repositori si existeix
if [ -d ~/git_cherrypick ]; then
    rm -rf ~/git_cherrypick
fi

mkdir -p ~/git_cherrypick
cd ~/git_cherrypick
git init
git branch -m main
echo "# Git cherrypick" > README.md
git add README.md
git commit -m "Commit inicial"
git branch begudes
git branch menjar
git checkout begudes
echo "Aigua" >> begudes.txt
git add begudes.txt
git commit -m "Begudes: aigua"
echo "Refresc" >> begudes.txt
git commit -a -m "Begudes: refresc"
git checkout main
git lga
jpuigcerver@fp:~ $ mkdir -p ~/git_cherrypick
jpuigcerver@fp:~ $ cd ~/git_cherrypick
jpuigcerver@fp:~/git_cherrypick $ git init
Initialized empty Git repository in ~/git_cherrypick/.git/
jpuigcerver@fp:~/git_cherrypick (main) $ git branch -m main
jpuigcerver@fp:~/git_cherrypick (main) $ echo "# Git cherrypick" > README.md
jpuigcerver@fp:~/git_cherrypick (main) $ git add README.md
jpuigcerver@fp:~/git_cherrypick (main) $ git commit -m "Commit inicial"
[main (root-commit) f21f6f7] Commit inicial
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
jpuigcerver@fp:~/git_cherrypick (main) $ git branch begudes
jpuigcerver@fp:~/git_cherrypick (main) $ git branch menjar
jpuigcerver@fp:~/git_cherrypick (main) $ git checkout begudes
Switched to branch 'begudes'
jpuigcerver@fp:~/git_cherrypick (begudes) $ echo "Aigua" >> begudes.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git add begudes.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git commit -m "Begudes: aigua"
[begudes 5b87d79] Begudes: aigua
 1 file changed, 1 insertion(+)
 create mode 100644 begudes.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ echo "Refresc" >> begudes.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git commit -a -m "Begudes: refresc"
[begudes 054e4e0] Begudes: refresc
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_cherrypick (begudes) $ git checkout main
Switched to branch 'main'
jpuigcerver@fp:~/git_cherrypick (main) $ git lga
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver (begudes)
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (HEAD -> main, menjar)
Exemple: git cherry-pick

En aquest cas, ens hem enganyat i hem creat el commit Menjar: pa a la branca begudes en lloc de la branca menjar.

jpuigcerver@fp:~/git_cherrypick (main) $ git checkout begudes
Switched to branch 'begudes'
jpuigcerver@fp:~/git_cherrypick (begudes) $ echo "Pa" >> menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git add menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git commit -m "Menjar: pa"
[begudes b5f02cd] Menjar: pa
 1 file changed, 1 insertion(+)
 create mode 100644 menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git lga
* b5f02cd - (0 seconds ago) Menjar: pa - Joan Puigcerver (HEAD -> begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (menjar, main)

Copiem aquest commit a la branca menjar.

jpuigcerver@fp:~/git_cherrypick (begudes) $ git checkout menjar
Switched to branch 'menjar'
jpuigcerver@fp:~/git_cherrypick (menjar) $ git lga
* b5f02cd - (0 seconds ago) Menjar: pa - Joan Puigcerver (begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (HEAD -> menjar, main)
jpuigcerver@fp:~/git_cherrypick (menjar) $ ls
README.md
jpuigcerver@fp:~/git_cherrypick (menjar) $ git cherry-pick b5f02cd
[menjar 604897c] Menjar: pa
 Date: Tue Jan 21 12:40:47 2025 +0100
 1 file changed, 1 insertion(+)
 create mode 100644 menjar.txt
jpuigcerver@fp:~/git_cherrypick (menjar) $ git lga
* b5f02cd - (0 seconds ago) Menjar: pa - Joan Puigcerver (begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver (HEAD -> menjar)
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)
jpuigcerver@fp:~/git_cherrypick (menjar) $ ls
menjar.txt
README.md
jpuigcerver@fp:~/git_cherrypick (menjar) $ cat menjar.txt
Pa

Esborrem el commit de la branca begudes.

jpuigcerver@fp:~/git_cherrypick (menjar) $ git checkout begudes
Switched to branch 'begudes'
jpuigcerver@fp:~/git_cherrypick (begudes) $ git reset --hard 054e4e0
HEAD is now at 054e4e0 Begudes: refresc
jpuigcerver@fp:~/git_cherrypick (begudes) $ git lga
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver (HEAD -> begudes)
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver (menjar)
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)

Resolució de conflictes

Aquesta acció pot generar conflictes si els canvis que es volen aplicar es produeixen en llocs que han segut modificats.

En aquest cas, passarem a l'estat CHERRY-PICKING i caldrà resoldre els conflictes manualment, de la mateixa manera que es fa en una fusió de branques (merge).

Exemple: Resolució de conflictes en git cherry-pick

Vaja, ens hem tornat a enganyar de branca i hem creat el commit Menjar: taronges a la branca begudes en lloc de la branca menjar.

jpuigcerver@fp:~/git_cherrypick (begudes) $ git checkout begudes
Already on 'begudes'
jpuigcerver@fp:~/git_cherrypick (begudes) $ echo "Taronges" >> menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git add menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git commit -m "Menjar: taronges"
[begudes 2b643ff] Menjar: taronges
 1 file changed, 1 insertion(+)
 create mode 100644 menjar.txt
jpuigcerver@fp:~/git_cherrypick (begudes) $ git lga
* 2b643ff - (0 seconds ago) Menjar: taronges - Joan Puigcerver (HEAD -> begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver (menjar)
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)

Tornem a copiar aquest commit a la branca menjar, però en aquest cas hi ha conflictes, ja que el fitxer menjar.txt ha estat modificat en ambdues branques.

jpuigcerver@fp:~/git_cherrypick (begudes) $ git checkout menjar
Switched to branch 'menjar'
jpuigcerver@fp:~/git_cherrypick (menjar) $ git lga
* 2b643ff - (0 seconds ago) Menjar: taronges - Joan Puigcerver (begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver (HEAD -> menjar)
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)
jpuigcerver@fp:~/git_cherrypick (menjar) $ git cherry-pick 2b643ff
Auto-merging menjar.txt
CONFLICT (add/add): Merge conflict in menjar.txt
error: could not apply 2b643ff... Menjar: taronges
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".
hint: Disable this message with "git config advice.mergeConflict false"
jpuigcerver@fp:~/git_cherrypick (menjar|CHERRY-PICKING) $ cat menjar.txt
<<<<<<< HEAD
Pa
=======
Taronges
>>>>>>> 2b643ff (Menjar: taronges)
jpuigcerver@fp:~/git_cherrypick (menjar|CHERRY-PICKING) $ code menjar.txt # (1)!
jpuigcerver@fp:~/git_cherrypick (menjar|CHERRY-PICKING) $ git diff
diff --cc menjar.txt
index 6b24a67,694e2da..0000000
--- a/menjar.txt
+++ b/menjar.txt
@@@ -1,1 -1,1 +1,2 @@@
 +Pa
+ Taronges
jpuigcerver@fp:~/git_cherrypick (menjar|CHERRY-PICKING) $ git add menjar.txt
jpuigcerver@fp:~/git_cherrypick (menjar|CHERRY-PICKING) $ git cherry-pick --continue --no-edit
[menjar 63d71c6] Menjar: taronges
 Date: Tue Jan 21 12:40:47 2025 +0100
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_cherrypick (menjar) $ git lga
* 2b643ff - (0 seconds ago) Menjar: taronges - Joan Puigcerver (begudes)
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 63d71c6 - (0 seconds ago) Menjar: taronges - Joan Puigcerver (HEAD -> menjar)
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)
  1. S'ha editat manualment el fitxer per eliminar els marcadors de conflictes i deixar el contingut desitjat.

Per últim, esborrem el commit de la branca begudes.

jpuigcerver@fp:~/git_cherrypick (menjar) $ git checkout begudes
Switched to branch 'begudes'
jpuigcerver@fp:~/git_cherrypick (begudes) $ git reset --hard 054e4e0
HEAD is now at 054e4e0 Begudes: refresc
jpuigcerver@fp:~/git_cherrypick (begudes) $ git lga
* 054e4e0 - (0 seconds ago) Begudes: refresc - Joan Puigcerver (HEAD -> begudes)
* 5b87d79 - (0 seconds ago) Begudes: aigua - Joan Puigcerver
| * 63d71c6 - (0 seconds ago) Menjar: taronges - Joan Puigcerver (menjar)
| * 604897c - (0 seconds ago) Menjar: pa - Joan Puigcerver
|/  
* f21f6f7 - (0 seconds ago) Commit inicial - Joan Puigcerver (main)
📌 Aquest document pot quedar desactualitzat després d’imprimir-lo. Pots consultar la versió més recent a la pàgina web.
🌿 Abans d’imprimir aquest document, considera si és realment necessari. Redueix el consum de paper i ajuda a protegir el nostre entorn.