Files
fn_registry/docs/adr/0001-gitbutler-experiment.md
T
egutierrez 7597549fcf docs: añadir ADR, diario, CHANGELOG y comando /entrada_diario
Infraestructura de documentación operativa y de decisiones:

- docs/adr/ — Architecture Decision Records. Incluye plantilla y
  ADR 0001 documentando el experimento y retirada de GitButler.
- docs/diary/ — diario de avances con un archivo por día.
  Primera entrada 2026-04-24.md retrocubriendo esta sesión
  (conectar aurgi-pc, dashboard fn_monitoring, funciones systemd
  locales, ADR GitButler, regla KISS).
- CHANGELOG.md — formato Keep a Changelog para cambios cara a
  usuario/agentes. Sección 2026-04-24 con Added/Changed/Fixed/Removed.
- .claude/commands/entrada_diario.md — slash command para añadir
  entradas al diario con formato consistente.

Separación:
  diary   = contexto operativo diario
  CHANGELOG = qué cambió en el código
  ADR     = por qué se decidió algo
  rules   = reglas operativas del agente

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 14:27:38 +02:00

4.3 KiB

ADR 0001 — Experimento con GitButler para trabajo paralelo

  • Fecha: 2026-04-24
  • Estado: rejected

Contexto

El flujo de trabajo en fn_registry a menudo toca varias tareas simultáneamente: issues independientes en distintos dominios, features nuevas, fixes rápidos, docs. Con git + ramas tradicionales esto obliga a git stash / checkout constantes o a mezclar cambios en una misma rama.

Se planteó GitButler (virtual branches) como herramienta para mantener múltiples líneas de trabajo activas en el mismo working tree sin dance de stash/checkout, con push independiente de cada VB a su rama remota en Gitea.

Restricciones relevantes del entorno:

  • Repo grande con submódulos C++ activos (cpp/vendor/imgui, implot, tracy, glfw) usados por apps nativas.
  • Archivos "puente" que casi siempre se tocan: go.mod, python/uv.lock, registry.db, frontend/pnpm-lock.yaml.
  • Flujo de commit/push integrado con agentes de Claude Code.

Decisión

Se instaló y probó GitButler durante una sesión de trabajo:

  • Binario ~/.local/bin/but (37 MB).
  • Plugin gitbutler-tools en el marketplace de Claude Code.
  • Skill gitbutler en repo_Claude/.claude/skills/gitbutler/.
  • Hooks PreToolUse, PostToolUse, Stop en settings.json invocando but claude ....
  • Sección dedicada en el SKILL.md del agente gitea explicando cómo combinar VBs con issues y PRs.

Se inició trabajo usando virtual branches: rama de workspace gitbutler/workspace, virtual branches e-branch-1/2/3, VB creada manualmente fn-monitoring-setup.

Alternativas consideradas

  1. Mantener git + ramas tradicionales (status quo). Conocido, sin deps extra, compatible con todo lo ya existente.
  2. git worktree + varias checkouts para paralelizar sin stash.
  3. GitButler virtual branches — opción experimentada.

Consecuencias del experimento (problemas encontrados)

  1. Bugs con submódulos: al añadir/modificar .gitmodules junto con gitlinks (cpp/vendor/glfw) GitButler no podía commitear el cambio; creaba commits vacíos (0 files changed) o metía contenido de otros cambios "unassigned" en el commit. Fue necesario recurrir a git commit --no-verify para saltarse el pre-commit hook, lo que a su vez rompía el modo GitButler y obligaba a but teardown.
  2. Auto-commits con el texto del chat como mensaje: el plugin de Claude Code hacía snapshots automáticos tras cada edición con el texto literal del turno del usuario como commit message. Ejemplo real: 56c7c3f3 haz que cree servicio de sistema , instalado el mingw.
  3. Pre-commit hook que bloquea git commit directo: obliga a usar but commit o a añadir --no-verify, que a su vez rompe el modo GitButler.
  4. Overhead de herramientas: binario 37 MB + plugin + skill + hooks + entrada en marketplace. Mucha superficie para gestionar.
  5. Falla silenciosa de but commit: mensajes Warning: Some selected changes could not be committed sin detalle de qué no se incluyó.
  6. Complicación con rm/--no-verify: al salir de GitButler (but teardown) quedan ramas fantasma (gitbutler/workspace, gitbutler/target, e-branch-*) y estado interno (.git/gitbutler/).

Decisión final

Retirar GitButler completamente:

  • but teardown para salir del modo workspace.
  • Eliminación del binario, plugin, skill, hooks, config, ramas y estado interno. Documentado en commit a5ab498 de repo_Claude.
  • Consolidación de los commits útiles de la sesión (registry.db untrack, submódulo GLFW, 7 funciones systemd locales, pipeline install_systemd_service) en 2 commits limpios sobre master de fn_registry.

Aprendizaje

Se deriva una regla KISS formal (.claude/rules/kiss.md):

  • Antes de adoptar una herramienta externa, medir la fricción real del flujo actual. Si no duele, añadir capas no ayuda.
  • Cuestionar cada nueva dependencia: coste de instalación + mantenimiento + aprendizaje + riesgo upstream vs. beneficio concreto y medible.
  • Preferir lo que ya tenemos (git, submódulos, fn CLI) antes que soluciones "generalistas" con más superficie.

Para el caso concreto de trabajo paralelo, si vuelve a surgir la necesidad, la siguiente alternativa a explorar sería git worktree — ya soportado por git nativo, sin deps extra, sin hooks externos.