381 lines
9.3 KiB
Markdown
381 lines
9.3 KiB
Markdown
---
|
||
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
|