¿Qué es un cherry pick en git?

Como sabemos GIT es uno de los sistemas de control de versiones mas populares en la industria y dispone de muchas funciones como la creación de ramas, commits, merge, rebase etc.

En este post vamos a analizar justo una de sus funciones llamada cherry pick la cual nos podría salvar de algún momento desagradable.

Supongamos el siguiente escenario:

Estamos trabajando para una empresa que está desarrollando en una aplicación web X y tenemos lista la primer versión de nuestro proyecto y siguiendo el flujo normal de git hacemos lo siguiente:

git init #inicializamos el repositorio
git add . #agregamos todos los archivos a nuestro repositorio
git commit -m "Version 1 de la aplicacion X" #

Recuerden esto es solo una suposición en un proyecto real probablemente no haremos el primer commit con la versión 1 completa.

Muy bien continuemos...

Ya que tenemos lista esta primer versión nos empezamos a trabajar en los primeros fixes y cambios a la aplicación por lo que empezamos con la creación de ramas por feature o por fix haciendo algo como esto

git branch nuevo-feature
git checkout nuevo-feature

Dentro de este branch se nos pide modificar el color de header de nuestra aplicación y modificar las opciones del menú.

Empezamos cambiando el color del header y hacemos nuestro commit

git add header.js
git add esitlos.css
git commit -m "Cambio de color en el header"

Y continuamos cambiando ahora las opciones del menú y eso lo vamos a hacer en varios commits, entonces hacemos lo siguiente:

git add menu.js
git commit -m "Cambio de la opcion 1 del menu"
git add menu_responsivo.js
git commit -m "Cambio de la opcion 1 del menu responsivo"

Llegamos al lunes y temprano en una junta nuestro jefe nos dice que necesita que el nuevo color del header lo necesitamos ya en producción y hay que pasarlo a la rama main (recuerden que siguiendo el estándar de github master no se usa más como rama principal) y entonces entramos en pánico por que aun que ese cambio ya está listo el resto de cambios en la rama aun no están listos y ahora que hacemos...

Bueno el cherry pick está ahí para salvarnos la vida ya que esta característica de git nos va a permitir traernos commits de un branch a otro sin tener que hacer un merge o un rebase.

¿Y bueno esto como se hace?

Primero en nuestro branch nuevo-feature vamos a hacer un git log para ver todos nuestros commits.

Deberíamos ver algo así:

commit a4d05f9ad128329095074f14255bf24a28c300f7 (HEAD -> nuevo-feature)
Author: Leonardo Alonso <usuario@empresa.com>
Date:   xxxxxxxxxxxxxxxxx

    Cambio de color en el header

commit 12ceg453529095074f14255bf24a2832443dfg3 (HEAD -> nuevo-feature)
Author: Leonardo Alonso <usuario@empresa.com>
Date:   xxxxxxxxxxxxxxxxxxx

    Cambio de la opcion 1 del menu

commit 2343425324ef23432423asd14255bf24a28c553f (HEAD -> nuevo-feature)
Author: Leonardo Alonso <usuario@empresa.com>
Date:   xxxxxxxxxxxxxxxxxxxx

    Cambio de la opcion 1 del menu responsivo

Entonces solo queremos el cambio del color del header no todos los demás así que nos copiamos el hash de ese commit y nos cambiamos de rama a main

git checkout main

Ya con el hash del commit que necesitamos vamos a hacer

git cherry-pick a4d05f9ad128329095074f14255bf24a28c300f7

Cabe mencionar que aquí estamos usando el hash completo sin embargo si usáramos más opciones en nuestro comando git log seguramente el hash seria más corto pero eso lo veremos en otro post.

Continuando, una vez que corremos el comando cherrypick lo que va a pasar es que a nuestra historia del branch main se le sumara el commit que elegimos de esa forma no necesitamos hacer un merge de todo el branch.

¿Está muy bien no? Bueno pues aún con lo practico que esto parece resulta ser que cherry-pick es una mala práctica y debe ser usada únicamente cuando en verdad no vemos otra opción ya que seguramente cuando hagamos el merge de todas las ramas con fixes y nuevos features nos vamos a tomar con muchos conflictos que habrá que resolver.

Pues bueno ahora tienen a su disposición una herramienta más de git que deberán utilizar con mucha responsabilidad.