Branching & Merging
Branches de funcionalidades, merge e estratégias de rebase para serviços Python que enviam pyproject.toml, lockfiles e migrações Alembic juntos.
Receita
git checkout main && git pull --rebase origin main
git checkout -b feat/api-91-refunds
# trabalhe...
git fetch origin && git rebase origin/main
git push -u origin feat/api-91-refunds
# abra PR -> squash merge para main após CI verdeQuando usar isso:
- Iniciando trabalho de ticket isolado de
main - Integrando o
mainmais recente antes da revisão do PR - Criando trains
release/x.ycom aplicativos Django/FastAPI - Backporting de hotfixes com cherry-pick
Exemplo de Trabalho
# Ciclo de vida do branch de funcionalidade
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
# conflito em uv.lock -> regenere o lock após resolver pyproject
uv lock
git add pyproject.toml uv.lock
git rebase --continue
git push --force-with-lease origin feat/worker-retriesO que isso demonstra:
- Branch a partir de
mainatualizado - Rebase integra upstream sem commits de merge no branch de funcionalidade
- Conflitos de lockfile resolvidos por regeneração, não edição manual
- Force-with-lease push forçado seguro após rebase
Mergulho Profundo
Como Funciona
- Fast-forward - O ponteiro do branch avança quando não há commits divergentes.
- Commit de merge - Combina dois históricos com um nó de merge.
- Rebase - Reexecuta commits em uma nova base - reescreve SHAs.
- Squash merge - O PR se torna um único commit em
main.
Tipos de Branch
| Branch | Propósito |
|---|---|
main | Integração sempre enviável |
feat/* | Trabalho de ticket; rebasado frequentemente |
release/x.y | Estabilização; apenas correções |
hotfix/* | Patch de produção a partir de tag |
Notas Python
# Cherry-pick de correção de migração para o branch de release
git switch release/2.3
git cherry-pick abc1234 # commit com revisão Alembic
uv run alembic upgrade head
uv run pytest -qArmadilhas
- Branches de funcionalidades de longa duração - Conflitos de lockfile e migração explodem. Correção: faça merge ou rebase de
maindiariamente. - Squash perdendo informações de revert - Difícil de usar
git bisect. Correção: título de PR significativo se torna a mensagem de squash. - Rebase após o início da revisão do PR - Confunde revisores com force push. Correção: comunique ou faça merge em vez disso.
- Fazer merge de
mainemrelease/*- Puxa funcionalidades não verificadas. Correção: apenas cherry-pick. - Conflitos de revisão Alembic - Cabeças duplicadas após branches paralelos. Correção: faça merge das cabeças de migração antes da implantação.
- Conflitos de wheel binária - Raro no git; artefatos grandes não devem estar no repositório. Correção: Git LFS ou índice de pacotes.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Trunk-based + flags | CI maduro e feature flags | Longos trains de release com migrações de schema |
GitFlow develop | Mandato de organização legado | Equipe prefere trunk + release/* |
| Commit de merge no PR | Preservar metadados de limite do PR | O ruído no histórico é uma preocupação |
| Rebase merge | Histórico linear com agrupamento de PR | Política proíbe qualquer reescrita |
FAQs
Squash ou commit de merge para PRs?
Squash para PRs de funcionalidades em main; commit de merge quando for necessário preservar a narrativa de funcionalidades com múltiplos commits.
Conflitos de rebase em uv.lock?
Aceite o pyproject.toml de um dos lados, execute uv lock, adicione o lock regenerado - nunca faça merge manual do lock JSON.
Quanto tempo devem viver os branches de feat?
Meta de 1-3 dias; se for mais longo, divida o ticket ou integre atrás de uma feature flag.
Excluir branch após merge?
Sim - habilite a exclusão automática no GitHub; localmente git branch -d após o merge.
Múltiplos PRs para uma migração?
Coordene a cadeia de revisão Alembic - o segundo PR se baseia no primeiro até que o primeiro seja mesclado.
Regras de proteção do main?
Exija PR, ruff, pytest, revisões - sem push direto, exceto para papéis de "break-glass".
Branching de Monorepo?
Mesmas regras por pasta de serviço; filtros de caminho na CI executam apenas projetos uv afetados.
Backport de hotfix?
Cherry-pick para main e release/* ativos; marque o patch após validação em staging.
Rebase vs merge para PRs do dependabot?
Faça merge dos PRs do dependabot como estão ou rebase usando o botão do GitHub - mantenha o lockfile consistente com uv sync --frozen na CI.
Marcadores de conflito no Jupyter?
Veja Git para Dados/Notebooks - nbstripout reduz o ruído.
Relacionados
- Comandos Essenciais do Git - comandos diários
- Checklist de Resolução de Conflitos de Merge - processo calmo
- Git Worktrees - checkouts paralelos
- Pipelines de CI/CD - proteções de branch
Versões de Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 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+, e uv 0.6+.