Guía10 min

git cherry-pick para coding agents: un commit nuevo, no copiar el SHA

Resumen

git cherry-pick aplica el diff de un commit existente y graba uno nuevo. Exige working tree limpio. Conflicto: CHERRY_PICK_HEAD y --abort. -x anota origen solo sin conflicto. Un agente no pickea merges a ciegas ni resuelve <<<<<<<. Man git-cherry-pick 2.50.1.

GitHub
Un commit C se aplica sobre otra rama y nace C′ con SHA distinto

Qué resuelve

Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.

git cherry-pick aplica el cambio que introdujo un commit ya existente y graba un commit nuevo por cada uno. El man (Git 2.50.1 / Apple Git-155): “Apply the changes introduced by some existing commits.” El SHA original no se reutiliza. El working tree tiene que estar limpio (sin modificaciones respecto a HEAD).

No es reset (mueve HEAD) ni restore (copia paths). git revert es el inverso: graba commits que deshacen un parche. GitHub Desktop también cherry-pickea desde la UI; un coding agent usa el CLI y el sequencer.

Esta guía no sustituye worktrees ni PRs con gh. El contrato: cuándo un agente puede pickear, qué flags están prohibidos, y cómo abortar.

Qué hace (y qué no)

Un commit C sobre topic no “vive” en maint hasta que alguien vuelve a aplicar su diff. git cherry-pick C sobre maint crea C′: mismo parche (si aplica limpio), autor original, committer = tú, SHA distinto.

El man: si el cambio no es obvio de aplicar:

  1. La rama y HEAD se quedan en el último commit exitoso.
  2. CHERRY_PICK_HEAD apunta al commit que no aplicó.
  3. Paths limpios se actualizan en index y disco.
  4. Paths en conflicto: hasta tres versiones en el index (como un true merge) y marcadores <<<<<<< / >>>>>>> en el working tree.
  5. Nada más se toca.

No hay merge commit. No hay rebase. Es un parche replay.

El parche de C se aplica sobre otra punta y nace C′

Lo que el agente sí / no corre

QuieroComandoTrampa
Backport de un SHA a mi topicgit cherry-pick -x <sha>-x solo si no hay conflicto. El man: no uses -x si pickeas de una rama privada
Parar a mitadgit cherry-pick --abort--quit olvida el sequencer y no vuelve al estado previo
Seguir tras resolver a manogit add paths + git cherry-pick --continue--continue lee .git/sequencer. Headless no resuelve <<<<<<<
Saltar este commit del rangogit cherry-pick --skipSolo con secuencia en curso. No “salta” un SHA suelto
Aplicar sin commiteargit cherry-pick -n <sha>Deja el diff en index/disco. El index no tiene que coincidir con HEAD
Fast-forward si HEAD es el padregit cherry-pick --ff <sha>Si no es el padre, crea commit nuevo igual

Prohibido en autónomo:

  • Cherry-pick con working tree sucio. El man lo exige limpio. Un dirty tree + pick es el mismo agujero que mergear sucio.
  • Cherry-pick de un merge commit sin -m <n>. El man: “Usually you cannot cherry-pick a merge because you do not know which side of the merge should be considered the mainline.” -m 1 no se adivina. Default del agente: no pickear merges.
  • -X ours / -X theirs. Pasa opciones al strategy de merge. Un agente no elige un lado.
  • Rangos (maint..next, ^HEAD master) salvo ticket que nombre exactamente el conjunto. Default: un SHA, o lista explícita de SHAs.
  • --allow-empty / --empty=keep “por si acaso”. Default de --empty es stop: el pick se detiene si el commit se volvió vacío. Commits que ya eran vacíos fallan salvo --allow-empty o --empty=keep.
  • --continue después de borrar marcadores a ciegas. Reporta git diff --name-only --diff-filter=U y --abort.
  • Cherry-pick sobre main local + push. El backport va a una rama topic y un PR.
  • Confundir el SHA nuevo con el original y force-push “para que coincidan”.

