# Command: git-recovery Recupera el repositorio de estados inconsistentes causados por worktrees huérfanos, branches bloqueados o conflictos de git. Ejecuta automáticamente cuando se detectan errores git durante operaciones de issues. ## Para el usuario ### Cuándo usar este comando - Cuando hay errores "exit status 128" al crear worktrees - Cuando git reporta "worktree already exists" - Cuando hay branches que no se pueden eliminar - Cuando `git worktree list` muestra worktrees huérfanos - Cuando el orquestador paralelo falla por problemas git - **Automáticamente:** El sistema lo invoca cuando detecta errores git ### Sintaxis ```bash /git:recovery [--aggressive] ``` ### Parámetros - `--aggressive` (opcional): Fuerza limpieza agresiva incluyendo branches remotas y reset de estado ### Ejemplos **Ejemplo 1: Recuperación estándar (recomendado)** ```bash /git:recovery ``` Limpia worktrees huérfanos, verifica estado, sincroniza con remoto. **Ejemplo 2: Recuperación agresiva** ```bash /git:recovery --aggressive ``` Incluye force-prune, eliminación de branches huérfanas, reset de índice. ## Para Claude ### Precondiciones Verificar antes de ejecutar: - [ ] Estamos en un repositorio git válido - [ ] Hay permisos para modificar .git/ - [ ] No hay operaciones git críticas en progreso (rebase, merge) ### Inputs - `--aggressive` (opcional): Modo agresivo de limpieza ### Flujo obligatorio #### 1. Diagnóstico inicial ```bash echo "🔍 Diagnosticando estado del repositorio..." echo "" # Verificar que estamos en repo git if [ ! -d ".git" ]; then echo "❌ Error: No estamos en un repositorio git" exit 1 fi # Guardar estado actual git branch --show-current > /tmp/git-recovery-current-branch.txt git status --porcelain > /tmp/git-recovery-status.txt echo "Rama actual: $(cat /tmp/git-recovery-current-branch.txt)" echo "Cambios pendientes: $(wc -l < /tmp/git-recovery-status.txt) archivos" echo "" ``` #### 2. Análisis de problemas ```bash echo "📋 Analizando problemas..." echo "" # Listar worktrees (puede fallar si hay huérfanos) echo "Worktrees actuales:" git worktree list 2>&1 || echo " (error listando worktrees - probablemente hay huérfanos)" echo "" # Verificar branches locales echo "Branches locales:" git branch --list echo "" # Verificar branches remotas echo "Estado remoto:" git remote -v git fetch --dry-run 2>&1 || echo " (problemas con fetch)" echo "" ``` #### 3. Limpieza de worktrees huérfanos ```bash echo "🧹 Limpiando worktrees huérfanos..." echo "" # Ejecutar prune (elimina referencias a worktrees que ya no existen) git worktree prune -v 2>&1 # Verificar si aún hay worktrees huérfanos en disco if [ -d "worktrees" ]; then echo "" echo "Verificando directorio worktrees/..." # Listar directorios en worktrees/ for worktree_dir in worktrees/issue-*; do if [ -d "$worktree_dir" ]; then worktree_name=$(basename "$worktree_dir") # Verificar si git lo conoce if ! git worktree list | grep -q "$worktree_dir"; then echo " ⚠️ Worktree huérfano detectado: $worktree_name" # Eliminar directorio huérfano rm -rf "$worktree_dir" echo " ✓ Eliminado: $worktree_dir" fi fi done fi echo "" echo "✓ Limpieza de worktrees completada" echo "" ``` #### 4. Verificación de branches bloqueados ```bash echo "🔓 Verificando branches bloqueados..." echo "" # Listar branches que podrían estar bloqueados git branch --list 'issue/*' 'quick/*' | while read -r branch; do branch=$(echo "$branch" | sed 's/^\* //' | xargs) # Verificar si la branch está asociada a un worktree if git worktree list | grep -q "$branch"; then echo " ℹ️ Branch activa en worktree: $branch" else # Branch no está en worktree, podría estar mergeada if git branch --merged master | grep -q "$branch"; then echo " ✓ Branch mergeada, puede eliminarse: $branch" git branch -d "$branch" 2>&1 || echo " (no se pudo eliminar automáticamente)" else echo " ⚠️ Branch NO mergeada: $branch" fi fi done echo "" ``` #### 5. Sincronización con remoto ```bash echo "🔄 Sincronizando con remoto..." echo "" # Volver a master si no estamos ahí current_branch=$(git branch --show-current) if [ "$current_branch" != "master" ]; then echo "Cambiando a master desde $current_branch..." git checkout master 2>&1 || { echo "❌ No se pudo cambiar a master" echo " Quedando en rama: $current_branch" } fi # Fetch y pull echo "Actualizando desde origin/master..." git fetch origin 2>&1 git pull --rebase origin master 2>&1 || { echo "⚠️ Problemas al hacer pull, continuando..." } echo "" echo "✓ Sincronización completada" echo "" ``` #### 6. Modo agresivo (solo si --aggressive) ```bash if [ "$AGGRESSIVE" = "true" ]; then echo "⚡ MODO AGRESIVO ACTIVADO" echo "" echo "Limpiando branches remotas obsoletas..." git remote prune origin -v 2>&1 echo "" echo "Verificando integridad del repositorio..." git fsck --full 2>&1 | head -20 echo "" echo "Limpiando objetos no referenciados..." git gc --prune=now 2>&1 echo "" echo "Verificando índice..." if [ -f ".git/index.lock" ]; then echo " ⚠️ Encontrado index.lock (proceso git interrumpido)" rm -f .git/index.lock echo " ✓ Eliminado .git/index.lock" fi echo "" echo "✓ Limpieza agresiva completada" echo "" fi ``` #### 7. Verificación final ```bash echo "✅ Verificación final..." echo "" # Estado limpio echo "Estado del repositorio:" git status echo "" # Worktrees finales echo "Worktrees activos:" git worktree list echo "" # Branches locales echo "Branches locales:" git branch --list echo "" ``` #### 8. Resumen ```bash echo "════════════════════════════════════════════════════════" echo "RECUPERACIÓN COMPLETADA" echo "════════════════════════════════════════════════════════" echo "" # Comparar estado antes/después CHANGES_BEFORE=$(wc -l < /tmp/git-recovery-status.txt) CHANGES_AFTER=$(git status --porcelain | wc -l) echo "Resumen:" echo " Rama actual: $(git branch --show-current)" echo " Cambios pendientes: $CHANGES_AFTER (antes: $CHANGES_BEFORE)" echo " Worktrees activos: $(git worktree list | grep -v bare | wc -l)" echo " Sincronizado con origin: $(git rev-parse HEAD) = $(git rev-parse origin/master 2>/dev/null || echo 'N/A')" echo "" if [ "$AGGRESSIVE" = "true" ]; then echo "Modo agresivo aplicado: ✓" echo "" fi echo "Próximos pasos:" echo " - Verifica que master esté actualizado: git log --oneline -5" echo " - Reintenta la operación que falló" echo " - Si persisten errores, reporta el problema" echo "" # Limpiar archivos temporales rm -f /tmp/git-recovery-*.txt ``` ### Detección automática de errores git El orquestador Go debe detectar estos patrones de error: **Patrones de error que activan recovery:** - `exit status 128` (error genérico de git) - `worktree .* already exists` - `reference is not a tree` - `cannot lock ref` - `index.lock` - `fatal: not a git repository` **Flujo de auto-recovery:** 1. Orquestador detecta error git 2. Pausa ejecución del grupo actual 3. Ejecuta `claude -p /git:recovery` automáticamente 4. Si recovery tiene éxito (exit code 0), reintenta la operación 5. Si recovery falla, aborta con error descriptivo ### Verificación final ```bash # Verificar que el repo quedó en estado válido git status --porcelain git worktree list # Exit code 0 si todo OK, 1 si hay problemas if [ $? -eq 0 ]; then exit 0 else echo "❌ El repositorio sigue con problemas" exit 1 fi ``` ## Convenciones - **No destructivo por defecto:** Solo limpia worktrees huérfanos y branches mergeadas - **Modo agresivo bajo demanda:** Solo con flag explícito - **Siempre sincroniza con remoto:** Garantiza consistencia - **Preserva cambios locales:** No hace reset hard sin --aggressive - **Logs detallados:** Reporta cada acción para debugging ## Troubleshooting ### Error: "cannot remove worktree" **Causa:** Proceso usando archivos del worktree **Solución:** ```bash # Verificar procesos lsof +D worktrees/ 2>/dev/null # Forzar eliminación con --aggressive /git:recovery --aggressive ``` ### Error: "index.lock exists" **Causa:** Operación git previa interrumpida **Solución:** Automáticamente manejado en modo estándar. Si persiste: ```bash rm -f .git/index.lock /git:recovery ``` ### Warning: "branch no mergeada" **Causa:** Branch contiene commits no integrados a master **Solución:** Verificar manualmente si es seguro eliminarla: ```bash git log master..branch-name git branch -D branch-name # Solo si estás seguro ``` ## Reglas críticas - **NUNCA hacer git reset --hard sin --aggressive** - puede perder cambios - **SIEMPRE hacer backup del estado antes de recovery agresivo** - **NUNCA eliminar branches no mergeadas automáticamente** - **SIEMPRE sincronizar con remoto después de limpieza** - **SIEMPRE verificar que quedó en estado válido** - **LOGS completos** - reportar cada acción para auditoría ## Integración con orquestador El orquestador Go debe: 1. **Capturar stderr** de comandos git 2. **Detectar patrones** de error conocidos 3. **Invocar recovery** automáticamente: ```go if isGitError(err) { log.Warn("Error git detectado, ejecutando recovery...") if err := executeRecovery(); err != nil { return fmt.Errorf("recovery falló: %w", err) } // Reintentar operación original return retryOperation() } ``` 4. **Limitar reintentos** a 1 vez por operación 5. **Abortar si recovery falla** ## Ejemplos de uso automático **Escenario 1: Error al crear worktree** ``` [ERROR] crear worktree: exit status 128 [INFO] Detectado error git, ejecutando recovery... [INFO] ✓ Recovery completado [INFO] Reintentando crear worktree... [SUCCESS] ✓ Worktree creado exitosamente ``` **Escenario 2: Recovery falla** ``` [ERROR] crear worktree: exit status 128 [INFO] Detectado error git, ejecutando recovery... [ERROR] Recovery falló: problemas persistentes [ABORT] Abortando ejecución del grupo ```