Ramificación y Fusión
Estrategias de ramas de características, fusión y rebase para servicios de Python que envían pyproject.toml, lockfiles y migraciones de Alembic juntos.
Receta
git checkout main && git pull --rebase origin main
git checkout -b feat/api-91-refunds
# trabajar ...
git fetch origin && git rebase origin/main
git push -u origin feat/api-91-refunds
# abrir PR -> fusionar con squash a main después de que CI esté en verdeCuándo usar esto:
- Comenzar trabajo de tickets aislado de
main - Integrar el último
mainantes de la revisión de PR - Crear líneas de lanzamiento
release/x.ycon aplicaciones Django/FastAPI - Backportear hotfixes con cherry-pick
Ejemplo de Trabajo
# Ciclo de vida de la rama de características
git switch -c feat/worker-retries main
uv run pytest -q
git commit -am "feat(worker): retry smtp errors [WRK-12]"
git fetch origin
git rebase origin/main
# conflicto en uv.lock -> regenerar lock después de resolver pyproject
uv lock
git add pyproject.toml uv.lock
git rebase --continue
git push --force-with-lease origin feat/worker-retriesLo que esto demuestra:
- Ramificación desde
mainactualizado - Rebase integra upstream sin commits de fusión en la rama de características
- Conflictos de lockfile resueltos por regeneración, no edición manual
- Force push seguro con
--force-with-leasedespués de rebase
Profundización
Cómo Funciona
- Fast-forward - El puntero de la rama se mueve cuando no hay commits divergentes.
- Commit de fusión - Combina dos historiales con un nodo de fusión.
- Rebase - Reproduce commits sobre una base nueva - reescribe SHAs.
- Fusión con squash - El PR se convierte en un solo commit en
main.
Tipos de Ramas
| Rama | Propósito |
|---|---|
main | Integración siempre lista para enviar |
feat/* | Trabajo de ticket; rebasado a menudo |
release/x.y | Estabilización; solo correcciones |
hotfix/* | Parche de producción desde etiqueta |
Notas de Python
# Hacer cherry-pick de corrección de migración a la rama de lanzamiento
git switch release/2.3
git cherry-pick abc1234 # commit con revisión de Alembic
uv run alembic upgrade head
uv run pytest -qErrores Comunes
- Ramas de características de larga duración - Los conflictos de lockfile y migraciones explotan. Solución: fusionar o rebasar
maindiariamente. - Squash pierde información de revertir - Difícil de bisectar. Solución: un título de PR significativo se convierte en el mensaje de squash.
- Rebase después de que comienza la revisión del PR - Confunde a los revisores con force push. Solución: comunicar o fusionar en su lugar.
- Fusionar
mainenrelease/*- Introduce características no verificadas. Solución: solo cherry-pick. - Conflictos de revisiones de Alembic - Cabezas duplicadas después de ramas paralelas. Solución: fusionar la migración de cabezas antes del despliegue.
- Conflictos de ruedas binarias - Raros en git; los artefactos grandes no deben estar en el repositorio. Solución: Git LFS o índice de paquetes.
Alternativas
| Alternativa | Usar Cuándo | No Usar Cuándo |
|---|---|---|
| Trunk-based + flags | CI madura y flags de características | Líneas de lanzamiento largas con migraciones de esquema |
GitFlow develop | Mandato de organización heredado | El equipo prefiere trunk + release/* |
| Commit de fusión en PR | Preservar metadatos de límite de PR | El ruido del historial es una preocupación |
| Fusión de rebase | Historial lineal con agrupación de PR | La política prohíbe cualquier reescritura |
Preguntas Frecuentes
¿Squash o commit de fusión para PRs?
Squash para PRs de características en main; commit de fusión cuando se requiere preservar la narrativa de características de múltiples commits.
¿Conflictos de rebase en uv.lock?
Aceptar el pyproject.toml de un lado, ejecutar uv lock, preparar el lock regenerado - nunca fusionar manualmente el JSON del lock.
¿Cuánto tiempo deben vivir las ramas de características?
Apunta a 1-3 días; si es más largo, dividir el ticket o integrar detrás de un flag de característica.
¿Eliminar rama después de fusionar?
Sí - habilitar auto-eliminación en GitHub; git branch -d local después de fusionar.
¿Múltiples PRs para una migración?
Coordinar la cadena de revisiones de Alembic - el segundo PR se basa en el primero hasta que el primero se fusione.
¿Reglas para proteger main?
Requerir PR, ruff, pytest, revisiones - sin push directo excepto rol de emergencia.
¿Ramificación en monorepo?
Las mismas reglas por carpeta de servicio; los filtros de ruta en CI ejecutan solo los proyectos uv afectados.
¿Backportear hotfix?
Hacer cherry-pick a main y release/* activos; etiquetar el parche después de la validación en staging.
¿Rebase vs merge para PRs de dependabot?
Fusionar PRs de dependabot tal cual o rebasar usando el botón de GitHub - mantener el lockfile consistente con uv sync --frozen CI.
¿Marcadores de conflicto en Jupyter?
Ver Git para Datos/Notebooks - nbstripout reduce el ruido.
Relacionado
- Comandos Esenciales de Git - comandos diarios
- Lista de Verificación para Resolución de Conflictos de Fusión - proceso calmado
- Worktrees de Git - checkouts paralelos
- Pipelines de CI/CD - protecciones de rama
Versiones de la Pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.