-x añade (cherry picked from commit …) al mensaje solo si no hubo conflicto. Sirve para backport entre ramas públicas (fix en nextmaint). En una rama privada el dato no le sirve a nadie.

--abort cancela y vuelve al estado pre-secuencia. El ejemplo oficial: abort preserva modificaciones locales que ya tenías. --quit solo limpia el sequencer.

Receta (60 segundos)

Solo en un worktree propio, working tree limpio, SHA nombrado (no HEAD~3 “el de ayer”):

git status -sb                    # limpio; no cherry-pick in progress
git rev-parse --verify <sha>^{commit}
git cherry-pick -x <sha>

Conflicto:

git diff --name-only --diff-filter=U
git cherry-pick --abort

El ejemplo del man, si el humano pide reintentar con más contexto:

git cherry-pick --abort
git cherry-pick -Xpatience <sha>

-Xpatience es strategy-option de ort/patience, no magia. Si vuelve a pelear: abort y reporta. No --continue.

Varios SHAs en orden, no un rango opaco:

git cherry-pick -x abc123 def456

Cada uno genera su commit. Si el segundo falla, HEAD quedó en el primero; CHERRY_PICK_HEAD apunta al que no aplicó.

Cherry-pick vs revert vs merge

ComandoHistoriaUso del agente
cherry-pick CCommit nuevo con el diff de CBackport de un fix a otra línea
revert CCommit nuevo que deshace el diff de CDeshacer un merge/commit ya publicado, vía PR
merge de la ramaUne historias; puede crear commit de fusiónIntegrar un topic entero, no un parche suelto

Pickeear “todo lo de feature” es un merge (o un rango que el ticket liste). Un agente no traduce “trae esos cambios” a cherry-pick feature.

git cherry-pick --ff ...next (ejemplo del man): si la historia es lineal y HEAD es ancestro de next, avanza HEAD. Eso es un fast-forward disfrazado, no un backport. No lo uses para “sincronizar main”.

Conflicto: aborta; no resuelvas marcadores a ciegas

Checklist

  • Worktree propio, git status -sb limpio, sin sequencer previo.
  • Un SHA (o lista explícita). Cero merges sin -m pedido por escrito.
  • -x solo entre ramas públicas y si el pick sale limpio.
  • Conflicto → --abort + paths. Cero --continue autónomo.
  • El commit nuevo va a una rama topic + PR. Cero pick sobre main.
  • SHA nuevo ≠ SHA origen. No force-push para “igualarlos”.
  • Vacío: no --allow-empty ni --empty=keep sin ticket.

FAQ

¿Puedo pickear un merge con -m 1? El man lo permite: -m es el número de padre (desde 1) que cuentas como mainline, y replayea el cambio respecto a ese padre. Un agente no elige 1 vs 2. Si el ticket no dice el padre, no pickea el merge.

¿-n es más seguro? --no-commit aplica al index/disco y no crea commit. Útil para inspeccionar varios diffs juntos. Sigue exigiendo (salvo -n) que partas de un árbol conocido; con -n el pick es contra el inicio del index. Headless: no lo uses para “acumular y ya commiteo yo” sin git diff --cached revisado.

¿--skip vs --abort? Skip descarta este commit de la secuencia y sigue. Abort tira toda la secuencia y vuelve atrás. Con un solo SHA, abort.

¿El autor se conserva? Sí el original; el committer es quien pickea. Por eso el SHA cambia. -s añade Signed-off-by; no lo pongas si el repo no lo pide.

¿GitHub Desktop? La doc de Desktop (200, 2026-09-03) cherry-pickea en la GUI. El agente no abre Desktop; corre el man.

El curso instalar un agente cubre el loop local. Aislamiento: sandboxing. Cherry-pick reescribe parches, no es sandbox.

Verificado 2026-09-03 contra git-cherry-pick(1) y git-revert(1) (Git 2.50.1 / Apple Git-155) y GitHub Desktop cherry-pick (HTTP 200).