git absorb: el fixup automático que no sabías que necesitabas
Tenés 5 commits en una branch y el reviewer encontró bugs en 3 distintos. El ritual: git rebase -i, buscar cada commit, marcarlo como fixup, no equivocarte de orden. Diez minutos para arreglar tres líneas.
git absorb hace todo eso solo. No es solo git commit --fixup SHA — también detecta el SHA correcto por vos.
# Instalación
brew install git-absorb # macOS
cargo install git-absorb # cualquier plataforma
# El flujo
git add -p # staging selectivo de los fixes
git absorb # detecta y crea fixup! commits automáticamente
git rebase -i --autosquash # aplica todo de unaLo que genera git absorb en tu historial:
$ git log --oneline
f3a1b2c fixup! feat: agregar validación de formulario
9e4d5a1 fixup! fix: corregir typo en config
a7c8e0f feat: agregar validación de formulario
3b2d1e9 fix: corregir typo en configDespués de rebase --autosquash, esos fixup! desaparecen y los commits quedan limpios.
Funciona así: para cada hunk staged, verifica si el cambio es independiente (conmuta) de cada commit reciente. Cuando encuentra uno con el que no conmuta, ese es el target; crea el fixup! apuntando exactamente ahí. Por defecto revisa los últimos 10 commits. Si el hunk conmuta con todos, no encontró candidato: lo deja staged y muestra un warning. No adivina.
El truco está en git add -p: stage exactamente los cambios que corresponden a cada fix. Cuanto más atómico sea lo que stageas, más precisa es la detección. El historial queda limpio sin haber abierto el editor de rebase.
Tip: git absorb --and-rebase hace el rebase automáticamente en un solo paso. O configurá git config --global rebase.autoSquash true para saltarte el flag --autosquash siempre.
Cuándo falla: dos casos concretos. Si stageas código completamente nuevo sin contexto en commits recientes, no encuentra candidato: muestra un warning y deja el hunk staged.
El caso más silencioso: dos commits que tocaron la misma región. Commit A introduce expiry=3600 (el bug). Commit B renombra esa misma variable después. Tu fix (3600 → 86400) no conmuta con B → git absorb apunta ahí, aunque el bug vino de A. El historial queda limpio pero semánticamente incorrecto. Para ese caso, rebase manual.
Las herramientas no obvias existen por algo. Instalalo antes de que tu próxima PR se convierta en un quirófano de commits.
🔗 Sugerencias de lectura
- La Cerca de Chesterton en el Refactoring Senior: Por qué investigar antes de tocar código que no entendés.
- Efecto Zeigarnik en el Workflow del Dev: La tensión psicológica detrás del impulso de limpiar commits.