git pull vs git fetch: la diferencia que importa

git fetch descarga los cambios del remoto sin tocar tu trabajo; git pull los descarga y los integra. Cuándo conviene cada uno y por qué.

git pull vs git fetch: la diferencia que importa

Escribes git pull en piloto automático, como todo el mundo, y un buen día ese pull te mete un merge que no esperabas justo en mitad de un cambio a medias. La diferencia entre git pull y git fetch es la diferencia entre mirar antes de integrar e integrar a ciegas. Aquí explico qué toca cada comando en tu repositorio y cuándo me interesa quedarme solo con fetch.

¿Qué hace exactamente git fetch?

git fetch descarga los commits, ramas y tags que hay en el remoto y actualiza tus ramas de rastreo remoto, como origin/main, sin tocar tu rama local ni tu working tree. Es una operación de solo lectura sobre tu trabajo: baja información, la guarda en un rincón de tu repositorio, y te deja exactamente donde estabas.

# Descarga lo que hay en el remoto, no cambia nada de tu trabajo
git fetch origin

La clave está en entender qué es origin/main. No es la rama main del servidor en tiempo real: es una copia local de dónde estaba main en el remoto la última vez que hiciste fetch. Por eso origin/main solo se mueve cuando tú ejecutas fetch (o pull, que hace fetch por dentro). Si configuraste el remoto siguiendo cómo conectar tu repositorio a GitHub, origin es ese enlace, y fetch es la forma segura de preguntarle “¿qué hay de nuevo?”.

Después de un fetch, tu rama actual sigue apuntando al mismo commit. Tu working tree no ha cambiado ni una coma. Lo único que se ha actualizado son las referencias remotas.

¿Qué hace exactamente git pull?

git pull hace dos cosas seguidas: primero un git fetch y después integra la rama upstream sobre la tuya. Por defecto esa integración es un git merge; si usas git pull --rebase, es un git rebase. Dicho de otra forma:

# Estos dos comandos equivalen, aproximadamente, a un git pull
git fetch origin
git merge origin/main

Ese segundo paso es todo. pull mueve tu rama activa para incorporar los commits del remoto, y al hacerlo modifica tu working tree. Si el historial ha divergido (tú tienes commits que el remoto no tiene, y el remoto tiene commits que tú no tienes), ese merge puede crear un commit de merge, o parar en seco con un conflicto que tienes que resolver a mano.

fetch te dice qué ha pasado. pull decide por ti qué hacer con ello.

¿Por qué git pull te sorprende y git fetch no?

La sorpresa siempre viene del segundo paso de pull: mueve tu HEAD y toca tus archivos. fetch no. Esta tabla resume qué toca cada comando en tu repositorio:

Diagrama comparativo de git fetch y git pull mostrando qué parte del repositorio local toca cada comando
git fetch se detiene al actualizar origin/main. git pull sigue: mueve tu rama y tu working tree.
Efectogit fetchgit pull
Descarga commits y objetos del remoto
Actualiza origin/main y demás refs remotas
Mueve tu rama local (HEAD)No
Modifica tu working treeNo
Puede abrir un merge o un conflicto ahora mismoNo

Léela de arriba abajo y verás dónde está la frontera: las dos primeras filas son idénticas, las tres últimas separan una operación inofensiva de una que reescribe dónde estás. Cuando entiendes esa frontera, dejas de temer al fetch y empiezas a respetar al pull.

¿Cuándo conviene preferir git fetch?

Prefiero git fetch siempre que quiero ver qué trae el remoto antes de dejar que toque mi trabajo. Un fetch seguido de una inspección me da control sobre el momento y la forma de integrar, en vez de aceptar lo que pull decida.

Los casos donde me quedo con fetch:

  • Tengo cambios a medias sin commitear. Un pull sobre un working tree sucio puede abortar o meterte en un conflicto en el peor momento. Con fetch bajas lo nuevo sin arriesgar nada, terminas o guardas tu cambio, y luego integras con calma.
  • Quiero revisar qué commits llegaron. Antes de mezclar el trabajo de otra persona sobre el mío, me gusta leer qué es. Un git log sobre las refs remotas me lo cuenta sin integrar nada.
  • Cuido un historial lineal. Si el equipo trabaja con rebase para mantener el historial limpio, un pull con merge por defecto ensucia esa línea con commits de merge de más. fetch más rebase te deja decidir.
  • Quiero refrescar todas las ramas remotas de golpe. git fetch --all actualiza las refs de todos los remotos sin integrar ninguna, útil cuando sigues varias ramas y solo quieres ver el estado antes de decidir sobre cuál trabajar.

Este control es exactamente lo que practicamos en el módulo interactivo de sincronización con el remoto. Pruébalo aquí, sin salir de la página:

Cargando ejercicio...

¿Cómo inspecciono lo que trajo el fetch antes de integrarlo?

Después de un fetch, comparas tu rama con la rama remota usando el rango HEAD..origin/main. Ese rango significa “commits que están en origin/main pero no en donde yo estoy”:

