Comparación

git fetch y git pull: en qué se diferencian y cuál elegir

Actualizado: · Skillaria.Top

git fetch solo descarga los commits nuevos del servidor y actualiza las ramas remotas como origin/main, sin tocar tus archivos ni tus ramas. git pull hace lo mismo y además integra los cambios en la rama actual mediante merge o rebase. Fetch siempre es seguro; pull es cómodo cuando estás listo para aceptar los cambios de otros en ese momento.

Respuesta corta

git fetch descarga del servidor los commits nuevos y actualiza las referencias de las ramas remotas (origin/main, origin/feature-x), pero no cambia ni tu rama actual ni los archivos de la carpeta de trabajo. git pull es git fetch más la integración inmediata de lo descargado en la rama actual: mediante merge (por defecto) o mediante rebase.

De ahí sale una regla práctica: fetch puedes ejecutarlo cuando quieras, no rompe nada. Pull modifica tu rama y puede acabar en conflicto, así que conviene lanzarlo con la carpeta de trabajo limpia y sabiendo qué va a llegar.

Dónde viven las ramas remotas

Para que la diferencia quede clara hay que entender que en el repositorio local hay dos tipos de ramas. Las locales, como main o feature-x, las mueves tú con tus commits. Las ramas remotas de seguimiento, como origin/main, son marcadores de «así estaba el servidor en la última sincronización». No se pueden mover a mano: solo las actualiza la comunicación con el servidor, es decir, fetch, pull y push.

git branch -a
* main
  remotes/origin/HEAD -> origin/main
  remotes/origin/main
  remotes/origin/feature-x

git status compara tu rama precisamente con el marcador origin/main, no con el servidor en vivo. Por eso el mensaje «Your branch is up to date with 'origin/main'» puede engañar: si hace tiempo que no haces fetch, Git simplemente no sabe que tus compañeros han subido commits nuevos.

Qué hace git fetch

$ git fetch
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
Unpacking objects: 100% (4/4), done.
From github.com:team/project
   3f2a1c9..8b7d4e2  main       -> origin/main

La última línea dice lo esencial: la referencia origin/main ha pasado de 3f2a1c9 a 8b7d4e2. Tu main sigue donde estaba. Ahora puedes revisar con calma lo que ha llegado:

git status                       # Your branch is behind 'origin/main' by 2 commits
git log main..origin/main --oneline   # commits que tú no tienes
git diff main origin/main        # qué cambiará en los archivos

Variantes útiles de fetch:

  • git fetch --all: trae los cambios de todos los remotes (útil si en un fork tienes origin y upstream);
  • git fetch --prune (-p): borra los marcadores locales de ramas que ya no existen en el servidor;
  • git fetch origin main: trae solo una rama;
  • git fetch --tags: trae además todas las etiquetas.

Para que el prune se haga siempre, actívalo una vez: git config --global fetch.prune true.

Qué hace git pull

git pull ejecuta dos pasos seguidos. Primero, un fetch de la rama upstream de la rama actual; después, la integración de origin/<rama> en tu rama. Literalmente equivale a:

git fetch origin
git merge origin/main      # o git rebase origin/main con pull --rebase

El resultado depende de cómo hayan divergido los historiales:

  • tú no tienes commits nuevos: se hace un fast-forward y la rama simplemente avanza;
  • hay commits nuevos tanto tuyos como en el servidor: con merge se crea un commit de fusión, con rebase tus commits se recolocan encima de los del servidor;
  • las mismas líneas se cambiaron en ambos lados: hay un conflicto que tendrás que resolver a mano.

Comparativa entre git fetch y git pull

