TuBrief
Subscribed Channels
Videos
Community

Como implementar PRs empilhados (Stacked PRs) na prática para quando PRs gigantes atrasam as revisões em semanas

TuBrief Editorial
August 7, 2026
0
Computing/Software

Written with AI assistance from the source video. The video is the authority.

Português한국어EnglishEspañol中文हिन्दीDeutschFrançaisالعربيةРусскийBahasa Indonesia日本語

Related Video

O maior lançamento do GitHub em anos. Stacked PRs.5:17

O maior lançamento do GitHub em anos. Stacked PRs.

Better Stack

More from the community

사내 시스템에 llm api 붙일 때 마주하는 현실적인 한계와 대응법

September 13, 2026

레거시 백엔드에 GPT-6 Astra 붙일 때 예산 승인과 보안 통과를 먼저 끝내는 법이 있습니다

September 13, 2026

에이전트끼리 대화하다 6천만 원 청구서가 나오는 이유

September 13, 2026

사내 RAG 벡터 검색에 Okta 권한 필터를 직접 거는 방법

September 13, 2026

브라우저 에이전트에게 내 구글 계정을 통째로 넘기면 안 되는 이유

September 12, 2026

Apple Won the AI Race

September 12, 2026

Comments (0)

Log in to leave a comment

No posts yet

© 2026 . All rights reserved.

TuBrief
Subscribed Channels
Videos
Community
Log in

Como implementar PRs empilhados (Stacked PRs) na prática para quando PRs gigantes atrasam as revisões em semanas

Com a introdução de ferramentas de IA, a velocidade de geração de código aumentou drasticamente. No entanto, a velocidade de revisão não acompanhou esse ritmo. De acordo com o relatório DORA (DevOps Research and Assessment) de 2024, equipes com alta taxa de adoção de IA viram o tamanho dos PRs aumentar em média 154% e o tempo de revisão subir 91%. Como resultado, o ciclo de lançamento ficou ainda mais lento. Quando alguém recebe mais de 1.000 linhas de código para revisar de uma só vez, os olhos de qualquer pessoa ficam cansados. Para acabar com essa bagunça, precisamos migrar para uma estrutura de cadeia de PRs empilhados (Stacked PRs), onde o código é construído em camadas.

Dividindo um bloco de 1.000 linhas em 3 branches

Cortar o código aleatoriamente fará com que a compilação falhe ou as dependências quebrem. É necessário um critério claro. Limite um único PR a no máximo 200 linhas de código alteradas e menos de 10 arquivos modificados, permitindo que o revisor termine em 15 minutos. Divida uma funcionalidade grande em uma cadeia de até 3 branches filhas:

  • Layer 1: Schema de banco de dados, Entity, DTO
  • Layer 2: Lógica de domínio, implementação de serviço
  • Layer 3: Controller, endpoints de API

Siga esta ordem rigorosamente. Fixe também os nomes dos branches no formato feature/<nome-da-funcionalidade>/stack-<etapa>-<descricao>. O processo de decompor um branch de 1.000 linhas já emaranhado (legacy-giant-branch) em uma cadeia é simples.

Primeiro, atualize o branch main e faça backup do original.

`bash
git checkout main
git pull origin main
git checkout legacy-giant-branch
git branch backup/legacy-giant-branch

`

Em seguida, crie o branch Layer 1 a partir de main e aplique via cherry-pick apenas os commits relacionados ao schema.

`bash
git checkout -b feature/order-refactor/stack-1-schema main
git cherry-pick
git push origin feature/order-refactor/stack-1-schema

`

Agora, usando o Layer 1 como pai, você pode estender o Layer 2 e o Layer 3 sequencialmente.

`bash
git checkout -b feature/order-refactor/stack-2-service feature/order-refactor/stack-1-schema
git cherry-pick
git push origin feature/order-refactor/stack-2-service

git checkout -b feature/order-refactor/stack-3-controller feature/order-refactor/stack-2-service
git cherry-pick
git push origin feature/order-refactor/stack-3-controller

`

A escolha da ferramenta também é um fator a se considerar. O CLI puro do Git não custa dinheiro, mas exige muito trabalho manual, enquanto ferramentas dedicadas como o Graphite são convenientes, mas geram custos e dependência de infraestrutura.

Critério de Avaliação Pure Git CLI GitHub CLI (gh stack) Graphite / External Tools
Rastreamento de Dependências Configuração manual da Base do branch .git local e metadados do GitHub Engine remota separada e Banco de Dados local
Automação de Rebase Trabalho manual em cada branch Execução do comando gh stack rebase Tratamento automático da cadeia inferior ao alterar commits
Curva de Aprendizado Alta (Necessário entender os princípios do Git) Baixa (Instalação de extensão CLI) Média (Necessário se adaptar a uma UI dedicada)
Estabilidade Operacional 100% compatível com o Git padrão Em estado de Preview público Muito alta

Evitando conflitos de rebase quando o PR pai é modificado

Ao usar PRs empilhados, o momento mais doloroso é quando surge um pedido de alteração no PR pai. Como o Hash do commit muda, todos os branches filhos anexados abaixo quebram. Se você simplesmente executar um git rebase, os commits serão duplicados. É preciso especificar o intervalo a ser recortado usando a sintaxe git rebase --onto.

Se o Layer 1 foi modificado, vá para o Layer 2 e desloque a partir do ponto de commit do Layer 1 antes da modificação até o HEAD atual, colocando-o em cima do ponto final do novo Layer 1.