git fetch origin
# ¿Qué commits nuevos trae el remoto que yo no tengo?
git log --oneline HEAD..origin/main
# ¿Qué cambia en el código, línea a línea?
git diff HEAD origin/main

Si lo que ves te convence, integras cuando tú quieras:

git merge origin/main     # crea un merge si el historial divergió
# o, para mantener el historial lineal:
git rebase origin/main    # reaplica tus commits encima de lo remoto

Este flujo (bajar, mirar, decidir) es el mismo que resuelve el clásico push rechazado. Cuando GitHub te contesta con el error non-fast-forward, casi siempre significa que el remoto avanzó y tú no lo has integrado todavía: un fetch y un rebase (o merge) lo desatascan.

¿git pull con merge o con rebase?

git pull usa merge por defecto, pero puedes pedirle rebase por comando o por configuración. La elección es un compromiso, no un dogma:

git pull --rebase             # solo esta vez
git config pull.rebase true   # por defecto en este repositorio

Con merge conservas el historial tal cual ocurrió, a costa de commits de merge que pueden llenar de ruido la línea temporal. Con rebase mantienes un historial lineal y fácil de leer, a costa de reescribir tus commits locales (cosa que no debes hacer sobre commits que ya compartiste). Para el trabajo diario en una rama tuya que aún no has subido, --rebase suele dar un historial más limpio. La decisión final depende de cómo trabaje tu equipo, un tema que desarrollo en la guía de trabajar en equipo con Git y GitHub.

Errores comunes

Creer que git fetch ya integró los cambios

fetch actualiza origin/main, no tu rama. Es fácil hacer git fetch, ver que el comando terminó sin errores, y asumir que ya tienes el código nuevo en tu working tree. No lo tienes. Sigues sobre tu commit anterior hasta que hagas un merge o un rebase. Si notas que “el fetch no hizo nada”, en realidad hizo justo lo que debía: preparar la información, sin mover tu trabajo.

Hacer git pull con el working tree sucio

Un pull sobre cambios sin guardar puede pararte con un conflicto o abortar la operación. La costumbre sana es tener el working tree limpio antes de integrar: haz commit de lo tuyo, o guárdalo con git stash, y solo entonces trae lo remoto. Si ya estás a medias, fetch es la salida segura: baja lo nuevo ahora, intégralo cuando termines.

Confundir origin/main con el main del remoto

origin/main es una foto local, tomada en tu último fetch. Si tu compañero acaba de subir un commit hace treinta segundos y tú no has hecho fetch desde ayer, tu origin/main no lo refleja. Eso no es ningún fallo: las ramas de rastreo remoto solo se actualizan cuando tú lo pides. Un fetch fresco antes de mirar te ahorra decisiones sobre información caduca.

Checklist rápido

  • Sé que git fetch no toca mi rama ni mi working tree
  • Uso fetch cuando tengo cambios sin commitear o quiero inspeccionar antes de integrar
  • Reviso git log HEAD..origin/main antes de mezclar trabajo ajeno sobre el mío
  • Entiendo que git pull es fetch más merge (o rebase con --rebase)
  • Integro con merge o rebase según el historial que quiera mantener

Si quieres afianzar este modelo mental con ejercicios guiados en vez de solo leerlo, lo trabajamos paso a paso en el curso Git de cero a profesional, desde el primer commit hasta resolver conflictos con confianza.

Un concepto nuevo cada semana

Preguntas Frecuentes

¿git fetch cambia mi código?

No. git fetch descarga los commits del remoto y actualiza las ramas de rastreo como origin/main, pero no modifica tu rama local ni los archivos de tu working tree. Después de un fetch sigues exactamente donde estabas; para incorporar los cambios necesitas un merge o un rebase.

¿git pull es git fetch más algo?

Sí. git pull ejecuta primero un git fetch y luego integra la rama upstream sobre la tuya. Por defecto lo hace con git merge; si usas git pull --rebase, lo hace con git rebase. Por eso pull puede abrir un merge o un conflicto que fetch por sí solo nunca provoca.

¿Es peligroso hacer git fetch?

No, es de las operaciones más seguras de Git. No cambia tu trabajo: solo baja información y actualiza referencias remotas, así que puedes hacerlo con cambios a medias sin riesgo de perder nada.

¿Cómo veo qué trajo el fetch antes de integrarlo?

Compara tu rama con la remota con git log --oneline HEAD..origin/main para ver los commits nuevos, y con git diff HEAD origin/main para ver los cambios de código. Cuando lo revisado te convenza, integras con git merge origin/main o git rebase origin/main.

¿Debería usar siempre git pull —rebase?

Depende. En una rama tuya que aún no has compartido, --rebase suele dejar un historial más limpio y lineal. Pero rebase reescribe commits, así que no lo apliques sobre commits que otras personas ya usan. Si tu equipo tiene una convención, síguela antes que tu preferencia personal.