git cherry-pick

Ramas y merges

Aplicar los cambios de commits concretos sobre la rama actual


El comando 'git cherry-pick' aplica los cambios introducidos por uno o varios commits existentes sobre la rama actual y crea un commit nuevo por cada uno. A diferencia de merge o rebase, que trabajan con ramas enteras, cherry-pick te deja copiar commits concretos de forma selectiva. Es muy valioso para llevar hotfixes a ramas de release, recuperar commits perdidos o traer funcionalidades concretas de una rama a otra sin integrarlo todo. Cada commit copiado con cherry-pick recibe un SHA nuevo: es una copia, no un traslado. Cherry-pick es quirúrgico y preciso, y te da un control fino sobre qué cambios llegan a tu rama.

Sinopsis

git cherry-pick [--edit] [-n] [-m <parent-number>] [-s] [-x] [--ff] [-S[<keyid>]] <commit>...
git cherry-pick (--continue | --skip | --abort | --quit)
[ ] opcional| o<arg> valor a sustituir... repetible--flag opción

Opciones

Haz clic en una opción para desplegarla

Principiante (2)

Aplicar los cambios al directorio de trabajo y al índice sin crear un commit. Perfecto para combinar varios cherry-picks en un solo commit.

Cuando haga faltaJuntar varios cherry-picks en un solo commit

Ejemplo

git cherry-pick -n abc1234

Abrir el editor para modificar el mensaje antes del commit. Úsalo cuando quieras explicar por qué se copió el commit.

Cuando haga faltaAñade contexto al mensaje del commit copiado

Ejemplo

git cherry-pick -e abc1234

Intermedio (5)

Continuar el cherry-pick tras resolver los conflictos. Primero tienes que preparar los archivos resueltos con 'git add'.

RecomendadoContinúa después de que resuelvas y prepares los conflictos

Ejemplo

git cherry-pick --continue

Cancelar el cherry-pick y devolver la rama a su estado anterior. Úsalo cuando los conflictos sean demasiado complejos o elegiste el commit equivocado.

RecomendadoCancela con seguridad y restaura el estado previo al cherry-pick

Ejemplo

git cherry-pick --abort

Saltar el commit actual y seguir con los commits restantes de la secuencia. Los cambios del commit saltado NO se aplican.

Cuando haga faltaSalta un commit cuyos cambios ya no necesitas

Ejemplo

git cherry-pick --skip

Añadir '(cherry picked from commit ...)' al mensaje del commit. Ayuda a rastrear el origen de los commits copiados con cherry-pick.

RecomendadoRegistra el commit de origen: imprescindible al portar correcciones

Ejemplo

git cherry-pick -x abc1234

Añadir un trailer 'Signed-off-by' con tu nombre y tu correo. Algunos proyectos lo exigen por motivos legales o de auditoría.

Cuando haga faltaSolo si el proyecto exige líneas Signed-off-by

Ejemplo

git cherry-pick -s abc1234

Avanzado (2)

Conservar los commits que ya estaban vacíos de entrada (mismo árbol que su padre). Los commits que quedan vacíos porque sus cambios ya existen siguen deteniendo el proceso; para esos usa --empty=keep.

Cuando haga faltaSolo para commits que ya eran vacíos desde el principio

Ejemplo

git cherry-pick --allow-empty abc1234

Obligatorio al hacer cherry-pick de commits de merge. Indica qué padre (1 o 2) es la línea principal. Normalmente -m 1 para obtener los cambios de la rama integrada.

Cuando haga faltaObligatorio con commits de merge; normalmente -m 1

Ejemplo

git cherry-pick -m 1 abc1234

Experto (2)

Usar la estrategia de merge indicada al aplicar los cambios. Por defecto es 'ort' (o 'recursive' en Git antiguos). No tiene forma corta: aquí -s significa --signoff.

No recomendadoLa estrategia ort predeterminada casi siempre es la adecuada

Ejemplo

git cherry-pick --strategy=ort abc1234

Pasar opciones a la estrategia de merge. Habituales: 'theirs' (favorece los cambios elegidos), 'ours' (favorece lo actual), 'patience' (mejores diffs).

No recomendado-Xours / -Xtheirs descartan sin avisar un lado de los hunks en conflicto

Ejemplo

git cherry-pick -Xtheirs abc1234

Elegir la opción adecuada

git cherry-pick frente a comandos parecidos

Saber cuándo usar cherry-pick en lugar de merge, rebase o revert

ComandoAspectoCherry-pickOtro comando
ScopeSolo commits concretosMerge: la rama entera / Rebase: toda la rama
Creates new commitsSí: SHA nuevo, mismo contenidoMerge: commit de merge / Rebase: lo reescribe todo
Original staysSí: el original no se tocaMerge: sí / Rebase: huérfano
Use caseBackports, portar de forma selectivaIntegrar ramas completas
History effectCrea cambios duplicadosLo conserva o lo hace lineal
ConflictsPor commit durante el pickEn el punto de merge o por cada commit del rebase

Ejemplos de flujos de trabajo

1
git checkout release-1.0

Cambiarse a la rama de release

2
git log main --oneline

Encontrar el hash del commit del arreglo

3
git cherry-pick -x abc123

