Por Anónimo (no verificado) , 29 Abril 2026

Introducción

git fetch es la operación de red que descarga nuevos objetos y actualiza las refs de seguimiento remoto. No cambia tus branches ni tu árbol de trabajo, lo que lo hace el comando "¿qué hay nuevo?" más seguro.

La secuencia

  1. Resolver la URL del remoto.
  2. Abrir una conexión (HTTPS, SSH o git://).
  3. Negociar capacidades (versión de protocolo, multi-ack, filtros de clon parcial, etc.).
  4. El servidor anuncia refs (o, en protocolo v2, solo las que coincidan con los patrones solicitados).
  5. El cliente reporta lo que ya tiene.
  6. El servidor envía un archivo pack que contiene los objetos faltantes.
  7. El cliente escribe el pack en .git/objects/pack/ y lo indexa.
  8. El cliente actualiza las refs de seguimiento remoto (refs/remotes/origin/*).
  9. Opcionalmente poda refs eliminadas.

Comandos

git fetch
git fetch origin
git fetch --all
git fetch --prune
git fetch origin main:my-main         # fetch a una ref local

La sintaxis con dos puntos main:my-main crea o actualiza una ref local directamente; úsala con cuidado.

Inspeccionando lo que se descargó

git fetch origin
cat .git/FETCH_HEAD
git log HEAD..origin/main --oneline

FETCH_HEAD lista cada ref actualizada por el fetch más reciente, en el orden solicitado.

Refspecs

Cada remoto tiene uno o más refspecs de fetch. El predeterminado para origin:

+refs/heads/*:refs/remotes/origin/*

Puedes añadir más, por ejemplo para descargar refs de pull-request desde GitHub:

git config --add remote.origin.fetch '+refs/pull/*/head:refs/remotes/origin/pr/*'
git fetch
git switch -c review/123 origin/pr/123

Podando

Sin prune, los branches eliminados en el servidor permanecen como refs origin/* obsoletas:

git fetch --prune
git config --global fetch.prune true

Tags

Por defecto, fetch descarga tags que apuntan a commits descargados. Fuerza o deshabilita:

git fetch --tags
git fetch --no-tags

Trace y debug

GIT_TRACE=1 GIT_TRACE_PACKET=1 git fetch
GIT_CURL_VERBOSE=1 git fetch        # HTTPS

Estos revelan las solicitudes exactas, útil para depurar proxies o auth.

Negociación y haves

El handshake de fetch es un baile de "wants" y "haves". El cliente lista lo que quiere (los SHAs de las puntas de los branches remotos), y ofrece haves (commits locales recientes) para que el servidor pueda calcular un pack mínimo. Git moderno usa el algoritmo de negociación skipping, que converge en O(log n) rondas incluso en historiales largos. Puedes ajustarlo:

git config fetch.negotiationAlgorithm skipping
git config fetch.negotiationAlgorithm consecutive
GIT_TRACE_PACKET=1 git fetch 2>&1 | grep -E 'have|want' | head

Errores comunes

Creer que git fetch cambia tus branches; nunca lo hace. Usa git pull o git merge origin/main para integrar. Saltarse --prune en clones de larga duración y acumular docenas de refs origin/* obsoletas. Configurar mal un refspec a mano y sobrescribir branches locales; verifica con git config -e. Finalmente, hacer fetch desde un clon parcial sin darte cuenta de que algunos objetos requerirán una llamada de red de seguimiento al accederlos; los clones parciales intercambian velocidad inicial por latencia ocasional posterior.