# Git & PR Conventions — Fundamental Skill

Skill para mantener un historial de Git limpio, navegable y automatizable. Usar al crear branches, escribir commits, y abrir PRs.

---

## Nombres de Ramas

### Prefixes estándar
- `feat/` — Nueva funcionalidad. Ej: feat/user-auth
- `fix/` — Corrección de bug. Ej: fix/login-timeout
- `chore/` — Mantenimiento, dependencias. Ej: chore/update-eslint
- `hotfix/` — Fix urgente en producción. Ej: hotfix/payment-crash
- `docs/` — Documentación. Ej: docs/api-auth-endpoints
- `refactor/` — Refactor sin cambio funcional. Ej: refactor/extract-payment-gateway
- `test/` — Agregar o corregir tests. Ej: test/checkout-e2e

### Reglas
- Siempre en minúsculas. ❌ feat/User-Auth → ✅ feat/user-auth
- kebab-case, no snake_case. ❌ fix/payment_timeout → ✅ fix/payment-timeout
- Inglés. ❌ feat/autenticacion-usuarios → ✅ feat/user-authentication
- Máximo 3 palabras descriptivas. ❌ fix/the-login-form-authentication-token-expiry → ✅ fix/auth-token-expiry
- Incluí número de issue si existe. ❌ fix/bug → ✅ fix/payment-duplicate-#142

---

## Conventional Commits

Formato: `type(scope): descripción`

### Tipos
- feat — Nueva feature
- fix — Bug fix
- chore — Mantenimiento, dependencias
- docs — Solo documentación
- refactor — Refactor sin cambio de comportamiento
- test — Agregar o corregir tests
- perf — Mejora de performance
- ci — CI/CD changes
- style — Formato, punto y coma, espacios

### Reglas de oro
- Imperativo presente: "add", no "added" ni "adding"
- Máximo 72 caracteres en la primera línea
- Un commit = un cambio lógico. Si usás "and", son dos commits
- El body explica el PORQUÉ, no lo que ya dice el diff

### Ejemplos
- ✅ feat(auth): add JWT token refresh logic
- ✅ fix(checkout): prevent double charge on network retry
- ✅ perf(api): add Redis cache for product list endpoint (Before: 850ms, After: 45ms)
- ❌ fix bug (no da contexto)
- ❌ WIP (no es un commit, es un grito de auxilio)
- ❌ updated some stuff and fixed things (vago)

---

## PR Description

### Template
```markdown
### ¿Qué cambia?
Resumen en una frase.

### ¿Por qué?
Contexto de negocio o técnico. Link al issue.

### ¿Cómo lo hice?
Decisiones técnicas clave. Alternativas consideradas.

### ¿Cómo probarlo?
Pasos concretos para QA. Comandos, fixtures, URLs de staging.

### Screenshots / Evidencia
Si es UI: antes/después. Si es API: response de curl.

### Riesgos
Qué podría romperse. Migraciones, cambios de schema.
```

### Checklist de PR
- [ ] ¿El título sigue Conventional Commits?
- [ ] ¿El PR tiene una sola responsabilidad?
- [ ] ¿La descripción incluye el PORQUÉ?
- [ ] ¿Hay instrucciones claras para probar?
- [ ] ¿Los commits están limpios (sin WIP, fix typo)?
- [ ] ¿Revertiste cambios de debug?
- [ ] ¿Corren los tests localmente?

---

## Estrategia de Merge

### Squash and merge (RECOMENDADO)
Todos los commits se comprimen en uno. Historial de main lineal y limpio.
- ✅ PRs con muchos WIP. Ramas con ida y vuelta.
- ✅ Fácil revertir. Un commit = un PR.
- ❌ Pierde historial granular.

### Merge commit
Crea un commit de merge. Preserva todo el historial.
- ✅ Ramas longevas con múltiples features significativas.
- ✅ Claro qué commits entraron juntos.
- ❌ Más ruido visual en git log.

### Rebase and merge
Reescribe commits sobre la punta de main. Historial lineal.
- ✅ Commits individuales preservados. Sin burbujas de merge.
- ❌ Reescribe historia. Más trabajo si hay conflictos.

### Árbol de decisión
1. ¿Tu rama tiene más de 2 días? → merge | rebase
2. ¿Alguien más trabaja en esta rama? → merge | rebase
3. ¿Querés historial lineal? → rebase | merge
4. ¿Los commits cuentan una historia útil? → rebase | squash

### Anti-patrones
- ❌ git push --force a main: sobreescribe historial compartido
- ❌ Mergear sin revisar conflictos: merge commit se crea pero código roto
- ❌ git add . && git commit -m "changes": todo sin discriminar
- ❌ Commits directos a main: saltás review, CI, y la red de seguridad
