git format-patch para coding agents: mailbox, no un diff suelto
Resumen
git format-patch arma un mbox por commit no-merge. -1 SHA = ese commit; SHA solo = todo lo posterior. -o dir o --stdout. Cero --root/--signoff/--cover-letter. Git 2.50.1.

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 format-patch prepara cada commit no-merge como un mensaje tipo mailbox. El man (git-format-patch(1); git-scm.com/docs/git-format-patch HTTP 200, last-modified 2026-08-31, last updated in 2.55.0; pie del man local Git 2.54.0, 2026-04-19; binario Git 2.50.1 / Apple Git-155): Prepare each non-merge commit with its "patch" in one "message" per commit, formatted to resemble a UNIX mailbox. El output es para correo o para git am. SEE ALSO: git-am(1), git-send-email(1).
No es diff. Diff imprime hunks; este comando añade From, Date, Subject y un -- al final. Tampoco apply: apply pega. format-patch escribe archivos (o stdout). HEAD no se mueve. El reverso para aplicar y committear es am.
Contrato: -1 para un SHA, -o o --stdout para no ensuciar el cwd, cero --root / --signoff / --cover-letter autónomo.
Qué hace (y qué no)
Un mensaje tiene tres partes (man): cabecera From <commit> con fecha fija Mon Sep 17 00:00:00 2001 (para que file(1) lo reconozca), cuerpo del log, y el parche separado por ---. Autor y título salen del commit. El SHA del From es el original; am hará un SHA nuevo.
Dos formas de elegir commits (man):
- Un solo
<since>: commits de la punta actual que no están en la historia de ese since. - Un
<revision-range>. Un SHA suelto entra por la regla 1. Para “solo ese commit”:git format-patch -1 <commit>. Para “desde el origen hasta<commit>”:--root.
Verificado 2026-09-04 (Git 2.50.1 / Apple Git-155), repo feat: a → feat: change b → feat: change c:
- Sin argumentos: 0, cero archivos.
git format-patch -1: 0,0001-feat-change-c.patchen el cwd, untracked. Log intacto.--stdout -1: 0, el mbox en stdout, cero archivos.-o dir -1: 0, el archivo vive endir. El cwd no gana otro.patch.- SHA de
feat: asin-1: 0,0001-feat-change-b.patchy0002-feat-change-c.patch. No emitea. -1del mismo SHA: 0, solo0001-feat-a.patch.git format-patch mainentopic(un commit extra): 0, un parche. Equivale a “lo quetopictiene ymainno”.main..topic: solo el commit de topic.main...topic(simétrica): los dos lados (feat: gyfeat: h).- Merge
--no-ffen HEAD:-1salta el merge y emite el no-merge previo (feat: h).-5no crea archivo del merge. - Working tree sucio: 0, igual escribe el parche. El comando no mira el índice.
- Fuera de un repo: fatal: not a git repository, 128.
--signoff: 0, trailerSigned-off-by: t <t@t>(identidad del committer ahora).--cover-letter -2: 0,0000-cover-letter.patchextra.--rfc: Subject[RFC PATCH] ….-k: Subject sin[PATCH].-n -1: Subject[PATCH 1/1].--numbered-files -2: archivos llamados1y2, sin.patch.--root HEAD: un archivo por commit de la historia (4 en el fixture).--allow-emptyreciente:-1sí emitió un mailbox corto (8 líneas, sin diff) sin--always.- Binario: el parche lleva
GIT binary patch/literal.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| Un commit | git format-patch -1 -- "$sha" | git format-patch "$sha" (rango) |
Serie vs main | git format-patch main (estando en topic) | --root |
| Un mbox | -1 --stdout | volcar el mbox al LLM |
| Archivos en carpeta | -o "$dir" | cwd lleno de 0001-*.patch |
| Pegar el parche | apply --check | creer que format-patch ya aplicó |
| Aplicar el mbox a commits | am | git apply del mismo archivo |
| Traer el SHA del grafo | cherry-pick | format-patch + am “por si acaso” |
Prohibido en autónomo:
- SHA sin
-1. El man: un solo commit es<since>, no “ese commit”. Verificado: emite los posteriores. --root. Toda la historia a disco.- Sin
-oni--stdout. Ensucia el worktree con untracked0001-*.patch. Verificado: status?? 0001-…. --signoff/-s. Firma tu identidad. Un agente no pone DCO por Marco.--cover-letter. Inventa0000-cover-letter.patchpara que un humano lo edite.--rfc,-v/--reroll-count,--subject-prefix. Cambian el Subject queamva a committear.--numbered-files. Nombres1,2sin sufijo: fáciles degit addpor error.--thread/--attach/--in-reply-to/--to/--cc. Correo, no un agente.--notes. Mete notas al mailbox.--always“por si el empty no sale”. En 2.50.1 el empty ya salió.A...Bcuando el ticket esA..B. Verificado: la simétrica mete ambos lados.- Tratar el SHA del
From:como “el objeto que vas a tener después deam”.amcrea SHA nuevo.
El mbox se consume con am. Un agente que reescribe el From: / hunk a mano está un paso más allá de este comando.
Receta (60 segundos)
Solo en un worktree propio. Un SHA o un since explícito:
git status -sb
mkdir -p /tmp/patches
git format-patch -1 -o /tmp/patches -- "$sha"
ls /tmp/patches
Un mbox a stdout (sin archivos en el repo):
git format-patch -1 --stdout -- "$sha" > /tmp/one.mbox
Serie de la rama vs main:
git format-patch -o /tmp/patches -- main
Si el rango es dudoso: para. Cero --root. Cero SHA suelto “a ver qué sale”.
Cierre = entregar el mbox / los .patch, no add de esos archivos al repo. Cero push a main.

format-patch vs diff vs apply
diff es hunks. format-patch es correo: From, Subject, --- y el parche. apply pega bytes y no committea. am parte el mailbox y sí committea.
Un agente que “exporta el PR” con git diff main no replica autor ni mensaje. Si el ticket es “arma un mbox para am”, este comando. Si el ticket es “muéstrame el delta”, diff --stat. Si el ticket es “trae el SHA abc”, cherry-pick.
El man (CAVEATS, heredado del flujo am): un diff sin indentar en el mensaje de commit puede aplicarse como parche. No “arreglar” el mbox a ciegas.
format-patch exige un repo. Diff de working tree no.
Checklist
- Worktree propio.
git status -sb. Destino-oo--stdout. - Un commit =
-1 -- "$sha". Serie vs rama =git format-patch -- main. - Cero SHA suelto, cero
--root, cero--signoff/--cover-letter/--rfc. - No add los
.patchal índice. - Cierre = mbox fuera del repo. No push a
main.
FAQ
¿git format-patch SHA es ese commit? No. Un SHA suelto es <since>. Verificado: emite los posteriores. El commit solo es -1.
¿HEAD se mueve? No. Verificado: el log no cambia; aparecen untracked.
¿Hace falta un repo? Sí. Verificado: 128 fuera de Git.
¿--signoff “por si el proyecto usa DCO”? No. El trailer es la identidad del proceso. Nunca en autónomo.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. format-patch no es apply: escribe el mailbox, no pega el árbol. El reverso es am.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git merge-tree para coding agents: merge en seco, sin tocar el índice

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

git am para coding agents: mailbox a commits, no un diff suelto
