git rerere para coding agents: el mismo conflicto no se resuelve dos veces
Resumen
git rerere graba cómo resolviste un conflicto de merge y reaplica esa resolución cuando el mismo conflicto reaparece en rebase, merge o cherry-pick. Con rerere.enabled y autoupdate, el agente deja de re-derivar resoluciones idénticas en ramas largas y PRs apilados. Cero forget a ciegas, cero confiar en resoluciones rancias de 60 días. Git 2.50.1.

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 rerere (REuse REcorded REsolution) graba el conflicto y la resolución manual la primera vez que resuelves un merge, y reaplica esa resolución automáticamente cada vez que el mismo conflicto reaparece. El man (git-rerere(1); git-scm.com/docs/git-rerere; man local Git 2.50.1.428.g0e8243, binario Git 2.50.1 / Apple Git-155): assists the developer by recording conflicted automerge results and corresponding hand resolve results on the initial manual merge, and applying previously recorded hand resolutions to their corresponding automerge results.
El caso canónico es el de las ramas tópicas largas: haces merge de main en tu rama para probar, resuelves 5 conflictos, y una semana después repites el merge y aparecen los mismos 5 conflictos. Sin rerere, los resuelves otra vez a mano (o el agente los re-deriva con un LLM, gastando tokens y arriesgando una resolución distinta). Con rerere, Git reconoce la huella del conflicto y aplica tu resolución anterior.
No es merge. merge combina ramas y produce el conflicto; rerere solo recuerda cómo lo resolviste la vez anterior. No es rebase: rebase reescribe la serie y re-expone los mismos conflictos una y otra vez —rerere es lo que hace ese ciclo tolerable. No es cherry-pick: cherry-pick puede tropezar con el mismo conflicto al portar commits entre ramas, y rerere lo resuelve igual. Y no es gc: git rerere gc poda resoluciones viejas, pero no empaqueta ni recorta objetos.
Contrato: activa rerere.enabled una vez, resuelve bien la primera vez, y deja que Git repita tu resolución. Verifica cada resolución reutilizada antes de commitear. Cero forget a ciegas. Cero asumir que una resolución de hace 60 días sigue siendo correcta.
Activar (una vez por repo o global)
Rerere viene apagado por defecto. Sin el flag, git rerere no graba nada y los subcomandos no tienen estado que mostrar:
# Por repo (recomendado para agentes: vive en .git/config del worktree)
git config rerere.enabled true
# O global para todos tus repos y worktrees
git config --global rerere.enabled true
# Recomendado: que el stage de archivos auto-resueltos sea automático
git config rerere.autoupdate true
rerere.autoupdate hace que los archivos cuya resolución fue reutilizada queden staged (git add implícito) sin intervención. Sin él, el agente debe revisar y stagear a mano —que, siendo honestos, es lo que quieres en resoluciones delicadas. Regla operativa: autoupdate en true para ramas de experimento del agente, en false (default) cuando el merge toca código crítico y quieres ojo humano en cada archivo reutilizado.
Verifica que quedó activo:
git config --get rerere.enabled # debe imprimir: true