git fetchgit pull
Descarga commitsSíSí
Actualiza origin/*SíSí
Cambia la rama actualNoSí
Cambia archivos de la carpeta de trabajoNoSí
Puede provocar conflictosNoSí
Requiere la carpeta de trabajo limpiaNoEs recomendable
Afecta a otras ramasActualiza todos los marcadores de seguimientoSolo integra en la actual
Cuándo usarloVer qué ha cambiado; antes de un rebase; en scriptsPonerte al día rápidamente con el servidor en tu rama

git pull: ¿merge o rebase?

Desde Git 2.27, si el historial ha divergido y no hay configuración explícita, pull muestra una advertencia, y en las versiones nuevas, en lugar de hacer un merge en silencio, se detiene con el error «Need to specify how to reconcile divergent branches». Git te pide elegir la estrategia una vez:

git config --global pull.rebase false   # merge (el comportamiento por defecto de antes)
git config --global pull.rebase true    # rebase
git config --global pull.ff only        # solo fast-forward; si no, se niega

Merge conserva el historial tal cual y añade un commit «Merge branch 'main' of github.com:...». Si haces pull a diario en una rama con commits locales, el historial se llena de estas fusiones técnicas.

Rebase recoloca tus commits no enviados encima de los recién llegados del servidor. El historial queda lineal y los conflictos se resuelven commit a commit. Para commits locales sin publicar suele ser la mejor opción. Rebase solo es peligroso con commits ya enviados sobre los que otros están trabajando.

ff only es el modo más estricto: pull solo funciona cuando no tienes commits propios. Si el historial ha divergido, decides tú explícitamente qué hacer. Muchos desarrolladores con experiencia lo configuran precisamente para las ramas principales.

Si tienes cambios sin commit en la carpeta de trabajo y necesitas el pull ya, te servirá git pull --rebase --autostash: Git guarda los cambios aparte, hace el rebase y los devuelve.

Flujo típico: fetch, revisar, integrar

El enfoque «primero fetch» te da control sobre lo que entra en tu rama. Es especialmente útil antes de abrir un pull request y después de un tiempo sin tocar el proyecto.

git fetch
git log --oneline --graph HEAD origin/main   # cómo han divergido las ramas
git rebase origin/main                       # o git merge origin/main
git push

Otro caso frecuente: actualizar tu rama de funcionalidad con el main más reciente sin cambiar a él:

git switch feature-x
git fetch
git rebase origin/main

Aquí pull no sirve: git pull en una rama de funcionalidad trae los cambios de su propio upstream (origin/feature-x), no de la rama principal. Claro que puedes escribir git pull --rebase origin main, pero la variante con fetch es más clara.

Sincronizar con el servidor: cómo mantener la rama al día

Cuando se habla de «sincronizar» en Git se suele referir al ciclo «traer lo de los demás y enviar lo tuyo». Git puro no tiene un comando sync (el botón Sync existe en IDE y clientes gráficos, y por dentro hace pull y luego push). A mano, un ciclo fiable es este:

  1. git status: asegúrate de que todo tiene commit o está guardado con git stash;
  2. git pull --rebase: trae los cambios y recoloca tus commits encima;
  3. resuelve los conflictos si los hay: corrige los archivos, git add, git rebase --continue;
  4. ejecuta los tests;
  5. git push.

Para sincronizar un fork con el repositorio original:

git remote add upstream https://github.com/original/project.git
git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main

Problemas frecuentes con git pull

Your local changes would be overwritten by merge

Pull quiere modificar archivos que estás editando y no has confirmado. Opciones: hacer commit, guardarlos aparte (git stash, luego pull y git stash pop) o usar --autostash. No hace falta borrar tus cambios para hacer pull.

Conflicto después de pull

Git se detendrá y mostrará los archivos en conflicto en git status. Ábrelos, elige la versión correcta entre los marcadores <<<<<<< y >>>>>>>, y luego git add y git commit (con merge) o git rebase --continue (con rebase). Si cambias de opinión, git merge --abort o git rebase --abort lo devuelven todo al estado anterior al pull.

There is no tracking information for the current branch

La rama no tiene upstream configurado y Git no sabe de dónde traer los cambios. Indícalo explícitamente con git pull origin main o configura el vínculo una vez: git branch --set-upstream-to=origin/main.

refusing to merge unrelated histories

El repositorio local y el remoto se crearon por separado; por ejemplo, al crear el del servidor se añadió un README. Si estás seguro de que hay que unirlos: git pull origin main --allow-unrelated-histories.

Un pull que salió mal: cómo deshacerlo

Si el merge del pull ya terminó y el resultado no te convence, devuelve la rama al estado anterior: git reset --hard ORIG_HEAD. El comando elimina los cambios sin commit, así que revisa antes git status. En el peor de los casos, la posición anterior de la rama se encuentra en git reflog.

Cuál elegir

  • Quieres saber qué hay de nuevo sin cambiar nada: git fetch.
  • Trabajas en tu rama y solo te pones al día con el servidor: git pull --rebase (o pull con pull.rebase true configurado).
  • Actualizas la rama principal sin commits tuyos: git pull --ff-only.
  • Necesitas integrar main en una rama de funcionalidad: git fetch y después git rebase origin/main o git merge origin/main.
  • Escribes un script o un pipeline de CI: fetch y comandos explícitos, sin pull.

Cómo se ve en el grafo de commits

Imagina que tú y un compañero partís del commit C. Tú has hecho en local el commit D y tu compañero ha subido al servidor E. Tras git fetch, tu repositorio conoce ambas líneas: main apunta a D, origin/main a E, y tienen como ancestro común C.

          D   <- main (HEAD)
         /
A---B---C
         \
          E   <- origin/main

A partir de ahí todo depende de cómo integres. git merge origin/main creará un commit M con dos padres, D y E. git rebase origin/main copiará D encima de E como un commit nuevo D' con otro hash, y el historial quedará en línea recta. git pull simplemente hace estos mismos pasos de forma automática, sin pausa entre ellos. Esa pausa, la posibilidad de mirar el grafo antes de integrar, es justo el valor principal de un fetch por separado.

Fetch y pull en el IDE

En VS Code, IntelliJ IDEA y otros editores los botones se llaman de distintas maneras, pero debajo están los mismos comandos. «Fetch» es git fetch, «Pull» o «Update Project» es pull con la estrategia elegida en la configuración (merge o rebase) y «Sync Changes» es pull seguido de push. Antes de pulsar Sync en una rama compartida conviene saber qué estrategia está seleccionada; si no, aparecerán commits de fusión inesperados en el historial. Muchos IDE también hacen fetch periódicamente en segundo plano, así que el contador de commits entrantes de la barra de estado suele estar al día.

Resumen

git fetch actualiza lo que sabes del servidor y git pull, además, aplica ese conocimiento a la rama actual. Fetch es seguro en cualquier momento; pull es cómodo, pero cambia la rama y puede traer conflictos, así que configura su estrategia una vez y mantén limpia la carpeta de trabajo. La diferencia entre push, pull y fetch, el trabajo con remotes y GitHub se practican en el curso de Git.

Preguntas frecuentes

¿Hay que hacer git fetch antes de git pull?

No, pull ya hace fetch como primer paso. Un fetch aparte sirve cuando quieres ver primero los cambios y después decidir cómo integrarlos.

¿Puede git fetch borrar mis cambios?

No. Fetch solo cambia las referencias remotas como origin/main y no toca las ramas locales, el índice ni la carpeta de trabajo.

¿git pull actualiza todas las ramas?

No, pull integra cambios solo en la rama actual. Los marcadores origin/* del resto de ramas se actualizan gracias al fetch, pero las ramas locales se quedan donde estaban.

¿Cada cuánto conviene hacer git fetch?

Antes de empezar a trabajar, antes de crear un pull request y antes de hacer push. Muchos IDE hacen fetch automáticamente en segundo plano, y es seguro.

¿Qué es FETCH_HEAD?

Una referencia interna en la que fetch guarda lo último que ha descargado. Por ejemplo, después de git fetch origin main puedes ejecutar git merge FETCH_HEAD.

Aprende este tema en vídeo

Este tema se explica a fondo y con práctica en el curso «Git desde cero hasta desarrollador seguro».

Ir al curso