Añadidos arhcivos basicos de repos
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [git, workflow, trunk-based]
|
||||
---
|
||||
|
||||
# Command: git-branch
|
||||
|
||||
Crea una rama de trabajo. **Nunca trabajar directamente en master.**
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar siempre antes de empezar cualquier trabajo. Dataforge sigue trunk-based development estricto: todo el trabajo se hace en ramas temporales que se integran rápidamente a master.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/git:branch issue <NNNN> <slug>
|
||||
/git:branch quick <slug>
|
||||
```
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Rama para issue existente**
|
||||
```bash
|
||||
/git:branch issue 0013 hot-reload
|
||||
```
|
||||
|
||||
Crea rama `issue/0013-hot-reload` para implementar el issue 0013.
|
||||
|
||||
**Ejemplo 2: Rama para cambio rápido**
|
||||
```bash
|
||||
/git:branch quick fix-typo-readme
|
||||
```
|
||||
|
||||
Crea rama `quick/fix-typo-readme` para fix pequeño sin issue asociado.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Repositorio es un repo git válido
|
||||
- [ ] Branch master existe
|
||||
- [ ] No hay cambios sin commitear (working tree limpio)
|
||||
|
||||
### Inputs
|
||||
|
||||
Preguntar al usuario si el cambio está asociado a un issue o no.
|
||||
|
||||
#### Si es un issue:
|
||||
- `issue_number`: número de 4 dígitos (e.g. `0020`)
|
||||
- `slug`: nombre corto separado por guiones (e.g. `hot-reload`)
|
||||
|
||||
#### Si es un cambio rápido (sin issue):
|
||||
- `slug`: nombre corto descriptivo separado por guiones (e.g. `fix-typo-readme`)
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Verificar estado actual del repositorio
|
||||
|
||||
{{include: git-verify-clean}}
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
git status --short
|
||||
```
|
||||
|
||||
**Si no estamos en master:**
|
||||
```bash
|
||||
git checkout master
|
||||
```
|
||||
|
||||
**Si hay cambios sin commitear:**
|
||||
✗ Error: Working tree no está limpio
|
||||
|
||||
⚠ Avisar al usuario y **STOP** hasta resolver:
|
||||
```
|
||||
Hay cambios sin commitear. Opciones:
|
||||
|
||||
1. Commitear cambios primero:
|
||||
git add .
|
||||
git commit -m "mensaje"
|
||||
|
||||
2. Hacer stash:
|
||||
git stash
|
||||
|
||||
3. Descartar cambios (⚠ peligroso):
|
||||
git reset --hard
|
||||
```
|
||||
|
||||
#### 2. Actualizar master desde remoto
|
||||
|
||||
{{include: git-update-master}}
|
||||
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
#### 3. Crear la rama según tipo
|
||||
|
||||
**Para issues:**
|
||||
```bash
|
||||
git checkout -b issue/<issue_number>-<slug>
|
||||
```
|
||||
|
||||
Ejemplo: `git checkout -b issue/0013-hot-reload`
|
||||
|
||||
**Para cambios rápidos:**
|
||||
```bash
|
||||
git checkout -b quick/<slug>
|
||||
```
|
||||
|
||||
Ejemplo: `git checkout -b quick/fix-typo-readme`
|
||||
|
||||
#### 4. Verificar creación de rama
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
```
|
||||
|
||||
Debe mostrar el nombre de la nueva rama.
|
||||
|
||||
### Verificación final
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Rama `<nombre-rama>` creada desde master actualizado
|
||||
|
||||
Puedes empezar a trabajar.
|
||||
|
||||
Cuando termines:
|
||||
/git:push
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Formato de rama issue**: `issue/<NNNN>-<slug>` (siempre 4 dígitos)
|
||||
- **Formato de rama quick**: `quick/<slug>` (sin número)
|
||||
- **Ramas cortas**: idealmente horas, no días
|
||||
- **Una rama por issue**: no mezclar issues en la misma rama
|
||||
- **Nunca pushear la rama al remoto**: el push se hace desde master después del merge
|
||||
- **No rebase interactivo**: si los commits son limpios desde el inicio, no reescribir historia
|
||||
- **No commits WIP**: cada commit en la rama debe ser atómico y con mensaje real
|
||||
|
||||
## Features multi-issue
|
||||
|
||||
Para features que no caben en una sola rama, usar sub-issues con sufijo letra:
|
||||
|
||||
```
|
||||
issue/0015a-telegram-types
|
||||
issue/0015b-telegram-client
|
||||
issue/0015c-telegram-listener
|
||||
issue/0015d-telegram-enable
|
||||
```
|
||||
|
||||
Cada sub-rama sigue el mismo flujo: crear → implementar → merge --no-ff → delete.
|
||||
El código parcial se protege con **feature flags** en `dev/feature_flags.json` (no con commits WIP).
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "fatal: not a git repository"
|
||||
|
||||
**Causa:** El directorio actual no es un repositorio git.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git init
|
||||
# O navegar al directorio correcto
|
||||
cd /ruta/al/repo
|
||||
```
|
||||
|
||||
### Error: "Your branch is behind 'origin/master'"
|
||||
|
||||
**Causa:** Master local está desactualizado respecto al remoto.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git pull --rebase
|
||||
```
|
||||
|
||||
### Error: "fatal: A branch named 'issue/0013-hot-reload' already exists"
|
||||
|
||||
**Causa:** La rama ya existe localmente.
|
||||
|
||||
**Solución:**
|
||||
1. Verificar si tiene cambios importantes:
|
||||
```bash
|
||||
git log issue/0013-hot-reload
|
||||
```
|
||||
|
||||
2. Si no tiene cambios importantes, borrar:
|
||||
```bash
|
||||
git branch -D issue/0013-hot-reload
|
||||
```
|
||||
|
||||
3. Si tiene cambios importantes, usar otro nombre o recuperar esos cambios primero.
|
||||
|
||||
### Advertencia: "You have unstaged changes"
|
||||
|
||||
**Causa:** Hay archivos modificados sin stagear.
|
||||
|
||||
**Solución:**
|
||||
1. Ver cambios:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Decidir qué hacer:
|
||||
- Commitear: `git add . && git commit -m "mensaje"`
|
||||
- Descartar: `git restore <archivo>`
|
||||
- Stash: `git stash`
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NUNCA trabajar directamente en master** sin rama temporal
|
||||
- **SIEMPRE** verificar que el working tree esté limpio antes de crear rama
|
||||
- **SIEMPRE** actualizar master desde remoto antes de crear rama
|
||||
- **NO** pushear las ramas temporales al remoto (se integran via merge a master)
|
||||
- **NO** usar underscores en nombres de rama, solo guiones
|
||||
- **NO** crear ramas de larga duración (máximo 1-2 días, idealmente horas)
|
||||
@@ -0,0 +1,380 @@
|
||||
---
|
||||
version: 2.0.0
|
||||
updated: 2026-03-11
|
||||
tags: [git, workflow, trunk-based, integration]
|
||||
---
|
||||
|
||||
# Command: git-push
|
||||
|
||||
Integra cambios a master y publica. Soporta ramas `issue/*` y `quick/*`.
|
||||
|
||||
## Para el usuario
|
||||
|
||||
### Cuándo usar este comando
|
||||
|
||||
Usar cuando hayas terminado de trabajar en una rama temporal (issue/* o quick/*) y quieras integrar los cambios a master y publicar al remoto.
|
||||
|
||||
### Sintaxis
|
||||
|
||||
```bash
|
||||
/git:push
|
||||
```
|
||||
|
||||
No requiere argumentos. Detecta automáticamente la rama actual y maneja el flujo completo.
|
||||
|
||||
### Ejemplos
|
||||
|
||||
**Ejemplo 1: Desde rama issue**
|
||||
```bash
|
||||
# Estando en issue/0013-hot-reload
|
||||
/git:push
|
||||
```
|
||||
|
||||
Crea commits atómicos, ejecuta tests, merge a master, push y limpia rama local.
|
||||
|
||||
**Ejemplo 2: Desde master con cambios**
|
||||
```bash
|
||||
# Estando en master con cambios pendientes
|
||||
/git:push
|
||||
```
|
||||
|
||||
Detecta cambios, crea automáticamente rama `quick/<slug>`, y ejecuta flujo completo.
|
||||
|
||||
## Para Claude
|
||||
|
||||
### Precondiciones
|
||||
|
||||
Verificar antes de ejecutar:
|
||||
|
||||
- [ ] Repositorio es un repo git válido
|
||||
- [ ] Hay cambios para commitear O estamos en una rama temporal
|
||||
- [ ] Tests del proyecto disponibles (si aplica)
|
||||
|
||||
### Inputs
|
||||
|
||||
No requiere inputs del usuario. El comando detecta automáticamente:
|
||||
- Rama actual (master, issue/*, quick/*)
|
||||
- Cambios pendientes (staged, unstaged)
|
||||
- Archivos modificados
|
||||
|
||||
### Flujo obligatorio
|
||||
|
||||
#### 1. Verificar rama actual y estado
|
||||
|
||||
```bash
|
||||
git branch --show-current
|
||||
git status --short
|
||||
```
|
||||
|
||||
##### Caso A: Estamos en rama `issue/*` o `quick/*`
|
||||
|
||||
✓ Continuar directamente al paso 2.
|
||||
|
||||
##### Caso B: Estamos en `master` con cambios pendientes
|
||||
|
||||
**Crear rama quick automáticamente antes de continuar:**
|
||||
|
||||
1. Detectar contexto automáticamente:
|
||||
|
||||
```bash
|
||||
git diff --name-only
|
||||
git diff --name-only --cached
|
||||
```
|
||||
|
||||
2. Analizar archivos para generar slug descriptivo:
|
||||
- Cambios en `README.md` → `update-readme`
|
||||
- Cambios en `.claude/` → `update-claude-config`
|
||||
- Cambios en `feature_flags.json` → `update-flags`
|
||||
- Cambios en `dev/issues/` → `update-issues`
|
||||
- Cambios en archivos de código → usar nombre del archivo principal
|
||||
- Cambios múltiples sin patrón claro → `misc-updates`
|
||||
|
||||
3. Crear rama quick automáticamente:
|
||||
|
||||
```bash
|
||||
git checkout -b quick/<slug-generado>
|
||||
```
|
||||
|
||||
4. Mostrar mensaje informativo:
|
||||
```
|
||||
✓ Creada rama automática: quick/<slug-generado>
|
||||
|
||||
Si estos cambios son parte de un issue, cancela (Ctrl+C) y usa:
|
||||
/factory:fix-issue <NNNN>
|
||||
```
|
||||
|
||||
5. Continuar al paso 2.
|
||||
|
||||
**IMPORTANTE:**
|
||||
- Por defecto siempre crear rama `quick/`
|
||||
- Solo usar `issue/` cuando se invoque desde `/factory:fix-issue` o el usuario indique explícitamente
|
||||
- No inventar números de issue
|
||||
- El objetivo es reducir fricción: si no sabes qué es, es un cambio quick
|
||||
|
||||
##### Caso C: Estamos en `master` sin cambios
|
||||
|
||||
✗ Error: No hay nada que publicar
|
||||
|
||||
**STOP**
|
||||
|
||||
#### 2. Revisar cambios y crear commits por bloque
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --stat
|
||||
git diff
|
||||
```
|
||||
|
||||
Analizar los cambios y agruparlos en **bloques lógicos**. Cada bloque debe tener la misma naturaleza/propósito.
|
||||
|
||||
**Tipos de bloques comunes:**
|
||||
- Nuevas funcionalidades (feat)
|
||||
- Correcciones de bugs (fix)
|
||||
- Tests (test)
|
||||
- Documentación (docs)
|
||||
- Refactoring (refactor)
|
||||
- Configuración/mantenimiento (chore)
|
||||
|
||||
**Crear commits atómicos por bloque:**
|
||||
|
||||
```bash
|
||||
git add <archivos_del_bloque_1>
|
||||
git commit -m "<tipo>: <resumen breve>" -m "<descripción larga en español explicando qué cambia, por qué se hizo, impacto esperado y alcance del bloque>"
|
||||
|
||||
git add <archivos_del_bloque_2>
|
||||
git commit -m "<tipo>: <resumen breve>" -m "<descripción larga en español>"
|
||||
```
|
||||
|
||||
**Convención de tipos:**
|
||||
- `feat:` nueva funcionalidad
|
||||
- `fix:` corrección de error
|
||||
- `refactor:` cambio estructural sin cambio funcional
|
||||
- `docs:` documentación
|
||||
- `chore:` mantenimiento, config, deps
|
||||
- `test:` tests nuevos o modificados
|
||||
|
||||
**Reglas críticas de commits:**
|
||||
- **No WIP**: nunca commitear "wip", "tmp", "fix fix" ni código a medias
|
||||
- **No mezclar tipos**: no combinar `feat:` + `test:` en un mismo commit
|
||||
- **No squash**: los commits individuales se preservan en master via `--no-ff`
|
||||
- **No rebase interactivo**: si los commits ya son limpios, no reescribir historia
|
||||
- **Descripción larga obligatoria**: cada commit debe tener cuerpo explicativo en español
|
||||
|
||||
#### 3. Ejecutar tests
|
||||
|
||||
{{include: run-tests}}
|
||||
|
||||
**Obligatorio antes de mergear:**
|
||||
|
||||
```bash
|
||||
go test -tags goolm ./...
|
||||
```
|
||||
|
||||
**Casos:**
|
||||
- Tests **pasan** → ✓ Continuar al paso 4
|
||||
- Tests **fallan** → ✗ **STOP**: corregir antes de continuar. No mergear código roto.
|
||||
- No hay tests aplicables (solo docs/config) → ℹ Indicar al usuario y continuar al paso 4
|
||||
|
||||
#### 4. Evaluar feature flags
|
||||
|
||||
Feature flags se usan cuando el issue es **parte de una feature multi-issue** o el cambio tiene riesgo y necesita poder desactivarse.
|
||||
|
||||
**Feature flag ≠ WIP** — un flag protege código terminado y testeado, no código a medias.
|
||||
|
||||
**Si se modificó `dev/feature_flags.json` o cambios son parte de feature multi-fase:**
|
||||
|
||||
1. Verificar que `dev/feature_flags.json` existe y está actualizado
|
||||
2. Confirmar que el flag correspondiente tiene el estado correcto (`enabled: true/false`)
|
||||
3. Incluir el archivo en el commit correspondiente (no crear commit separado solo para flags)
|
||||
|
||||
**Si el issue es autocontenido** (se completa en esta rama):
|
||||
- No necesita flag
|
||||
- ✓ Saltar este paso
|
||||
|
||||
#### 5. Merge a master con --no-ff
|
||||
|
||||
{{include: git-merge-to-master}}
|
||||
|
||||
```bash
|
||||
git checkout master
|
||||
git pull --rebase
|
||||
git merge --no-ff <rama> -m "merge: <rama> — <título breve>"
|
||||
```
|
||||
|
||||
**Formato del mensaje de merge:**
|
||||
- Título: `merge: <rama> — <descripción corta>`
|
||||
- Cuerpo (opcional): resumen de lo que entra
|
||||
|
||||
**Ejemplos:**
|
||||
```
|
||||
merge: issue/0021-threads-default-config — habilitar threads en agentes
|
||||
merge: quick/fix-typo-readme — corregir typo en README
|
||||
```
|
||||
|
||||
**Si hay conflictos durante el merge:**
|
||||
1. Resolver los conflictos manualmente
|
||||
2. `git add` los archivos resueltos
|
||||
3. `git commit` (sin -m, para mantener el mensaje de merge)
|
||||
|
||||
#### 6. Push a remoto
|
||||
|
||||
```bash
|
||||
git push
|
||||
```
|
||||
|
||||
**Si falla el push:**
|
||||
- Error "rejected - non-fast-forward" → alguien pusheó a master antes
|
||||
- Solución: `git pull --rebase && git push`
|
||||
|
||||
#### 7. Limpiar rama local
|
||||
|
||||
```bash
|
||||
git branch -d <rama>
|
||||
```
|
||||
|
||||
**Si el branch delete falla:**
|
||||
- `-d` falla si la rama no está mergeada
|
||||
- Usar `-D` solo si estás seguro que el merge se completó correctamente
|
||||
|
||||
### Verificación final
|
||||
|
||||
```bash
|
||||
git log --oneline -3
|
||||
git branch --list
|
||||
```
|
||||
|
||||
Informar al usuario:
|
||||
|
||||
```
|
||||
✓ Rama `<rama>` integrada a master y publicada
|
||||
|
||||
Commits creados:
|
||||
- <commit 1>
|
||||
- <commit 2>
|
||||
- merge: <rama>
|
||||
|
||||
Rama local eliminada.
|
||||
Master actualizado y sincronizado con remoto.
|
||||
```
|
||||
|
||||
## Convenciones
|
||||
|
||||
- **Commits atómicos**: un commit = un cambio lógico completo
|
||||
- **Mensajes descriptivos**: título corto + cuerpo explicativo en español
|
||||
- **No mezclar tipos**: feat, fix, test, docs cada uno en su commit
|
||||
- **Tests obligatorios**: siempre ejecutar antes de merge
|
||||
- **Merge --no-ff**: preservar historia de la rama
|
||||
- **Push inmediato**: integrar y publicar en un solo flujo
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Error: "nothing to commit, working tree clean"
|
||||
|
||||
**Causa:** No hay cambios pendientes para commitear.
|
||||
|
||||
**Solución:**
|
||||
Si estás en una rama temporal y todos los cambios ya están commiteados, continúa con el merge. Si estás en master sin cambios, no hay nada que hacer.
|
||||
|
||||
### Error: "Tests failing"
|
||||
|
||||
**Causa:** Los tests no pasan.
|
||||
|
||||
**Solución:**
|
||||
1. Ver detalles de los tests fallidos:
|
||||
```bash
|
||||
go test -v -tags goolm ./...
|
||||
```
|
||||
|
||||
2. Corregir el código que causa el fallo
|
||||
3. Re-ejecutar tests hasta que pasen
|
||||
4. Crear commit con el fix si es necesario
|
||||
5. Continuar con el merge
|
||||
|
||||
### Error: "merge conflict in <archivo>"
|
||||
|
||||
**Causa:** El archivo tiene cambios en master que conflictúan con tu rama.
|
||||
|
||||
**Solución:**
|
||||
1. Ver conflictos:
|
||||
```bash
|
||||
git status
|
||||
```
|
||||
|
||||
2. Abrir archivo y resolver marcadores de conflicto:
|
||||
```
|
||||
<<<<<<< HEAD
|
||||
código en master
|
||||
=======
|
||||
tu código
|
||||
>>>>>>> rama
|
||||
```
|
||||
|
||||
3. Editar y dejar solo la versión correcta
|
||||
|
||||
4. Stagear archivo resuelto:
|
||||
```bash
|
||||
git add <archivo>
|
||||
```
|
||||
|
||||
5. Completar merge:
|
||||
```bash
|
||||
git commit
|
||||
```
|
||||
|
||||
### Error: "branch -d <rama> failed"
|
||||
|
||||
**Causa:** Git detecta que la rama no está completamente mergeada.
|
||||
|
||||
**Solución:**
|
||||
1. Verificar si el merge se completó correctamente:
|
||||
```bash
|
||||
git log --oneline -5
|
||||
```
|
||||
|
||||
2. Si el merge commit está presente, forzar eliminación:
|
||||
```bash
|
||||
git branch -D <rama>
|
||||
```
|
||||
|
||||
3. Si el merge no se completó, volver atrás y resolver el problema.
|
||||
|
||||
### Error: "rejected - non-fast-forward"
|
||||
|
||||
**Causa:** Alguien más pusheó cambios a master mientras trabajabas.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git pull --rebase
|
||||
git push
|
||||
```
|
||||
|
||||
Si hay conflictos durante el rebase, resolverlos y continuar:
|
||||
```bash
|
||||
# Resolver conflictos
|
||||
git add <archivos-resueltos>
|
||||
git rebase --continue
|
||||
git push
|
||||
```
|
||||
|
||||
### Advertencia: "Detached HEAD state"
|
||||
|
||||
**Causa:** No estás en ninguna rama.
|
||||
|
||||
**Solución:**
|
||||
```bash
|
||||
git checkout master
|
||||
# O crear rama si tienes cambios importantes
|
||||
git checkout -b quick/rescue-changes
|
||||
```
|
||||
|
||||
## Reglas críticas
|
||||
|
||||
- **NO hacer commits WIP** - cada commit debe ser atómico y completo
|
||||
- **NO mezclar tipos** en un commit (feat + test en commits separados)
|
||||
- **NO saltear tests** - si fallan, arreglar antes de merge
|
||||
- **NO hacer push --force** a master nunca
|
||||
- **NO hacer squash** - preservar commits individuales vía --no-ff
|
||||
- **SIEMPRE** escribir descripción larga en español en cada commit
|
||||
- **SIEMPRE** ejecutar tests antes de merge a master
|
||||
- **SIEMPRE** usar --no-ff para el merge
|
||||
- **SIEMPRE** limpiar rama local después del merge
|
||||
@@ -0,0 +1,407 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user