Guía9 min

git stripspace para coding agents: limpia el mensaje, no el parche

Resumen

git stripspace lee stdin y limpia metadatos como lo hace Git: trailing whitespace, líneas vacías y un \n final. Es para mensajes de commit, notes y tags. Cero --strip-comments autónomo sobre un mensaje que el humano escribió. Distinto de apply --whitespace=fix y de commit --cleanup. Git 2.50.1.

GitHub
Un coding agent limpia el mensaje de commit por stdin; el working tree no se toca

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 stripspace limpia texto por stdin. El man (git-stripspace(1); git-scm.com/docs/git-stripspace HTTP 200, last-modified 2026-08-31; last updated in 2.50.0; pie del man local Git 2.50.1.428.g0e8243, 2025-07-22; binario Git 2.50.1 / Apple Git-155): Remove unnecessary whitespace. DESCRIPTION: Read text, such as commit messages, notes, tags and branch descriptions, from the standard input and clean it in the manner used by Git. SYNOPSIS: git stripspace [-s | --strip-comments] o git stripspace [-c | --comment-lines].

Contrato para un coding agent: sí puedes usarlo sobre un mensaje que tú generaste, por stdin, y leer el stdout. No reescribe el working tree. No toca el index. No crea commits. El man es explícito: This is intended for cleaning metadata. Prefer the --whitespace=fix mode of git-apply(1) for correcting whitespace of patches or files in the repository. Un agente que “arregla trailing spaces” del código con stripspace está en el verbo equivocado.

No es commit: commit escribe un objeto y mueve HEAD. stripspace solo imprime. No es apply: apply pega un parche; --whitespace=fix es el modo para archivos. No es commit --cleanup=strip: ese flag vive dentro de commit y, además, quita comentarios. stripspace sin flags deja las líneas que empiezan con #.

Qué hace (y qué no)

Sin flags, el man promete cuatro cosas:

  1. Quita trailing whitespace de todas las líneas.
  2. Colapsa varias líneas vacías consecutivas en una.
  3. Quita líneas vacías al principio y al final.
  4. Añade un \n al final si faltaba.

Si el input es solo whitespace, no hay output. Verificado 2026-09-06 (Git 2.50.1 / Apple Git-155): printf ' \n\n ' → stdout vacío, exit 0. printf '' y printf '\n\n' también vacíos, exit 0. printf 'hello' (sin newline) → hello\n, exit 0. El \n final se añade; no es un no-op.

