Qué escribe Claude Code en tus commits
Claude Code añade el trailer Co-authored-by y, en sesiones cloud, un enlace a claude.ai. Comprueba el texto real y contrólalo antes de hacer push.
Qué incluye Claude Code en un commit
Claude Code añade un remate Co-authored-by: al final de los mensajes de commit que escribe y una línea de atribución a las descripciones de las pull requests que abre. Las sesiones que se ejecutan en la nube o mediante Remote Control también añaden un enlace a la sesión en claude.ai. Todo se almacena como texto sin formato dentro del historial de git. Cuando se publica en un repositorio público, pasa a ser público y permanece allí hasta que alguien reescribe el historial.
La redacción exacta ha cambiado entre versiones. Por tanto, no confíe en una copia del remate incluida en ninguna guía, incluida esta. Lea sus propios commits. Los comandos de git que aparecen a continuación son la parte estable de este tema: el manejo de remates de git funciona de la misma forma desde hace años y seguirá funcionando así aunque la próxima versión cambie el texto.
Qué es realmente un trailer de Git
Un trailer es una línea con un formato como Token: value en el último bloque del mensaje de un commit. Git no incluye una lista fija de tokens. Signed-off-by:, Reviewed-by:, Fixes: y Co-authored-by: son convenciones basadas en el mismo mecanismo, y un forge, es decir, el sitio que aloja el repositorio como GitHub o GitLab, los lee para decidir qué mostrar en la página del commit.
Git aplica reglas estrictas a la ubicación de ese bloque. La documentación de git interpret-trailers indica que el grupo debe estar precedido por una o más líneas vacías, debe encontrarse al final del mensaje o inmediatamente antes de una línea que empiece por ---, y debe contener únicamente trailers o bien "contener al menos un trailer generado por Git o configurado por el usuario y estar compuesto por al menos un 25% de trailers".
Esta última regla es importante en este caso. Una URL aislada o una línea de texto dentro del bloque final no es un trailer, y si hay suficientes líneas que no son trailers, todo el bloque deja de interpretarse como un bloque de trailers. Por eso un commit puede parecer que incluye una línea Co-authored-by:, mientras que cualquier herramienta que lea correctamente los trailers no encuentra nada.
¿Cómo leo los trailers que ya están en mi historial?
Empiece por el mensaje sin procesar del commit más reciente.
git log -1 --format=%B%B muestra el asunto y el cuerpo exactamente como están almacenados, sin ajuste de línea ni reformateo. Esa salida es la fuente de verdad. Todo lo que muestra una forja es una representación de ese contenido.
Ahora pregunte a git cuáles de esas líneas cuenta como trailers.
git log -1 --format=%B | git interpret-trailers --parse--parse es una forma abreviada de --only-trailers --only-input --unfold, por lo que la salida contiene únicamente el bloque de trailers. Un resultado correcto tiene una línea por trailer. Una salida vacía cuando puede ver claramente una línea Co-authored-by: indica que el bloque no cumple las reglas de ubicación anteriores.
Para revisar todo el historial, solicite el trailer por clave.
git log --format='%h %(trailers:key=Co-authored-by,valueonly)'Las versiones antiguas de git no admiten la opción key= en %(trailers). Una búsqueda en el texto del mensaje funciona en cualquier versión.
git log -i --grep='^Co-authored-by:' --format='%h %an %s'--grep busca coincidencias en el mensaje del commit y -i ignora mayúsculas y minúsculas. Esto es importante porque las herramientas no siempre han usado la misma capitalización para este trailer. Antes de hacer push, limite la consulta a lo que aún no ha enviado.
git log origin/main..HEAD --format=%BEsos commits todavía son locales, por lo que aún puede modificarlos con poco coste.
¿Qué efecto tiene Co-authored-by: en la atribución de GitHub?
GitHub lee el tráiler y muestra un segundo autor en la página del commit. Sólo vincula ese autor con un perfil cuando la dirección de correo pertenece a una cuenta. La documentación de GitHub indica que los commits aparecen en el gráfico de contribuciones cuando se «crean con una dirección de correo conectada a tu cuenta de GitHub», por lo que una dirección que no pertenece a nadie no puede asociarse con un perfil. En el caso de una colaboración entre dos personas, ese es precisamente el objetivo: la dirección de tu colega está asociada a su cuenta y el commit cuenta para ambos. Si ninguna cuenta es propietaria de la dirección, el tráiler cambia lo que muestra la página del commit, pero no modifica la lista de contribuidores del repositorio.
Git ignora completamente el tráiler. git shortlog -sn y git log --author leen la cabecera del autor, que contiene tu nombre y tu dirección de correo, por lo que ningún recuento local mostrará al coautor. Aquí, la atribución es una función de la forja que se añade a una convención de texto plano. Esta es la diferencia entre git y la forja donde lo alojas.
El enlace de la sesión es un problema diferente
Un tráiler identifica a un coautor. Una URL de sesión apunta a una transcripción. La referencia de configuración de Claude Code documenta attribution.sessionUrl como la clave que omite «el enlace de la sesión de claude.ai de las confirmaciones de Cloud y Remote Control». Esto también indica de dónde procede el enlace: de las sesiones en la web y de las sesiones controladas mediante Remote Control.
El enlace no es una credencial. El acceso a la sesión depende de la cuenta, no de que la URL permanezca desconocida. El motivo para no incluirlo en un repositorio público es más sencillo. Es texto público permanente que identifica un id de sesión interno y apunta a una transcripción de trabajo que nunca se redactó para una audiencia. En un repositorio privado se aplica el argumento contrario, porque un revisor puede seguir el enlace y leer cómo se realizó el cambio. La ubicación de esas transcripciones y el tiempo que se conservan se explica en cómo Claude Code almacena las sesiones y las reanuda.
Configuración que controla la atribución de commits de Claude Code
Comprobado con la referencia de configuración de Claude Code el 1 de septiembre de 2026. Estas claves están documentadas bajo el encabezado "Git y atribución":
attribution: "Personaliza la atribución que Claude Code añade a los commits y las pull requests"attribution.commit: "Cambia u oculta el trailer que Claude Code añade a los commits"attribution.pr: "Cambia u oculta la línea de atribución en las descripciones de pull request"attribution.sessionUrl: "Omite el enlace de sesión de claude.ai en los commits de cloud y Remote Control"includeGitInstructions: "Elimina del prompt del sistema las instrucciones integradas para commits y PR"includeCoAuthoredBy: marcada como obsoleta, con la nota "usaattributionpara ocultar o cambiar la atribución de commits y PR"
Tome el valor que acepta cada clave de su propia entrada en la referencia de configuración, no de una guía. Los nombres de las claves son estables. Los valores aceptados y los valores predeterminados pueden cambiar. Un archivo de configuración con la clave escrita correctamente y el valor escrito de forma incorrecta falla sin mostrar errores.
La ubicación donde la escriba determina quién la recibe. ~/.claude/settings.json se aplica a todos los proyectos que abra. Un archivo .claude/settings.json confirmado en la raíz del repositorio llega a todas las personas que lo clonen. .claude/settings.local.json es suyo en ese proyecto concreto. Claude Code lo añade a las exclusiones globales de git la primera vez que escribe el archivo, por lo que no se incluye en sus commits. La precedencia sigue este orden: configuración administrada, línea de comandos, configuración local del proyecto, configuración compartida del proyecto y configuración del usuario. Por tanto, el archivo local de un compañero tiene precedencia sobre el archivo que usted confirmó. Considere una configuración confirmada como un valor predeterminado, no como una garantía.
Después, verifíquelo. Una configuración en la que confía no es una prueba. Deje que Claude Code cree el siguiente commit de la forma habitual y lea el resultado.
git log -1 --format=%B
git log -1 --format=%B | git interpret-trailers --parseSi el trailer todavía aparece, el cambio no llegó a la sesión. Compruebe qué archivo editó y revise el orden de precedencia anterior antes de concluir que la clave no funciona.
Los controles que no dependen de una configuración
Una configuración ajusta una herramienta. Una regla del repositorio debe seguir aplicándose aunque un colaborador use otra herramienta o no use ningún agente. Git ofrece un lugar para colocar esa regla: el hook commit-msg se ejecuta con la ruta al archivo del mensaje como primer argumento, y puede editar ese archivo o rechazar el commit directamente.
#!/bin/sh
# .githooks/commit-msg
grep -qi '^co-authored-by: claude' "$1" || exit 0
grep -vi '^co-authored-by: claude' "$1" > "$1.new" && mv "$1.new" "$1"chmod +x .githooks/commit-msg
git config core.hooksPath .githooksEl primer grep termina pronto cuando no hay nada que hacer, por lo que un commit normal tiene un coste mínimo. El segundo escribe de nuevo el mensaje sin la línea coincidente. Busque un token exacto en lugar de todos los trailers, porque un filtro escrito como "eliminar el último bloque" también eliminará una línea Signed-off-by: que el proyecto requiera.
.git/hooks no forma parte del repositorio, por lo que un hook que coloque allí nunca llegará a otras personas. core.hooksPath indica a git que use un directorio que puede incluir en un commit, y cada persona debe ejecutar por su cuenta esa única línea git config. Git no lo configura automáticamente. Es una decisión deliberada: un repositorio que pudiera instalar sus propios ejecutables al clonarse podría ejecutar código en su máquina.
Para rechazar el commit en lugar de reescribirlo, escriba un mensaje en la salida de error estándar y ejecute exit 1 desde el hook. Rechazarlo es la opción adecuada en un repositorio compartido, porque editar en silencio el mensaje de commit de otra persona oculta la regla en lugar de explicarla. Esta es una capa distinta de los hooks propios del agente, que se ejecutan en una llamada a la herramienta antes de que intervenga git, y cómo un hook de Claude Code coincide con una herramienta y la bloquea explica esa parte.
Ninguno de esos mecanismos ayuda con una pull request desde un fork, porque el hook reside en una máquina que usted no controla. Una comprobación en CI (integración continua) es la única capa que ve cada commit antes de que se fusione.
if git log --format=%B "origin/${BASE_BRANCH:-main}..HEAD" | grep -qi '^co-authored-by: claude'; then
echo "Attribution trailer found. Rewrite the branch before merging." >&2
exit 1
fiEscriba también la regla, además de hacerla cumplir. Un AGENTS.md junto a un CONTRIBUTING.md legible para las personas comunica lo mismo al agente y a la persona, y la comprobación de CI es lo que garantiza su cumplimiento.
Eliminar el pie antes de hacer push
Para el commit que acaba de crear:
git log -1 --format=%B | grep -vi '^co-authored-by: claude' | git commit --amend -F --F - lee el mensaje nuevo desde la entrada estándar. Git elimina las líneas vacías iniciales y finales de un mensaje suministrado de esa forma, por lo que la línea vacía que deja el pie eliminado desaparece automáticamente. Vuelva a leer el resultado con git log -1 --format=%B antes de continuar.
Para varios commits de una rama, ejecute un rebase interactivo contra la rama en la que los va a fusionar y marque cada mensaje que quiera cambiar como reword.
git rebase -i origin/mainCada commit, desde el primero que edite en adelante, obtiene un hash nuevo porque el hash de un commit incluye su mensaje y su padre. Esto no tiene coste mientras los commits sean locales, pero resulta costoso cuando dejan de serlo.
Eliminar el pie de mensaje después de haber hecho push
En una rama que sólo uses tú, reescribe el historial como se indicó arriba y después haz push sobre ella.
git push --force-with-lease--force-with-lease rechaza el push si el remoto ha cambiado desde tu última obtención, por lo que no puede descartar silenciosamente un commit añadido por otra persona. El --force normal no realiza esta comprobación.
Si el pie de mensaje aparece a lo largo de un historial extenso, git filter-repo reescribe todos los mensajes en una sola pasada. Ejecuta la clonación desde dentro de tu copia de trabajo existente para que la URL se obtenga del remoto que ya tienes configurado.
pip install git-filter-repo
git clone "$(git remote get-url origin)" ../project-rewrite
cd ../project-rewrite
git filter-repo --message-callback '
return b"\n".join(l for l in message.split(b"\n") if not l.lower().startswith(b"co-authored-by: claude"))
'La función de callback recibe cada mensaje como bytes y devuelve el mensaje que se almacenará. Por eso, cada cadena contiene el prefijo b. filter-repo no se ejecuta en un repositorio que no sea un clon nuevo, a menos que pases --force. Además, elimina el remoto origin cuando termina para impedir que hagas push de la reescritura por accidente. Vuelve a añadir el remoto de forma deliberada, haz force-push y después indica a todos que vuelvan a clonar el repositorio, porque todos los hashes que tienen han dejado de ser válidos.
Ten claro qué no puede hacer una reescritura. Cambia tu copia del repositorio. No modifica los forks, los clones existentes, los mirrors, las páginas de pull request que ya hayan citado el mensaje ni un índice de búsqueda de código que te haya rastreado la semana pasada. Si se ha filtrado un secreto, la solución es rotarlo y usar la reescritura como limpieza. Un pie de mensaje de divulgación no es un secreto. Por tanto, compara el coste de una reescritura completa del historial con sus consecuencias: será necesario reconstruir cada pull request abierta.
Qué espera el revisor del otro lado
Los mantenedores no están de acuerdo sobre esto, y ese desacuerdo es la razón principal para comprobarlo antes de eliminar nada. Algunos proyectos quieren que se incluya la declaración y le pedirán que la vuelva a poner, porque un revisor analiza un parche generado por una máquina de otra manera. Otros la prohíben, a menudo por la cuestión de quién fue legalmente el autor del cambio. Los proyectos que usan un DCO (certificado de origen del desarrollador) requieren una línea Signed-off-by:, que es una declaración sobre su derecho a enviar el código, y un filtro de mensajes descuidado la elimina junto con la atribución.
Lea primero CONTRIBUTING.md. Si el proyecto no indica nada, elija una regla para el repositorio y déjela por escrito, porque un remolque que aparece en la mitad de los commits es peor que cualquiera de las dos opciones: hace que un mismo historial parezca corresponder a dos proyectos.
Si ejecuta el agente en un servidor en lugar de hacerlo en su portátil, la misma cuestión reaparece un nivel más abajo. Ejecutar Claude Code en un VPS con su propia cuenta determina a qué repositorios puede acceder, y qué envía un agente de programación fuera de la máquina abarca el tráfico que nunca aparece en un mensaje de commit.
FAQ
¿Un remolque Co-authored-by para Claude cuenta en las estadísticas de colaboradores de mi repositorio?
No. GitHub asocia un commit con un perfil mediante una dirección de correo electrónico vinculada a una cuenta de GitHub y cuenta las contribuciones según ese criterio. Una dirección que no pertenece a ninguna cuenta no se puede vincular, por lo que el remolque cambia la página del commit, pero deja intacta la lista de colaboradores. Git no lee los remolques para esto. git shortlog -sn cuenta la cabecera del autor, por lo que el coautor nunca aparece allí.
¿Cómo encuentro todos los commits que ya contienen el remolque?
git log -i --grep='^Co-authored-by:' --format='%h %an %s' los lista en todo el historial sin distinguir mayúsculas de minúsculas. En una versión reciente de git, git log --format='%h %(trailers:key=Co-authored-by,valueonly)' lee el valor mediante su propio analizador de remolques, en lugar de buscar texto sin procesar. Para ver sólo lo que aún no has enviado al remoto, añade un rango: git log origin/main..HEAD --format=%B.
¿Puedo eliminar el remolque de los commits que ya he enviado al remoto?
Sí, reescribiendo el historial, pero el coste es real. En una rama que sólo utilizas tú, modifica el commit o haz un rebase y después ejecuta git push --force-with-lease. En una rama compartida, cada commit desde el primero modificado recibe un hash nuevo, por lo que hay que reconstruir cada clon y cada pull request abierto. Además, una reescritura nunca llega a los forks, los mirrors ni a un clon que alguien haya creado ayer.
¿El enlace de la sesión de claude.ai en un mensaje de commit supone un riesgo de seguridad?
No es una credencial. El acceso a la sesión depende de la cuenta, no de que sea difícil adivinar la URL. El problema es que se trata de texto público permanente que apunta a una transcripción escrita como notas de trabajo. La documentación de referencia de configuración de Claude Code identifica attribution.sessionUrl como la clave que omite ese enlace de los commits de cloud y Remote Control, y un hook commit-msg lo elimina de todo lo que no cubra esa configuración.
¿Debería desactivar la atribución?
Depende del repositorio, no de las preferencias personales. En un proyecto público, sigue CONTRIBUTING.md, porque un mantenedor que quiera conservar la indicación te pedirá que la restaures. En un repositorio de empresa, conservar el remolque suele ser útil, ya que indica a un revisor, incluso un año después, por qué un cambio tiene ese aspecto. Decide una vez para todo el repositorio y aplícalo en CI para que el historial mantenga un formato coherente.