Aplicar el arreglo con la referencia de origen

4
git push origin release-1.0

Subir el arreglo portado

1
git checkout main

Cambiarse a la rama main

2
git log feature --oneline

Revisar los commits de la rama de funcionalidad

3
git cherry-pick abc123 def456

Elegir solo los commits listos

4
git push origin main

Subir los commits elegidos

1
git reflog

Encontrar el hash del commit en el reflog

2
git checkout main

Cambiarse a la rama de destino

3
git cherry-pick abc123

Aplicar el commit huérfano

1
git checkout target-branch

Cambiarse a la rama de destino

2
git cherry-pick A^..C

Aplicar los commits de A a C (incluidos)

3
git log --oneline

Comprobar que los commits se aplicaron

Solución de problemas

"commit is a merge but no -m option was given"

Causa: Intentas hacer cherry-pick de un commit de merge sin indicar qué padre

Usa -m 1 o -m 2 para indicar el padre de la línea principal

git cherry-pick -m 1 <merge-commit>

Conflictos durante el cherry-pick

Causa: Los cambios chocan con tu rama actual

Resuelve los conflictos en los archivos, haz git add y luego git cherry-pick --continue. O cancela con --abort

git add <resolved-files> && git cherry-pick --continue

"The previous cherry-pick is now empty"

Causa: Los cambios del commit ya existen en tu rama

Ejecuta 'git commit --allow-empty' para registrarlo igualmente, o 'git cherry-pick --skip' para saltarlo

git cherry-pick --skip

El cherry-pick creó commits duplicados

Causa: Los mismos cambios existen ahora como commits distintos en ramas distintas

Es el comportamiento esperado. Usa la opción -x para dejar constancia de la relación

git cherry-pick -x <commit>

Se hizo cherry-pick del commit equivocado

Causa: Elegiste el SHA de commit equivocado

Si no se ha subido: git reset --hard HEAD~1. Si ya se subió: haz git revert del commit copiado

git reset --hard HEAD~1

El cherry-pick parece no tener efecto

Causa: Puede que el commit esté vacío o que sus cambios ya estuvieran aplicados

Revisa git diff HEAD~1 para ver los cambios reales

git diff HEAD~1

Consejos y trampas

Buenas prácticas

  • ✓Usa -x en los backports para añadir la referencia '(cherry picked from commit ...)' al mensaje del commit
  • ✓Haz cherry-pick en orden cronológico: los commits dependientes deben aplicarse del más antiguo al más reciente para evitar conflictos
  • ✓Mejor merge en ramas compartidas: cherry-pick crea commits duplicados, mientras que merge conserva el historial
  • ✓Prueba después del cherry-pick: el commit puede funcionar en su contexto original y fallar en el nuevo
  • ✓Documenta los cherry-picks en los mensajes con la opción -e para explicar por qué se copió el commit
  • ✓Usa --no-commit para combinar picks relacionados en un único commit más limpio
  • ✓Plantéate usar git cherry en lugar de log para encontrar commits que aún no se han aplicado
  • ✓En los backports, incluye siempre el hash del commit original en el mensaje para poder rastrearlo

Errores comunes

  • ✗Olvidar -m en los commits de merge. Hacer cherry-pick de un commit de merge sin '-m 1' o '-m 2' falla: debes indicar respecto a qué padre calcular el diff.
  • ✗No preparar los archivos resueltos antes de --continue. Tienes que ejecutar 'git add' sobre los archivos resueltos antes de 'git cherry-pick --continue'.
  • ✗Esperar el mismo hash de commit. Cherry-pick crea commits NUEVOS con SHA nuevos: copia cambios, no mueve commits.
  • ✗Hacer cherry-pick de commits ya aplicados. Provoca conflictos o commits vacíos: compruébalo antes con 'git log'.
  • ✗Elegir los commits en el orden equivocado. Los commits dependientes deben tomarse del más antiguo al más reciente; si no, tendrás conflictos.
  • ✗Usar cherry-pick en ramas públicas crea commits duplicados cuando otros tienen el original: mejor merge en ramas compartidas.

Preguntas frecuentes

A:

No. Cherry-pick crea un commit NUEVO con los mismos cambios pero un SHA distinto. El commit original se queda donde estaba.

A:

El hash de un commit de Git depende del contenido, el padre, el autor, la fecha y el mensaje. Cherry-pick conserva el autor y la fecha de autoría, pero el padre y la fecha del committer cambian, así que el hash cambia aunque los cambios sean idénticos.

A:

¡Sí! Enuméralos: git cherry-pick A B C, o usa rangos: git cherry-pick A^..C (incluye A y C).

A:

Usa la opción -m: git cherry-pick -m 1 <merge-commit>. El número indica qué padre es la línea principal (normalmente 1).

A:

A..B excluye A (los commits posteriores a A hasta B). A^..B incluye A (los commits de A a B, ambos incluidos).

A:

Si no se ha subido: git reset --hard HEAD~1. Si ya se subió: git revert <commit> para crear un commit que lo deshaga.

A:

Cherry-pick para commits concretos. Rebase para mover ramas enteras. Si necesitas la mayoría de los commits de una rama, rebase es más limpio.