Table of contents
Open Table of contents
Que es git cherry-pick?
git cherry-pick es uno de los comandos de git más útiles, permite copiar y pegar commits de un branch a otro.
git cherry-pick no afecta el commit original por lo que este commit permanecerá en el branch de origen.
Muchos desarrolladores consideran el uso de git cherry-pick como una mala práctica, que puede causar problemas como tener commits duplicados en múltiples branches, estropear el historial de git, entre otros.
Pero entendiendo cómo funciona git cherry-pick y usándola con precaución, es una de las herramientas más útiles de git.
Algunos caso de uso de git cherry-pick son:
- Copiar un commit echo en el branch equivocado al branch correcto y borrar el commit original.
- Copiar un quick fix en la rama de pre-producción cuando es un error urgente.
- Compartir cambios entre backend y frontend cuando el código está en un mismo repositorio.
Cómo usar cherry-pick
Para copiar un commit necesitamos el hash del commit a copiar y estar posicionados en el branch donde queremos pegar el commit.
El uso del commando git cherry-pick es el siguiente:
git cherry-pick <commit hash>
Nota: el hash del commit lo podemos obtener con el commando git log o directamente de Github.
Ejemplo: Tenemos un fix para un bug que es urgente y no podemos esperar a que termine el trabajo actual en el branch
de develop, el fix esta dentro del commit ecd878a en la rama dev , para pasar este fix a la rama master nos
posicionamos en esa rama y ejecutamos el comando git cherry-pick <commit hash>.
a - b - c - d master
\
e - f (fix urgent bug) - g - h dev
cherry-pick-test on master
$ git cherry-pick ecd878a60bd061912d395a5ea1f30d0729a360d0
[master 87dce58] fix urgent bug
Date: Thu Sep 9 11:44:55 2021 -0500
1 file changed, 1 insertion(+), 1 deletion(-)
a - b - c - d - f (fix urgent bug) master
\
e - f (fix urgent bug) - g - h dev
Copiar los cambios pero no el commit
En algunos casos no queremos copiar el commit como tal sino sólo los cambios, ya sea para hacer una revision antes o para hacer ajustes en el código.
git cherry-pick -n <commit hash>
Retomando el ejemplo anterior, en lugar de copiar directamente el commit podemos copiar los cambios y que queden en el stage.
cherry-pick-test on master
$ git cherry-pick -n ecd878a
cherry-pick-test on master
$ git status
On branch master
Changes to be committed:
(use git restore --staged <file>... to unstage)
modified: index.js
Nota: con git cherry-pick podemos usar la versión corta del hash.
Conflictos
Al igual que con git merge podemos tener conflictos al copiar un commit con git cherry-pick, en este caso git pausara el proceso de copia y nos pedirá resolver el conflicto.
Una vez resuelto el conflicto, tenemos que indicarle a git the estamos listos para reanudar el proceso de copia, con el siguiente comando:
git cherry-pick —continue
En caso de querer cancelar el proceso de copia podemos indicarlo con el siguiente comando:
git cherry-pick —abort
Copiar una serie de commits
git cherry-pick <commit A hash>..<commit B hash>
<commit A hash> y <commit B hash> son dos commits diferentes pertenecientes al mismo branch, git cherry-pick copiará todos los commits que encuentre entre el commit A y el commit B, excluyendo al commit A. Forzosamente commit A tiene que ser anterior al commit B.
Si queremos copiar todos los commits que encuentren entre el commit A y el commit B, incluyendo al commit A, el commando debe de ser el siguiente:
git cherry-pick <commit A hash>^..<commit B hash>
Resumen
git cherry-pick <commit hash>: para copiar un commit de otro branch en el branch actual.git cherry-pick -n <commit hash>: para copiar los cambios de un commit de otro branch en el branch actual.git cherry-pick —continue: para continuar con la copia de un commit después de resolver conflictos.git cherry-pick —abort: para cancelar la copia de un commit después de resolver conflictos.git cherry-pick <commit A hash>..<commit B hash>: para copiar todos los commits entre commit A y commit B excluyendo commit A.git cherry-pick <commit A hash>^..<commit B hash>: para copiar todos los commits entre commit A y commit B incluyendo commit A.
Espero que esta información sea de ayuda para tu día a día utilizando git.