`bash
git checkout feature/order-refactor/stack-2-service
git rebase --onto feature/order-refactor/stack-1-schema feature/order-refactor/stack-2-service
git push --force-with-lease

`

Mova o Layer 3 para cima do novo Layer 2 da mesma forma.

`bash
git checkout feature/order-refactor/stack-3-controller
git rebase --onto feature/order-refactor/stack-2-service feature/order-refactor/stack-3-controller
git push --force-with-lease

`

Se você fizer esse trabalho manualmente todas as vezes, os humanos com certeza cometerão erros. Crie um script shell para automatizar o rebase sequencial.

`bash
#!/usr/bin/env bash
set -e

STACK_BRANCHES=(
"feature/order-refactor/stack-1-schema"
"feature/order-refactor/stack-2-service"
"feature/order-refactor/stack-3-controller"
)
TARGET_BASE="main"

git fetch origin
CURRENT_PARENT="$TARGET_BASE"

for BRANCH in "STACKBRANCHES[@]";dogitcheckout"{STACK_BRANCHES[@]}"; do git checkout "STACKB​RANCHES[@]";dogitcheckout"BRANCH"
OLD_BASE=(gitmerge−base"(git merge-base "(gitmerge−base"CURRENT_PARENT" "BRANCH"2>/dev/null∣∣echo"")if[−n"BRANCH" 2>/dev/null || echo "") if [ -n "BRANCH"2>/dev/null∣∣echo"")if[−n"OLD_BASE" ]; then
git rebase --onto "CURRENTPARENT""CURRENT_PARENT" "CURRENTP​ARENT""OLD_BASE" "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH" || exit 1 fi git push --force-with-lease origin "BRANCH"∣∣exit1figitpush−−force−with−leaseorigin"BRANCH"
CURRENT_PARENT="$BRANCH"
done

`

Não se esqueça de ativar a função de histórico de resolução de conflitos nas configurações do Git. Ela lidará automaticamente com conflitos repetitivos.

`bash
git config --global rerere.enabled true
git config --global rerere.autoupdate true
git config --global rebase.autoStash true
git config --global rebase.updateRefs true

`

Bloqueando o desperdício de custo de CI runners e a inversão na ordem de merge

Dividir um PR em 3 gera o problema de rodar os CI runners 3 vezes mais. Não há necessidade de rodar testes de E2E pesados em todos os PRs. Configure o ambiente do GitHub Actions para rodar apenas testes unitários robustos nas camadas inferiores e realizar a validação de integração completa apenas no PR mais alto.

Adicione uma condicional de posição da stack em .github/workflows/ci.yml.

`yaml
name: Stack-Aware CI Pipeline

on:
pull_request:
branches: [ main ]

jobs:
fast-lint-and-unit-test:
name: Fast Validation (All Layers)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Linter & Unit Tests
run: |
npm ci
npm run test:unit

heavy-integration-test:
name: Full E2E Test (Top Layer Only)
runs-on: ubuntu-latest
if: |
github.event.pull_request.stack == null ||
github.event.pull_request.stack.position == github.event.pull_request.stack.size
steps:
- uses: actions/checkout@v4
- name: Run Heavy Integration & E2E Tests
run: |
npm ci
npm run test:e2e

`

Definir regras de proteção de branch em nível organizacional também é essencial.

  1. Ative a funcionalidade GitHub Merge Queue para forçar que os PRs empilhados aprovados sejam mesclados em ordem.
  2. Ative 'Require Linear History' em Repository Rulesets para evitar commits de merge residuais.
  3. Use 'Require Status Checks to Pass Before Merging' para evitar o incidente de misturar um PR superior no main antes que o PR inferior seja mesclado.

Cultura de revisão de equipe e como lidar com quebras de UI após o Squash Merge

Para executar PRs empilhados corretamente, os revisores precisam conseguir ver o panorama geral. Especifique o mapa da stack em .github/PULL_REQUEST_TEMPLATE.md.

`markdown
Stack Overview
Este PR faz parte da cadeia da Stack de Refatoração de Pedidos.

  1. #101 - feature/order-refactor/stack-1-schema (DB Migration)
  2. [Current PR] #102 - feature/order-refactor/stack-2-service (Business Logic)
  3. #103 - feature/order-refactor/stack-3-controller (API Controller)

Current Layer Scope

  • Implementação da lógica de alteração de status de pagamento dentro de OrderService
  • Processamento de emissão de Domain Event e adição de testes de integração com Repository

Dependency Status

  • Base PR: #101 (Must be merged first)

`

Depois que o PR inferior #101 entra no main via Squash Merge, o Diff da UI do GitHub do PR filho #102 explode de repente. Esse é o fenômeno em que até o código de #101 que já foi mesclado é capturado como alteração do PR filho. Isso ocorre porque os SHAs do commit de Squash e do commit pai mudaram no Grafo de Commits do Git. Não entre em pânico e basta subir apenas os commits do branch filho para cima do main usando a ordem abaixo.

`bash
git log --graph --oneline
git checkout feature/order-refactor/stack-2-service
git fetch origin
git rebase --onto origin/main feature/order-refactor/stack-2-service
git push --force-with-lease origin feature/order-refactor/stack-2-service

`

A tarefa de dividir um PR gigante de 1.000 linhas não é apenas uma questão de lidar com técnicas do Git. É mais um trabalho de engenharia para organizar perfeitamente a forma de revisão de código da equipe e toda a cadeia de implantação. Se você encontrar um branch legado bagunçado, faça um backup primeiro e tente cortá-lo em camadas de 3 etapas. Além de reduzir o cansaço do revisor, você mesmo conseguirá controlar o código com muito mais clareza.