El ejemplo del man (líneas con espacios al final, comentarios #, bloques vacíos) coincide byte a byte. Verificado con el mismo input ruidoso: sale el párrafo limpio, con las dos líneas comentadas, un solo blank entre bloques, sin trailing spaces. Exit 0.

Una línea que es solo espacios se vuelve una línea vacía y luego se colapsa. Verificado: a\n \nb\na\n\nb\n.

stripspace no lee paths. No hay <file>. No hay -- pathspec. Si le pasas un filename como argumento, Git lo trata como opción desconocida o lo ignora según el parseo: el contrato útil es stdin → stdout. Verificado: git stripspace --unknownerror: unknown option `unknown', usage de las dos formas, exit 129.

Stdin sucio entra; stdout sale con un solo blank y newline final

Flags: -s y -c no conviven

FlagManAgente
(ninguno)Trailing WS, blanks, \n final; no quita #Sí, sobre tu mensaje
-s / --strip-commentsSkip and remove all lines starting with a comment character (core.commentChar, default #)Cuidado. Borra líneas que el humano pudo querer
-c / --comment-linesPrepend the comment character and a blank space to each line. En líneas vacías, solo el carácterSí, para fabricar un bloque de comentario. No para “arreglar” un mensaje
-s + -cNo documentado como comboFatal. Verificado: options '-c' and '-s' cannot be used together, 129

--strip-comments borra las líneas # ... y deja el resto limpio. Verificado con el ejemplo del man: salen tres párrafos, sin las dos líneas de comentario, exit 0. -s es el mismo flag.

--comment-lines añade el prefijo. Verificado: hello\n\nworld# hello\n#\n# world\n. Línea vacía → # sin espacio extra. Input vacío → stdout vacío, exit 0.

core.commentChar cambia el carácter. Verificado: git -c core.commentChar=; stripspace -s con keep\n; drop\n# keep hash\nkeep\n# keep hash\n. El ; se trata como comentario; el # sobrevive. Un agente no pisa core.commentChar global: eso es config local.

Dónde sí y dónde no

Sí (metadatos):

  • Mensaje de commit que vas a pasar a git commit -m o a commit-tree por stdin. Limpia trailing spaces y blanks antes de grabar.
  • Texto de notes que el agente genera. El man cita notes, tags y branch descriptions.
  • Normalizar un subject de Conventional Commits que salió con espacios al final.

No:

  • Archivos del working tree. No hay path. Si quieres arreglar un parche, apply --whitespace=fix (el man de stripspace lo dice; strip es sinónimo histórico de fix en apply).
  • “Quitar comentarios del mensaje que el humano escribió en $EDITOR.” -s borra esas líneas. commit --cleanup=strip hace algo parecido dentro de commit: Strip leading and trailing empty lines, trailing whitespace, commentary and collapse consecutive empty lines. --cleanup=whitespace es Same as strip except #commentary is not removed — eso es el default de stripspace sin -s.
  • Reformatear código. Un src/index.ts no es un commit message.
  • Pisar am / format-patch. Esos tienen su propio flujo de mbox.

El man de commit (git-commit(1); git-scm.com/docs/git-commit HTTP 200, last-modified 2026-08-31) documenta --cleanup=<mode>: strip, whitespace, verbatim, scissors, default. default = strip si hay editor, whitespace si no. Un agente que ya manda -m no entra al editor; cleanup cae a whitespace salvo que pidas strip. No mezcles los dos verbos: stripspace es el filtro; commit es el objeto.

Flujo seguro

  1. Genera el mensaje (subject + blank + body). Nada de git commit -a.
  2. printf '%s' "$MSG" | git stripspace → captura stdout. Exit 0 con stdout vacío = el mensaje era solo whitespace: no commits vacíos; para y reescribe.
  3. No pases -s salvo que el mensaje sea un template con comentarios # que metiste (estilo scissors). El humano no marcó esas líneas para borrarlas.
  4. No pases -c para “comentar el mensaje”. Eso fabrica un bloque # línea listo para un archivo de plantilla, no para -m.
  5. Commit con -m + el texto ya limpio. Cero --allow-empty. Cero --amend. Ver commit.
  6. Whitespace de código: git apply --whitespace=fix o el linter del repo. Cero stripspace sobre el diff.

Comentarios # se quedan sin -s; con -s desaparecen

Checklist:

  • Stdin → stdout. Cero paths. Cero working tree.
  • Exit 0 + stdout vacío = no hay mensaje. No lo conviertas en commit.
  • Cero -s sobre texto del humano.
  • Cero -s y -c juntos (129).
  • Cero core.commentChar global.
  • Parche / archivo = apply --whitespace=fix, no este comando.

FAQ

¿Puedo usarlo en CI para “normalizar” todos los commit messages del historial? No reescribas historia. stripspace no mueve HEAD; un bucle que recommitea sí. Si el humano pide un mensaje limpio nuevo, fíltralo. El pasado se queda.

¿Es lo mismo que echo "$MSG" | tr -d ' '? No. stripspace no borra espacios interiores. Solo trailing, blanks colapsados, bordes y el \n final. tr destrozaría el subject.

¿--strip-comments respeta core.commentString? El man de stripspace nombra core.commentChar. git-config(1) (HTTP 200, last-modified 2026-08-31) documenta core.commentChar y core.commentString para commit/tag. No asumas que un string de varios caracteres se comporta igual aquí: verifica con -c core.commentChar=X sobre un input de prueba, no lo cambies en el repo del humano.

¿Por qué el man manda a apply? Porque builders pegan stripspace a un diff. apply --whitespace=<action> (nowarn|warn|fix|error|error-all) opera sobre líneas nuevas del parche. fix (sinónimo strip en apply) corrige trailing WS y space-before-tab del indent. Distinto universo.

¿Y las notes? notes add -m acepta el texto ya limpio. No abras el editor. stripspace el -m antes. Cero notes merge.

Si estás armando el agente desde cero, el curso de instalar un agente cubre el loop y las tools. El hub de comparativas agrupa el resto de verbos Git. Esta guía es la regla del filtro: limpia el mensaje, no el árbol.