git branch para coding agents: crear refs, no cambiar de árbol
Resumen
git branch lista, crea o borra refs. No cambia el working tree: para eso es switch -c. Un agente usa --list con patrón, --show-current y -d solo si --merged. Cero -D/-M/-C/-f autónomos. Nombres vía check-ref-format --branch. Git 2.50.1 / Apple Git-155.

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 branch no cambia el working tree. El man (git-branch(1), Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-branch HTTP 200, actualizado en 2.51.0): lista, crea o borra ramas. La forma que crea un head nuevo apunta al HEAD actual o a un <start-point>; el árbol se queda donde está. El propio man remite a git switch para entrar a esa rama.
Esta guía no sustituye switch, worktrees ni branch protection. El contrato: qué forma corre un agente, qué flags fuerzan, y cómo se nombra una ref.
Lista, no pager, no crear por accidente
Sin argumentos no opcionales, o con --list, lista. El man: la rama actual va con asterisco; un checkout en worktree ligado se marca con más. -r son tracking remotas; -a mezcla locales y remotas.
Un <pattern> es un glob de shell. Hay que pasar --list: si no, Git puede interpretar el patrón como creación. pager.branch solo aplica al listado; un agente no pagina.
--show-current imprime el nombre de la rama actual. HEAD detached: no imprime nada. No es un error silencioso que se trague: si sale vacío, para.
--format interpola %(fieldname) como git-for-each-ref. Para un agente, --format='%(refname:short)' o --show-current bastan. -v / -vv añaden SHA, subject, upstream y, al duplicar, la ruta del worktree. No dumps.

Lo que el agente sí / no corre
| Quiero | Comando | Trampa |
|---|---|---|
| Rama actual | git branch --show-current | Vacío = detached. No asumas main |
| Listar locales | git branch --list | git branch 'feat-*' sin --list (puede crear) |
| Crear sin entrar | git branch <name> origin/main | Entrar = switch -c |
| Crear y entrar | git switch -c <name> origin/main | git checkout -b (mezcla restore) |
| Borrar fusionada | git branch -d <name> | -D / -d --force sin --merged |
| Tracking | nace de una remote-tracking, o -u | --set-upstream ya no existe |
Prohibido en autónomo:
-f/--forceal crear. El man: sin-f, se niega a cambiar una rama que ya existe. Con-f, resetea<branch-name>al start-point. Reescribe la ref. Además se niega si esa rama está checked out en otro worktree.-D(--delete --force).-dexige que esté fusionada en su upstream, o en HEAD si no hay upstream.-Dborra igual, incluso si el tip no es un commit válido. El ejemplo del man borratestaunque la rama actual no contenga esos commits.-M/-C.-mrenombra con config y reflog;-ccopia. Las mayúsculas fuerzan si el destino ya existe.--edit-description. Abre editor. Un agente no edita la descripción de la rama a ciegas.--recurse-submodules. El man lo marca experimental. Solo creación, y solo sisubmodule.propagateBranchesestá on.--set-upstream. El man: sintaxis confusa, ya no se soporta. Usa--tracko--set-upstream-to/-u.- Borrar
-d -r origin/...“para limpiar”. El ejemplo del man: el próximo fetch las recrea salvo que el fetch esté configurado para no traerlas. El prune va engit-remote, no en un-d -rsuelto. - Crear sobre
main/master/ la default. GitHub Docs (Branches, HTTP 200 2026-09-04,/pull-requests/reference/branches): en repos nuevos con contenido, GitHub crea una rama, la default; es la que muestra al visitar, la que Git hace checkout al clonar, y —si no se indica otra— la base de PRs y commits. Por defecto esa default se llamamain. Cambiarla es Settings de admin (Changing the default branch, HTTP 200): el repo debe tener más de una rama. Un agente no la renombra ni la borra.
-- delante del nombre. Un name que parece opción se parsea mal.
Receta (60 segundos)
Solo en un worktree propio:
git branch --show-current # vacío → detached; para
git check-ref-format --branch feat/foo
git fetch origin
git switch -c feat/foo origin/main
Si el contrato del repo pide la ref sin entrar al árbol (otro proceso ya tiene el checkout):
git branch feat/foo origin/main
git worktree add ../feat-foo feat/foo
Listar sin crear:
git branch --list 'feat/*'
git branch --merged
git branch --no-merged
--merged (commit omitido = HEAD): tips alcanzables desde HEAD; el man, NOTES: candidatas a borrar con seguridad. --no-merged: las que no están contenidas; candidatas a mergear hacia HEAD. --contains <commit>: tips que descienden de ese commit (quién se rompe si lo reescribes). No son el mismo filtro.
Cierre: PR. No push a la default.

