Guía9 min

git pull para coding agents: fetch primero, --ff-only, no rebase

Resumen

git pull es fetch más integrar. El default es --ff-only: falla si la rama local divergió. Un agente no corre pull --rebase, --autostash ni pull en el checkout del humano. Equivale a fetch + merge. Conflictos: merge --abort. Git 2.50.1.

GitHub
Fetch actualiza origin/main; --ff-only mueve HEAD solo si no hay divergencia

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 pull no es “actualiza el repo”. El man (Git 2.50.1 / Apple Git-155): primero corre git fetch con los mismos argumentos (salvo opciones de merge); luego integra la rama remota en la actual. Sin argumentos usa el upstream de la rama. git-fetch(1) deja los refs en .git/FETCH_HEAD.

Hay cuatro modos de integrar:

  1. --ff-only — solo fast-forward; falla si la historia local divergió. Es el default cuando no pasas un método para reconciliar divergencia (--rebase).
  2. --rebase — corre git rebase.
  3. --no-rebase — corre git merge.
  4. --squashgit merge --squash.

pull.rebase, pull.squash y pull.ff en config cambian el default. Un agente no asume el default del humano: pasa --ff-only explícito.

Esta guía no sustituye worktrees ni PRs con gh. El contrato: cuándo un agente puede traer remoto, qué flags están prohibidos, y cómo abortar.

Fetch no mueve tu rama

git fetch descarga objetos y actualiza remote-tracking (origin/main). No toca HEAD, index ni working tree. El man de pull documenta la equivalencia:

git fetch origin
git merge origin/next
# mismo efecto que:
git pull origin next

git pull origin next deja next en FETCH_HEAD y actualiza origin/next. Un agente que “necesita ver main” fetch; no pull sobre la rama de trabajo.

GitHub Docs (HTTP 200, 2026-09-03, Syncing a fork): en CLI, git fetch upstream y luego git merge upstream/main sobre la default local. Si no hay commits únicos, Git hace fast-forward. gh repo sync no sincroniza si hay conflictos; --force pisa la rama destino. Un agente no pasa --force.

Fetch llena origin/*; --ff-only solo avanza HEAD si es descendiente

Lo que el agente sí / no corre

QuieroComandoTrampa
Ver el remotogit fetch originpull sin --ff-only puede mergear o rebasar según config
Traer si no divergígit pull --ff-only o git merge --ff-only origin/<rama>Sin --ff-only, pull.rebase=true reescribe historia
Parar un mergegit merge --abortEl man de pull: conflictos de merge o rebase; rebase → git rebase --abort
Parar un rebase de pullgit rebase --abortNo reset --hard “para salir”
Worktree sucioNo pull--autostash stashea, aplica al final y puede pelear

Prohibido en autónomo:

  • git pull sin --ff-only (el default del man es --ff-only si no hay rebase flags; pull.rebase del repo/usuario lo anula).
  • --rebase / -r. El man: “This is a potentially dangerous mode of operation. It rewrites history… Do not use this option unless you have read git-rebase(1) carefully.” Historia publicada + rebase = force-push, que el agente no corre.
  • --rebase=interactive. Headless no edita la todo-list.
  • --autostash. El man: puedes operar con dirty worktree; “the final stash application after a successful merge might result in non-trivial conflicts.” No es stash deliberado.
  • --allow-unrelated-histories. El man: no hay (ni habrá) config para activarlo por default.
  • --squash autónomo. Deja el árbol como merge sin commit ni MERGE_HEAD.
  • git pull origin main sobre main local del humano o sobre una rama topic con commits propios no publicados vía PR. Traer main a un topic: fetch + merge --ff-only solo si el topic no divergió; si divergió, reporta, no rebase.
  • gh repo sync … --force. La doc de GitHub: overwrites the destination branch.
  • Recuperar un pull fallido con reset --hard. El man de pull dice que puedes recuperar con git reset; un agente usa --abort del merge/rebase, no --hard.

--no-edit aplica al merge commit, no al fast-forward. Fast-forward no crea commit; --no-commit no lo detiene. El man: si quieres que la rama no se mueva, --no-ff con --no-commit — un agente no inventa merge commits.

Receta (60 segundos)

Solo en un worktree propio:

git status -sb                  # limpio; no MERGE_HEAD / rebase
git fetch origin
git log --oneline HEAD..origin/<rama>
git merge --ff-only origin/<rama>

Si --ff-only falla: la rama divergió. Reporta git status -sb y git log --oneline --left-right HEAD...origin/<rama>. Cero --rebase. Cero merge a ciegas.

Atajo equivalente con el flag:

git pull --ff-only origin <rama>

Conflicto (solo si alguien saltó --ff-only):

git merge --abort               # o git rebase --abort si el pull era --rebase
git diff --name-only --diff-filter=U

Cero --continue. Cero borrar <<<<<<< a ciegas.

Divergencia: --ff-only aborta; no rebase ni autostash

Config que miente

git-config(1) pull.ff:

  • (unset / default de merge) fast-forward si el remoto es descendiente.
  • false--no-ff (siempre merge commit).
  • only--ff-only. Overridea merge.ff al hacer pull.

pull.rebase=true hace que git pull rebasée. El agente no lee la mente del humano: pasa --ff-only en la línea de comando.

Un hook o alias pull=pull --rebase es trampa. git pull --ff-only gana al alias solo si no está enmascarado; si type git-pull no es el binario, no corras pull.

Checklist

  • Worktree propio, git status -sb limpio, sin merge/rebase en curso.
  • git fetch primero; inspecciona HEAD..origin/<rama>.
  • Integrar solo con --ff-only. Si falla, reporta divergencia.
  • Conflicto → --abort + paths. Cero --continue.
  • Cero --rebase, --autostash, --force de gh repo sync.
  • Cero pull sobre main del checkout humano.
  • El resultado de traer main a un topic va a commits/PR, no a push de main.

FAQ

¿git pull a secas? El man: sin parámetros, tradicionalmente ≡ git pull origin; si existe branch.<name>.remote, usa ese remote y branch.<name>.merge. Un agente nombra remote y rama.

¿--ff-only es el default de verdad?cuando no hay método de reconciliar divergencia vía --rebase. pull.rebase / branch.<name>.rebase lo cambian. Por eso el flag va escrito.

¿Puedo pull --rebase en un topic no publicado? El man lo llama peligroso porque reescribe. Aunque el topic no esté en origin, un segundo worktree o un humano puede tener esa SHA. No.

¿Forks? GitHub: fetch upstream, checkout de la default local, git merge upstream/main. Fast-forward si no hay commits únicos. Conflictos → PR, no --force.

El curso instalar un agente cubre el loop local. Hub: comparativas y decisiones. Pull no es sandbox (sandboxing) ni undo de untracked (clean).

Verificado 2026-09-03 contra git-pull(1) y git-fetch(1) (Git 2.50.1 / Apple Git-155) y GitHub Docs “Syncing a fork” (HTTP 200, URL canónica /pull-requests/how-tos/work-with-forks/syncing-a-fork).