Cómo graba: preimage, postimage y rr-cache
Cuando un merge conflicta con rerere activo, Git guarda en .git/rr-cache/ (un directorio por huella de conflicto):
- preimage: el estado conflictuado (el archivo con marcadores
<<<<<<<). - postimage: el archivo tal como quedó tras tu resolución +
git add. - thisimage: el estado actual durante una resolución en curso.
La próxima vez que aparezca un conflicto con la misma huella (mismo contenido en conflicto, aunque los SHAs de los commits sean distintos), rerere copia el postimage sobre el worktree y reporta Resolved ... using previous resolution. La huella es de contenido, no de commits: funciona aunque hayas hecho rebase, amend o cherry-pick entre medias.
Tres consecuencias prácticas para agentes:
- La primera resolución debe ser buena. Rerere repite exactamente lo que grabó, incluyendo tus errores. Si la primera resolución metió un bug, cada reaplicación lo propaga en silencio.
- Es local al repo.
rr-cachevive en.git/y no se pushea, no se clona, no viaja en bundles. Cada clon, cada worktree y cada runner de CI empieza con la memoria vacía. Si tu pipeline de agentes depende de rerere, elrr-cachedebe persistir en el volumen del runner o re-entrenarse. - Cero volcar preimage/postimage al contexto del LLM. Son archivos enteros con marcadores; el agente solo necesita saber qué paths se auto-resolvieron (
git rerere status) y el diff de la resolución (git rerere diff).
Subcomandos: la mesa de trabajo
| Subcomando | Qué hace | Cuándo lo usa el agente |
|---|---|---|
git rerere (sin args) | Corre la reutilización sobre el estado actual; también lo invocan merge/rebase/am automáticamente | Rara vez manual; el flujo lo dispara solo |
status | Lista paths en conflicto cuya resolución se va a grabar | Tras cada merge conflictuado, para saber el scope |
remaining | Lista conflictos NO auto-resueltos (incluye submódulos, que rerere no puede grabar) | Para separar "revisar" de "ya resuelto" |
diff | Muestra el diff del estado actual de la resolución | Revisar qué cambió antes de git add |
forget <pathspec> | Borra la resolución grabada para esos paths en el conflicto actual | Cuando la resolución grabada es mala y quieres re-entrenar |
clear | Resetea el metadata si vas a abortar la resolución (git am --skip/--abort y git rebase --skip/--abort lo invocan solos) | Aborto manual de un merge a medias |
gc | Poda grabaciones viejas: no-resueltas de +15 días, resueltas de +60 días (vía gc.rerereUnresolved / gc.rerereResolved) | Higiene mensual; nunca en el loop caliente |
El par que más importa en el loop del agente es status + remaining: después de un merge o rebase conflictuado, status te dice qué se va a grabar y remaining qué exige cerebro. Todo lo que salga de remaining y no esté en status es trabajo manual real.
Receta para coding agents: rebase repetido sin re-trabajo
El escenario donde rerere más tokens ahorra: el agente mantiene una rama de feature contra un main que se mueve rápido, con rebase diario.
# 0. Setup una vez por worktree
git config rerere.enabled true
git config rerere.autoupdate true
# 1. Primer rebase: conflictos reales, resolución manual (humano o agente supervisado)
git rebase origin/main
# ... resuelve, git add, git rebase --continue
# 2. Segundo rebase (main avanzó): los mismos hunks conflictan,
# rerere los resuelve solo
git rebase origin/main
# Resolved 'src/lib/auth.ts' using previous resolution.
git rerere status # confirma qué se auto-resolvió
git diff --cached # revisa la resolución reutilizada ANTES de continuar
git rebase --continue
Notas de disciplina que separan un buen uso de un desastre silencioso:
- Revisa siempre
git diff --cachedtras una auto-resolución. El contexto alrededor del hunk pudo cambiar enmainy la resolución grabada —correcta hace dos semanas— puede ya no compilar o, peor, compilar con semántica distinta. - Si la resolución grabada es mala,
forgety re-entrena.git rerere forget <path>borra la grabación del conflicto actual; resuelves bien, commiteas, y la próxima vez se reaplica la buena. Nunca edites.git/rr-cache/a mano. clearal abortar. Si el agente aborta un merge (git merge --abort), el metadata de rerere se limpia solo. Si aborta "a mano" (checkout + reset), corregit rerere clearpara no dejar una grabación a medias que contamine la próxima.

Límites: lo que rerere no puede (y lo que caduca)
- Submódulos. Un conflicto en un gitlink no tiene postimage grabable; siempre sale en
remainingy siempre es manual. Si tu repo usa submódulos, el agente debe saber que esa parte nunca se auto-resuelve. - Archivos binarios y renames complejos. La huella es de contenido textual del hunk; binarios y detecciones de rename frágiles no reutilizan bien.
- Resoluciones rancias.
git rerere gcpoda lo no-resuelto de más de 15 días y lo resuelto de más de 60 (configurables víagc.rerereUnresolvedygc.rerereResolved). Una resolución podada simplemente deja de aplicarse —fallo seguro hacia "conflicto manual", nunca hacia "resolución inventada". No desactives el gc para "conservar memoria": una resolución de hace 6 meses sobre código que ya cambió es el bug silencioso perfecto. - No cruza repos. Cada clon/worktree/runner tiene su propia memoria. Documenta en el README del repo (
git config rerere.enabled trueen el setup del agente) en vez de asumir que la máquina ya lo trae.
Checklist del agente
git config --get rerere.enabled→trueantes de cualquier serie de rebases/merges repetidos.- Primera resolución manual y revisada por humano en código crítico; esa es la que se repite.
- Tras cada auto-resolución:
git rerere status+git diff --cachedantes de--continueo commit. git rerere remainingpara aislar lo que exige resolución manual real (submódulos incluidos).forget+ re-entrenar ante una grabación mala;clearsi abortas a mano.- Nunca editar
.git/rr-cache/directamente; nunca asumir memoria compartida entre clones o CI.
FAQ
¿Rerere decide solo, sin que yo revise?
No. Reaplica tu resolución anterior sobre el conflicto actual y te deja el resultado en el worktree (staged si autoupdate). El commit o el --continue siguen siendo tu decisión, y el diff merece un vistazo siempre.
¿Funciona con rebase, cherry-pick y am, o solo con merge? Con todos: merge, rebase, cherry-pick y am invocan a rerere automáticamente cuando está activo. La huella es del contenido en conflicto, no del comando que lo produjo.
¿Por qué mi runner de CI nunca auto-resuelve nada?
Porque rr-cache vive en .git/ y cada clon/CI efímero empieza vacío. Persiste el directorio en caché del runner o acepta que CI siempre resuelve a mano.
¿Cada cuánto limpio las grabaciones?
git rerere gc con los defaults (15/60 días) basta como higiene mensual. No lo corras en el loop caliente y no desactives el gc para acumular "memoria infinita".
Siguiente paso: si tu agente aún se instala a mano en cada máquina, el flujo guiado de /curso/instalar-agente deja el entorno listo; y si los merges duelen por otra razón (estrategia, no memoria), revisa merge y el estado limpio con status antes de cada serie.
Lecturas relacionadas
Sigue explorando Coding Agents y otras piezas para builders.

git maintenance para coding agents: housekeeping programado, no gc a pelo

git credential para coding agents: helpers, no tokens en el prompt

git verify-tag para coding agents: ningún release sin firma válida
