Introducción
Un branch de seguimiento remoto es una ref local que refleja un branch en un remoto. Viven bajo refs/remotes/<remote>/ y se actualizan por git fetch (y operaciones que implican fetch, como git pull y git clone). No haces commit directamente a ellos.
De dónde vienen
El refspec predeterminado para origin es:
+refs/heads/*:refs/remotes/origin/*
Así que cuando el servidor tiene refs/heads/main, tu clon obtiene refs/remotes/origin/main. El + inicial significa "force update".
Listando
git branch -r
git branch -a # local + remote-tracking
git branch -vv # mostrar upstream de los locales
Vinculando un branch local a uno
git switch feature/login # auto-crea local desde origin/feature/login
git switch -c mine origin/feature/login # explícito
git branch -u origin/main # establecer upstream del branch actual
git branch --unset-upstream
El vínculo upstream impulsa el ahead/behind de git status, y los destinos predeterminados para git push y git pull.
Podando
Los branches de seguimiento remoto no desaparecen cuando el branch remoto se elimina. Pódalos:
git fetch --prune
git remote prune origin
git config --global fetch.prune true
El HEAD remoto especial
Cada remoto tiene un HEAD simbólico indicando su branch predeterminado:
git symbolic-ref refs/remotes/origin/HEAD
git remote set-head origin --auto # consultar al servidor
Esto es lo que hace que origin solo resuelva a origin/main (o cualquier predeterminado).
Diff contra un branch de seguimiento remoto
git fetch
git log HEAD..origin/main --oneline # qué hay en upstream
git log origin/main..HEAD --oneline # qué es solo local
git diff @{u} # vs upstream
@{u} (o @{upstream}) es atajo para el upstream configurado del branch actual.
Comportamiento de push
El predeterminado push.default = simple pushea el branch actual a su upstream del mismo nombre. Si pusheas un branch sin upstream y tienes push.autoSetupRemote = true (Git 2.37+), el upstream se crea automáticamente.
Detalles de refspec
El refspec de fetch para un remoto puede personalizarse para descargar refs adicionales o para mapearlas de manera diferente. Por ejemplo, para también traer refs de PR de GitHub y refs de MR de GitLab:
git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git config --add remote.origin.fetch '+refs/merge-requests/*/head:refs/remotes/origin/mr/*'
El + inicial significa "force update", necesario porque las refs de PR pueden moverse (rebases en el branch de PR). Después de hacer fetch, los PRs del servidor aparecen como refs locales origin/pr/*, listos para git switch -c review/<n> origin/pr/<n>.
Errores comunes
Intentar git checkout origin/main y editar; te pone en HEAD desconectado porque origin/main es de solo lectura. Crea un branch de seguimiento en su lugar. Olvidar hacer git fetch y ser confundido por conteos ahead/behind obsoletos. Tratar los branches de seguimiento remoto como si pushear a ellos actualizara el servidor; son espejos locales. Usa git push origin main. Finalmente, eliminar origin/main con git branch -dr y asumir que el branch del servidor se ha ido; no lo está. Usa git push origin --delete main y solo cuando lo desees.