git interpret-trailers para coding agents: parse, no reescribir el mensaje
Resumen
git interpret-trailers lee o añade trailers tipo RFC 822 al final del mensaje. --parse es el contrato de lectura. Cero --in-place autónomo, cero trailer.*.cmd y cero dump del parche. Distinto de commit --trailer, format-patch y am. 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 interpret-trailers añade o parsea trailers al final de un mensaje de commit. El man (git-interpret-trailers(1); git-scm.com/docs/git-interpret-trailers 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): Add or parse structured information in commit messages. DESCRIPTION: líneas que look similar to RFC 822 e-mail headers al final de la parte libre. SYNOPSIS: git interpret-trailers [--in-place] [--trim-empty] [(--trailer (<key>|<key-alias>)[(=|:)<value>])...] [--parse] [<file>...].
Contrato para un coding agent: lee con --parse. Es stdout. No toca el índice, ni HEAD, ni el working tree. Ante un mensaje, extrae Signed-off-by / Reviewed-by / Co-authored-by y para. No --in-place. No trailer.*.cmd. No vuelques el parche que viene después de ---. No reescribas el cuerpo.
No es commit: git commit --trailer crea un commit y usa esta herramienta por debajo. Aquí no hay objeto nuevo. No es format-patch: format-patch emite mbox; interpret-trailers puede operar sobre ese mbox sin tocar el diff. No es am: am aplica el mbox. Aquí el parche sale igual, salvo que pidas --no-divider.
Qué hace (y qué no)
Lee de <file>... o de stdin si no hay archivo. Sin --parse, aplica trailer.* del config y los --trailer de la línea de comando; el resultado va a stdout. Con --parse (alias de --only-trailers --only-input --unfold) ignora config y flags de escritura: solo imprime los trailers del input, unfolded.
Verificado 2026-09-06:
| Input | Comando | Salida | Exit |
|---|---|---|---|
subject + body, sin trailers | --parse | vacío | 0 |
body + Signed-off-by: Alice <[email protected]> | --parse | esa línea | 0 |
| body, sin trailers | --trailer 'Reviewed-by: Bob <[email protected]>' | mensaje + blank + trailer key: value | 0 |
| SOB de Alice | --trailer el mismo par | el original, sin duplicar | 0 |
| SOB de Alice | --if-exists replace --trailer 'Signed-off-by: Bob <…>' | Bob sustituye | 0 |
| SOB de Alice | --if-exists doNothing --trailer 'Signed-off-by: Bob <…>' | Alice intacta | 0 |
| SOB de Alice | --if-exists addIfDifferent --trailer Bob | Alice y Bob | 0 |
Fixes: y Cc: vacíos | --trim-empty | subject solo | 0 |
mensaje + --- + diff --git | --trailer 'Reviewed-by: Bob' | trailer antes del divider; el diff intacto | 0 |
Co-authored-by: Alice <[email protected]> | --parse | esa línea | 0 |
| valor folded en dos líneas | --parse | una sola línea | 0 |
| stdin | --in-place | fatal: no input file given for in-place editing | 128 |
| path inexistente | --trailer 'Foo: bar' /no/such/file | could not read input file | 128 |
El default de --if-exists es addIfDifferentNeighbor (man + git-config): no duplica el mismo (key, value) al lado. Por eso el mismo SOB de Alice no se reescribe. replace borra el trailer más cercano con esa key. doNothing no añade si la key ya existe, aunque el value sea otro.
--in-place exige archivo. Stdin → 128. No hay “editar el commit actual”: esto no mueve HEAD. Si el humano pide un trailer en un commit ya hecho, el camino es un commit nuevo o git commit --trailer antes de crear el objeto — no --in-place sobre .git/COMMIT_EDITMSG a ciegas.
Cómo extrae el bloque
El man: un grupo de una o más líneas que (i) son todas trailers, o (ii) contienen al menos un trailer generado por Git o configurado por el usuario y al menos 25 % trailers. El grupo va precedido de una o más líneas vacías. Está al final del input o es lo último no-blanco antes de una línea que empieza por --- (espacio o fin de línea).
Eso importa con format-patch: el mbox trae mensaje, divider --- y parche. Sin --no-divider, el comando no modifica divider ni patch. Verificado: el diff --git sale igual; el trailer nuevo se inserta en el mensaje.
Dentro de un trailer no hay whitespace en la <key>. Entre key y separador sí. El valor puede plegarse (línea siguiente con whitespace, estilo RFC 822). --unfold / --parse lo aplastan a una línea. No asumas encoding RFC 822: el man dice explícitamente que no siguen esas reglas.
Separador por defecto: : (un colon y un espacio) en la salida. En --trailer acepta = o : por compatibilidad. trailer.separators puede ampliar el set (:# para Fix #42); no lo toques en --global.
Config que un agente no debe escribir
trailer.<keyAlias>.key acorta --trailer sign: Alice a Signed-off-by. El alias es prefijo de la key (case-insensitive). trailer.where / --where: end (default), start, after, before. trailer.ifexists / --if-exists: addIfDifferentNeighbor (default), addIfDifferent, add, replace, doNothing. trailer.ifmissing / --if-missing: add (default) o doNothing.
trailer.<keyAlias>.cmd (y el deprecado .command) lanza un shell. El man: se llama una vez para auto-añadir el trailer y otra por cada --trailer <alias>=<value>, con el value como primer argumento. Ejemplos oficiales corren git log y scripts en ~/bin. Un coding agent no configura .cmd. No es un parser: es RCE con disfraz de trailer.
Tampoco commit.template con hook commit-msg que reescribe $1 vía --in-place o mv sin que el humano lo pida. El ejemplo del man existe; no lo copies a un repo ajeno.
La lectura segura no necesita config: --parse no aplica trailer.*. Verificado: --only-trailers --only-input --unfold equivale a --parse y sale 0 con el SOB de Alice.
Co-authored-by no es un verbo de Git
GitHub Docs Creating a commit with multiple authors (HTTP 200 el 2026-09-06; URL canónica /en/pull-requests/how-tos/commit-changes/creating-a-commit-with-multiple-authors tras 301 desde la ruta vieja): Add one or more Co-authored-by trailers to a commit message. Title: Creating a commit with multiple authors or on behalf of an organization. El trailer es convención de producto. Git lo trata como cualquier otra key. --parse lo extrae; no valida el email noreply ni cuenta contribuciones.
Si el humano pide co-autor, imprime el trailer canónico Co-authored-by: Name <email> y que lo pegue. No inventes el users.noreply.github.com. No mezcles Signed-off-by (DCO / -s de commit) con co-autoría.
git commit --trailer (man git-commit(1), git-scm.com/docs/git-commit HTTP 200, last-modified 2026-08-31) es el porcelain: añade el trailer al crear el commit y respeta trailer.*. interpret-trailers es el filtro. Un agente autónomo no corre ninguno de los dos contra un mensaje vivo.
Checklist del agente
- Diagnóstico:
git interpret-trailers --parsesobre el mensaje (stdin o archivo). Exit 0 aunque no haya trailers. - ¿Hay que añadir? Primero stdout sin
--in-place. Diff visual para el humano. Luego, si pide persistir un archivo,--in-placesobre ese path. - Duplicados: deja el default.
replacesolo si el humano pide sustituir la key. - Mbox de format-patch: no uses
--no-dividersalvo que el input sea solo el mensaje. - Cero
--in-placesobre stdin (128). Cero path inventado (128). Cerotrailer.*.cmd. Cero--globalen config. - No vuelques el parche al contexto:
--only-trailerso--parse. --trim-emptyborra trailers cuyo value es solo whitespace. Útil en templates. No lo corras “por si acaso” sobre un mensaje conFixes: 123real.

Errores que importan
--in-place sin archivo: fatal: no input file given for in-place editing, exit 128. Archivo ausente: fatal: could not read input file '…': No such file or directory, 128. Uso válido: 0, incluso cuando --parse no imprime nada.
No hay “tool-help” ni TTY. No abre GUI. No es interactivo. El riesgo no es FileMerge: es reescribir el mensaje o ejecutar .cmd.
git interpret-trailers -h lista --[no-]in-place, --trim-empty, --where, --if-exists, --if-missing, --only-trailers, --only-input, --unfold, --parse, --no-divider / --divider, --trailer. Verificado 2026-09-06, exit 0.
FAQ
¿Puedo usarlo para firmar un commit ya publicado? No. No mueve refs. El objeto commit es inmutable. Un trailer nuevo implica un commit nuevo (o un --amend que un agente no hace).
¿--parse respeta trailer.sign.key? No. El man: without influencing them with any command line options or configuration variables.
¿Es lo mismo que git commit -s? No. -s añade Signed-off-by del committer al crear. Esto filtra texto.
¿Puedo parsear git log -1 --format=%B? Sí, por stdin. No pases -p. El cuerpo basta.
¿Y un valor multilínea? --parse lo unfold. Verificado con el ejemplo del man (key: + continuación indentada) → una línea, exit 0.
Cuándo no usarlo
No lo uses para inventar DCO, para “arreglar” autoría ni para inyectar Reviewed-by en un PR ajeno. No lo uses como pretty-printer del parche. Si solo necesitas el SHA o el subject, commit ya cubre el porcelain y git log -1 --format=%s basta.
Siguiente lectura: el hub Comparativas y decisiones y el curso de instalar un agente.

Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git commit-graph para coding agents: índice de historia, no gc

git replace para coding agents: refs locales que mienten el SHA, no reescritura

git var para coding agents: una variable lógica, no el config
