git push para coding agents: origin, tu rama, cero main
Resumen
git push actualiza refs remotos y envía los objetos que el remoto aún no tiene. Un agente nombra origin y su rama de trabajo; no main, no --force, no --delete, no --tags, no --no-verify. Si Git rechaza un non-fast-forward, fetch primero. 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 push no es “sube esto a main”. El man (git-push(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-push HTTP 200, man 2.55.0): actualiza uno o más refs en un remoto y envía los objetos que el remoto todavía no tiene. Lo más simple: git push <remote> <branch>. El <repository> por default es el upstream de la rama actual, o origin si no hay.
GitHub Docs (HTTP 200, 2026-09-04, Pushing commits to a remote repository): el comando toma dos argumentos — un remote (origin) y una rama (main en su ejemplo). Un coding agent no usa ese ejemplo: cierra con PR, no con push a la default. Force, lease y amend viven en force-push. Aquí el contrato: qué forma corre un agente, qué flags están prohibidos, y qué hacer cuando Git rechaza.
Fast-forward o nada
PUSH RULES del man: destino refs/heads/* → solo fast-forward (el remoto es ancestro del commit que empujas; el source es un commit). Destino refs/tags/* → cualquier update se rechaza. --force o un + delante del refspec saltan esas reglas; no convierten un blob en rama, y no vencen receive.denyNonFastForwards ni un hook que niegue.
GitHub Docs, Dealing with "non-fast-forward" errors: si tu copia está detrás, el remoto rechaza. Hay que fetch antes de volver a empujar. Un agente no traduce ese rechazo en -f.
git push origin HEAD # misma rama, fast-forward
git push -u origin HEAD # primer push: fija upstream
git push --dry-run origin HEAD
push.default default = simple: empuja una rama del mismo nombre. Sin upstream, git push a secas puede fallar. El agente nombra remote y ref (origin HEAD o origin <rama>), no adivina matching.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| Primer push de la rama | git push -u origin HEAD | git push sin remote/ref; origin main |
| Push siguiente | git push origin HEAD | -f “porque ya existe” |
| Ver qué haría | git push --dry-run origin HEAD | Confiar en el long de status |
| Parsear | git push --porcelain origin HEAD | Parsear stderr humano |
| Cerrar trabajo | gh pr create | Push a main |
Prohibido en autónomo:
git push origin main/master/ la default del repo. El destino es la rama de trabajo. Branch protection no es un permiso para probar.--force/-f/+<refspec>. El man: desactiva el chequeo de ancestro, las PUSH RULES y--force-with-lease; puede hacer que el remoto pierda commits.--forceaplica a todos los refs que el comando empuja. Detalle y lease: force-push.--delete/-d/git push origin :rama. El man y GitHub Docs:<src>vacío borra<dst>en el remoto (git push origin :dev). Un agente no borra refs ajenos.--tags/--all/--branches/--mirror/--prune.--tagsempuja todorefs/tags.--alltodas las ramas.--mirrorforce-updatea y borra en el remoto.--pruneborra en el remoto lo que ya no existe en local.--no-verify. El default es--verify: el hookpre-pushpuede abortar. Saltar el hook es eludir el repo.- URL suelta como
<repository>. Nombra el remote degit remote -v(origin, a veces el fork). SECURITY del man: fetch/push no impiden que un peer robe objetos no pensados para compartir. Namespaces en el servidor no son ACL de lectura. - Refspec
:/+:(matching). Empuja cada rama local que ya existe en el remoto. --follow-tags“por si acaso”. Empuja tags anotados alcanzables. Un agente no publica tags.- Destino distinto al nombre local (
HEAD:main,topic:main). GitHub Docs, Renaming branches:git push REMOTE LOCAL:REMOTErenombra en el remoto. Eso es un push a otra rama, no un rename local.
Receta (60 segundos)
Solo en un worktree propio:
git status -sb # limpio; no MERGE_HEAD / rebase
git branch --show-current # no main, no master
git fetch origin
git push -u origin HEAD # o sin -u si ya hay upstream
Si el push se niega con non-fast-forward / rejected (flag ! en OUTPUT): no -f. Fetch, mira HEAD..origin/<rama>, integra con merge/--ff-only o reporta divergencia. Luego push otra vez, sin flags.
GitHub Docs, Resolving blocked commits: push protection puede bloquear un push si el commit trae un secreto soportado. Quita el secreto del historial o sigue la URL de bypass que da GitHub. Un agente no bypasea protección de secretos.
Cierre: PR, no merge a main.

Output, forks y el servidor
El man (OUTPUT, protocolo Git/ssh): <flag> <summary> <from> -> <to> (<reason>). --porcelain: <flag> \\t <from>:<to> \\t <summary> (<reason>) a stdout. Flags: espacio = fast-forward; + = forced update; - = borrado; * = ref nuevo; ! = rechazado; = = ya al día. Un agente que parsea usa porcelain, no la tabla humana.
rejected = Git ni intentó enviar (típico: no es fast-forward y no forzaste). remote rejected = el remoto dijo no: hook, receive.denyCurrentBranch, receive.denyNonFastForwards, receive.denyDeletes. remote failure = error transitorio. Reporta el reason; no reintentes con más flags.
Forks (GitHub Docs, Remotes and forks): git remote add upstream <url> y git fetch upstream. El push del agente va a su origin (el fork), no a upstream. El PR es el puente.
--set-upstream / -u: para cada rama que quedó al día o se empujó bien, fija tracking. Sirve en el primer push de la rama de trabajo. No es un permiso para empujar main.
push.autoSetupRemote=true asume -u en el push default sin upstream. Un agente igual pasa remote y ref explícitos: no depende de un config local que el humano puede no tener.
Checklist
- Worktree propio.
git status -sblimpio. Rama ≠main/master. -
git fetch originantes si el último fetch no es de esta receta. -
git push -u origin HEAD(o sin-usi ya hay upstream). Cero URL suelta. - Cero
--force,+refspec,--delete,:rama,--tags,--all,--mirror,--prune,--no-verify. -
!/ non-fast-forward → fetch + reportar, no-f. - Push protection / secreto → no bypass. Quita el secreto o para.
- Cierre = PR, no push a la default.
FAQ
¿git push sin argumentos? Depende de push.default y de si hay upstream. El man: puede fallar. Nombra origin y HEAD.
¿git push origin main “solo esta vez”? No. GitHub Docs usa main como ejemplo de argumentos, no como política de un agente. Default = PR.
¿--force-with-lease en vez de --force? Sigue siendo force. El man avisa que sin <expect> un git fetch de fondo derrota el lease. Guía: force-push.
¿Puedo borrar la rama remota al cerrar el PR? git push origin :rama borra. En autónomo, no. gh pr merge / borrar rama es decisión humana o del host tras el merge.
¿--tags para no olvidar un tag? El man: empuja todos los tags. Un agente no publica tags.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. Push no es pull ni fetch: empuja refs; no integra.
Verificado 2026-09-04 contra git-push(1) (Git 2.50.1 / Apple Git-155), git-scm.com/docs/git-push (HTTP 200, man 2.55.0) y GitHub Docs “Pushing commits to a remote repository” (HTTP 200).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.



