Guía9 min

git cherry para coding agents: +/− por patch-id, no por SHA

Resumen

git cherry lista commits de head vs upstream con + o − según el diff (sin whitespace ni números de línea). − = equivalente ya aplicado (cherry-pick, am o rebase); + = falta. Sin tracking: 129. Cero args a ciegas. No es cherry-pick. Git 2.50.1.

GitHub
Una rama topic frente a upstream: commits marcados más o menos según el parche, no el SHA

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 encuentra commits de una rama que aún no tienen equivalente en upstream. El man (git-cherry(1); git-scm.com/docs/git-cherry HTTP 200, last-modified 2026-08-31; pie del man local Git 2.50.1.428.g0e8243, 2025-07-22; binario Git 2.50.1 / Apple Git-155): Find commits yet to be applied to upstream. SYNOPSIS: git cherry [-v] [<upstream> [<head> [<limit>]]].

No es cherry-pick. cherry-pick aplica un diff y graba un commit nuevo. git cherry solo imprime SHA con prefijo + o -. HEAD no se mueve. El working tree no importa.

El test de equivalencia (man) usa el diff después de quitar whitespace y números de línea. Detecta copias hechas con cherry-pick, am o rebase. SEE ALSO: git-patch-id(1).

Contrato: git cherry -v <upstream> <head> con upstream explícito. Cero invocación sin args. Cero tratar + como “pickea ya”.

Qué hace (y qué no)

El comando recorre los commits de <limit>..<head> (por defecto, desde el merge-base) y, para cada uno, busca un parche equivalente en <upstream>. Prefijo:

  • - = hay equivalente en upstream. El SHA local puede tirarse en un rebase.
  • + = no hay equivalente. Ese parche aún no está aplicado allá.

<upstream> por defecto es la rama upstream de HEAD. <head> por defecto es HEAD. <limit> (opcional) recorta: no reporta commits hasta ese SHA inclusive.

Verificado 2026-09-04 (Git 2.50.1 / Apple Git-155). Repo base → topic feat: A, feat: B, feat: C (archivos independientes). Se cherry-pickeó A y C sobre main:

  • git cherry main topic: 0. + B, - C. A no sale: es el merge-base (el <limit> por defecto lo incluye y lo excluye del reporte).
  • git cherry -v main topic: 0. Igual, con subjects feat: B / feat: C.
  • git cherry main con HEAD = main: 0, cero líneas. head y upstream son el mismo rango vacío de “qué le falta a main respecto de main”.
  • git cherry topic main (al revés): 0. - del commit de C en main (equivalente al C de topic). B no aparece: no está en main.
  • git cherry main topic <merge-base>: 0. Igual que sin limit cuando el limit es el merge-base.
  • git cherry --abbrev=7 main topic: 0. SHA cortos. Un agente no los reutiliza para pick.
  • Working tree sucio: 0, misma salida. El comando no mira el índice.
  • Tras git am del mailbox de B sobre main: 0. B y C salen -.
  • Dos commits “feat: D” con whitespace distinto (trailing spaces): 0. El de topic sale -. El man no miente: ignora whitespace.
  • Sin args, sin branch.<name>.merge: 129, Could not find a tracked remote branch, please specify <upstream> manually.
  • Cuarto argumento (main topic HEAD extra): 129, mismo usage.
  • --foo: 129, unknown option `foo'.
  • Fuera de un repo: fatal: not a git repository, 128.

+ falta en upstream; - ya hay equivalente por parche

Lo que el agente sí / no corre

QuieroComandoTrampa
¿Qué de topic no está en main?git cherry -v main topicgit cherry sin args
Subjects junto al SHA-v / --verbose--abbrev y luego pickear el corto
Recortar una base inéditatercer arg <limit>dump de log -p
Aplicar el +cherry-pick después, con SHA completogit cherry no aplica nada
Armar mailbox de lo que faltaformat-patch de esos SHAtratar + como ya enviado

Prohibido en autónomo:

  • Sin <upstream>. Verificado: 129 si no hay tracking. Un agente no “adivina” origin/main.
  • Confundir el binario con cherry-pick. Un typo git cherry <sha> no pickea: el SHA se lee como <upstream> y el resultado es otra lista (o vacío).
  • Tratar - como “borra el commit”. Solo dice “el parche ya está”. El objeto local sigue ahí.
  • Tratar + como “pickea ahora”. Equivalencia de parche ≠ el ticket. Un + puede ser WIP, secreto o un commit que el humano no quiere.
  • --abbrev. El default es SHA completo. Cortar dígitos es para un humano, no para el siguiente comando.
  • Cuarto argumento o flags inventados. Verificado: 129.
  • Volcar la salida a un LLM “para que decida el rebase”. El contrato es: imprimir, parar. Rebase / pick / am son otro comando, con working tree limpio y confirmación.
  • Usarlo como log. cherry no es historia; es un filtro de patch-id.

Receta (60 segundos)

Solo en un worktree propio. Upstream y head explícitos:

git status -sb
git cherry -v main topic

Leer la lista. + = parche que main no tiene. - = parche que main ya tiene (otro SHA da igual).

Si hay una base que no debe listarse (trabajo inédito debajo del topic):

git cherry -v main topic "$limit"

Cierre = la lista. Cero pick, cero am, cero rebase en el mismo paso. Cero push a main.

Sin tracking el comando pide upstream a mano; no adivina origin

cherry vs cherry-pick vs log

cherry-pick escribe un commit nuevo. git cherry lee. Si el ticket es “trae el SHA abc a esta rama”, pick. Si el ticket es “¿qué de topic aún no está en main?”, este comando.

log A..B es conjunto de commits por grafo. cherry es el mismo recorte más el test de parche. Un commit rebaseado cambia de SHA y log main..topic lo sigue mostrando; cherry lo marca - si el diff (sin whitespace) ya vive en main.

format-patch arma el mailbox. cherry no escribe .patch. am consume el mailbox y committea — y a partir de ahí cherry verá -.

git cherry exige un repo. Verificado: 128 fuera de Git.

Checklist

  • Worktree propio. git status -sb. Upstream y head nombrados.
  • git cherry -v <upstream> <head>. SHA completos. Cero --abbrev.
  • + = falta el parche. - = ya está. No borrar, no pickear en el mismo paso.
  • Sin tracking: no reintentar sin args. Poner el ref a mano.
  • Cierre = la lista. No push a main.

FAQ

¿git cherry SHA pickea ese commit? No. Un SHA suelto es <upstream>. Para aplicar, cherry-pick.

¿HEAD se mueve? No. Verificado: el log no cambia; solo stdout.

¿Hace falta un repo? Sí. Verificado: 128 fuera de Git.

¿Sin -v alcanza? Sí para SHA. -v añade el subject. Un agente autónomo usa -v para no adivinar el mensaje.

¿Whitespace distinto cuenta como otro parche? No. Verificado: trailing spaces → -. El man compara el diff sin whitespace.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. cherry no es cherry-pick: lista equivalencias, no aplica el árbol.