Nombres, tracking y default main
El man: el nombre nuevo tiene que pasar git-check-ref-format(1). Verificado 2026-09-04 (git-check-ref-format(1), Git 2.54.0 / 2026-04-19; git-scm.com/docs/git-check-ref-format HTTP 200) y en esta máquina (Git 2.50.1 / Apple Git-155):
| Nombre | git check-ref-format --branch | Por qué |
|---|---|---|
feat/foo | 0 | Componente con / válido |
-bad | 128 | El man --branch: un guion al inicio del nombre de rama está prohibido |
foo..bar | 128 | Dos puntos seguidos (rango A..B) |
foo.lock | 128 | Componente que termina en .lock |
foo@{bar} | 128 | Secuencia @{ (reflog) |
Otras reglas del mismo man, sin improvisar nombres: nada de espacio, ~, ^, :, ?, *, [, barra al inicio/final, punto al final, ni la barra invertida. --branch es lo que deben usar los porcelains: primero expande @{-n} (último switch/checkout). Un agente valida antes de crear.
Tracking. Si la rama nace de una remote-tracking, Git rellena branch.<name>.remote y branch.<name>.merge para que pull sepa de dónde mergear. branch.autoSetupMerge default true: equivale a --track=direct cuando el start-point es remote-tracking. false = --no-track. always trackea también desde local. inherit copia el upstream del start-point. simple solo si el start-point es remote-tracking y el nombre coincide. --track=inherit vs --track=direct pisan ese default. Un agente no pone branch.autoSetupRebase (default never): rebase automático no es el contrato de pull.
GitHub Docs (Branches): hace falta write para crear rama, abrir PR, o borrar/restaurar ramas en un PR. Una rama de feature se crea desde otra, casi siempre la default. Las protected branches pueden bloquear force-push y delete, exigir checks, reviews, code owners o commits firmados: detalle en branch protection. El agente no bypassea eso ni hace force-push a main.
NOTES del man: si vas a entrar a la rama al crearla, git switch -c es un solo paso. switch -c es transaccional: si el switch falla, no deja la ref a medias. git branch + git switch son dos comandos; el segundo puede abortar y dejar la rama huérfana de checkout. Prefiere switch cuando el worktree es tuyo.
Checklist
- Worktree propio.
git branch --show-currentno vacío. - Nombre:
git check-ref-format --branch <name>exit 0. Cero-bad,..,.lock,@{. - Crear y entrar:
git switch -c <name> origin/main. Cerocheckout -b. - Solo crear la ref:
git branch <name> <start>y worktree, no-f. - Listar:
--list+ patrón. Cero patrón suelto. - Borrar:
-ddespués de--merged. Cero-D/-M/-C. - Cero
--set-upstream,--edit-description,--recurse-submodules. - Cierre = PR, no commit en la default.
FAQ
¿git branch feat y luego switch? Sí, pero el man recomienda switch -c si vas a entrar. Menos estados a medias.
¿Puedo -D de una rama que “ya mergeé en GitHub”? -d mira upstream o HEAD local, no el botón de GitHub. Si el tracking no está, HEAD tiene que contener el tip. Si no, no borres.
¿git branch -m de main a trunk? Renombrar la default es un cambio de admin en GitHub (Changing the default branch): Settings, más de una rama, confirmación. Un agente no.
¿Patrón feat-* sin --list? El man: puede leerse como creación. Siempre --list.
El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. Branch no es switch: mueve la ref, no el árbol.
Verificado 2026-09-04 contra git-branch(1) (Git 2.50.1 / Apple Git-155; git-scm.com/docs/git-branch HTTP 200, last updated 2.51.0), git-check-ref-format(1) (git-scm.com/docs/git-check-ref-format HTTP 200; --branch exit 128 para -bad, foo..bar, foo.lock, foo@{bar} en esta máquina) y GitHub Docs “Branches” (/pull-requests/reference/branches, HTTP 200; default main en repos nuevos) y “Changing the default branch” (HTTP 200).
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.



