Guía9 min

git commit para coding agents: index, -m, cero amend

Resumen

git commit graba el index, no el disco. Un agente pasa -m y el index ya staged o paths conocidos; nunca --amend, --no-verify, --allow-empty ni -a. -n elude pre-commit y commit-msg. Firma GPG o SSH no es el trailer Signed-off-by. Git 2.50.1 / Apple Git-155.

GitHub
Un commit nuevo sobre el index staged; el tip anterior no se reescribe

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 commit no reescribe el tip. El man (git-commit(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-commit HTTP 200): crea un commit con el index y un mensaje. El nuevo objeto es hijo directo de HEAD y la rama se mueve a él, salvo HEAD detached. GitHub Docs (HTTP 200, 2026-09-04, Commits, /pull-requests/reference/commits): el commit guarda cambios, autoría y un SHA. El mensaje es obligatorio.

Esta guía no sustituye add, conventional commits ni force-push. El contrato: qué forma corre un agente, qué flags están prohibidos, y qué hooks no se saltan.

El index, no el disco

El man lista cinco formas de armar el árbol. Un agente autónomo usa una:

  1. add por paths, luego git commit -m "…".
  2. Pathspecs en el commit: el man dice que ignora lo staged y graba el contenido actual de esos paths ya conocidos. Untracked no entra. Tampoco “el resto del index”.
git status --porcelain=v1 -z
git add -- path/a.ts path/b.ts
git diff --cached --stat
git commit -m "feat(guias): contrato de git commit para coding agents"

-m puede repetirse: cada valor es un párrafo. Es excluyente con -c, -C y -F. Un agente no abre editor: pasa -m. El subject sigue conventional commits.

--dry-run con los mismos pathspecs resume qué iría. No crea el objeto.

Index staged, mensaje con -m, commit nuevo; HEAD anterior intacto

Lo que el agente sí / no corre

QuieroComandoTrampa
Commit del indexgit commit -m "type: subject"git commit sin -m (editor)
Paths ya conocidosgit commit -m "…" -- pathPath untracked; el man no lo añade
Ver el árbolgit commit --dry-runConfiar en el long de status
Corregir el tip publicadocommit nuevo--amend + push
Cerrar trabajogh pr createCommit en main

Prohibido en autónomo:

  • --amend. El man: reemplaza el tip con un commit nuevo, mismos padres y autor; equivalente grosero a git reset --soft HEAD^ + git commit -c ORIG_HEAD. Puede enmendar un merge. Advierte reescribir historial ya publicado (git-rebase(1), RECOVERING FROM UPSTREAM REBASE). --amend --no-edit ni siquiera toca el mensaje. Detalle de force: force-push.
  • --no-verify / -n. El man: elude pre-commit y commit-msg. githooks(5) (HTTP 200): pre-commit corre antes del mensaje y aborta con status distinto de cero; commit-msg recibe el archivo del mensaje, puede editarlo, y también aborta. Saltarlos es eludir el repo. prepare-commit-msg no está en esa lista de --no-verify.
  • --allow-empty. El man: un commit con el mismo árbol que el padre suele ser un error; el flag lo permite, pensado para scripts de SCM extranjeros. Un agente no fabrica vacíos para “mover CI”.
  • --allow-empty-message. Vacío sin plumbing (git-commit-tree). Misma audiencia: scripts extranjeros.
  • -a / --all. Stage automático de modificados y borrados ya conocidos. Untracked no. Sigue siendo amplio: mezcla el ticket con un debug local.
  • -i / --include. Stagea también los pathspecs de la línea. El man: “usually not what you want” salvo un merge con conflictos.
  • -o / --only + --amend sin paths. El man: enmienda el último commit sin meter lo que ya estaba staged. Es amend disfrazado.
  • --fixup / --squash autónomos. Crean fixup! / squash! para rebase --autosquash. Reescriben después. Fuera de un humano.
  • Autoría falsa. --author, --date, --reset-author cambian quién/cuándo. GitHub Docs (Commits): el SHA identifica cambios, momento y quién. Un agente no se hace pasar por el humano.

-- + pathspecs. Sin --, un path que parece opción se parsea mal.

Receta (60 segundos)

Solo en un worktree propio:

git status --porcelain=v1 -z
git diff --cached --stat          # vacío → no hay commit
git commit -m "type(scope): subject"
git status -sb                    # limpio respecto al commit nuevo

Si el index está vacío, no --allow-empty: vuelve a add. Si el hook pre-commit falla, no -n: arregla el árbol. Si el subject es wip, reescribe el -m, no el historial.

HEAD detached: el man, el commit no mueve rama. Para. switch a la rama de trabajo.

Cierre: PR. Un segundo error = otro commit, no amend.

pre-commit y commit-msg corren; --no-verify no es un permiso

Hooks, firma y trailers

githooks(5): git commit puede correr prepare-commit-msg, pre-commit, commit-msg, post-commit y post-rewrite. post-commit es notificación: no deshace el objeto. El sample de pre-commit (si está enabled) bloquea nombres no ASCII y whitespace al final; hooks.allownonascii=true apaga lo primero. Un agente no desactiva hooks a ciegas.

--trailer "Token: valor" aplica trailers (git-interpret-trailers(1)). -s / --signoff añade Signed-off-by del committer. Git no tiene config para prender signoff por default (commit.signoff en gitfaq(7)). GitHub Docs (Commits): si el repo exige signoff y commiteas en la web, GitHub lo añade solo. En CLI, el agente no inventa DCO.

Firma ≠ signoff. GitHub Docs (HTTP 200, About commit signature verification): GPG, SSH o S/MIME. Estados default (vigilant mode off): Verified = firma verificada; Unverified = hay firma y no verificó; sin estado = no firmado. Firmar el commit no es firmar el signoff de la política del repo. -S / --gpg-sign del man firma GPG; --no-gpg-sign cancela commit.gpgSign. Un agente no apaga la firma del repo para “pasar CI”. SSH es la vía más simple en esa página: se puede reusar la clave de autenticación como clave de firma.

$GIT_DIR/COMMIT_EDITMSG guarda el mensaje en curso. Si git commit aborta, el texto puede quedar ahí. No es un permiso para --amend.

Checklist

  • Worktree propio. Rama ≠ main/master. No detached.
  • Index = el ticket. git diff --cached --stat no vacío.
  • git commit -m "type: subject". Cero editor. Cero -a.
  • Cero --amend, --no-verify/-n, --allow-empty, --allow-empty-message, --fixup.
  • Hook rojo → arreglar, no -n.
  • Error después de publicar = commit nuevo. Cero amend+push.
  • Cierre = PR, no commit en la default.

FAQ

¿git commit -am "fix"? -a solo trackeados. Sigue mezclando archivos del ticket con basura local. Add por paths.

¿El hook falló y “solo esta vez”? --no-verify elude pre-commit y commit-msg. El man lo nombra. Un agente no lo usa.

¿Amend local, sin push? El man igual reescribe el tip. Otro proceso (CI, IDE, segundo worktree) puede haber visto el SHA. Commit nuevo.

¿Varios -m? Sí: párrafos. El primero es el subject. No uses -m junto a -F.

¿Firma GPG obligatoria? Depende del repo. GitHub marca Verified si la firma verifica. No es el trailer Signed-off-by.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. Commit no es fetch ni add: graba el index.

Verificado 2026-09-04 contra git-commit(1) y githooks(5) (Git 2.50.1 / Apple Git-155), git-scm.com/docs/git-commit y git-scm.com/docs/githooks (HTTP 200), GitHub Docs “Commits” (/pull-requests/reference/commits, HTTP 200; la URL vieja /creating-and-editing-commits/about-commits redirige 301) y “About commit signature verification” (HTTP 200).