TuBrief
구독 채널
비디오
커뮤니티

当巨大PR导致代码审查延误一周时,我所采用的Stacked PR实战迁移法

TuBrief 편집팀
2026년 8월 7일
0
Computing/Software

원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.

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

관련 영상

GitHub 近年来最重磅的发布:Stacked PRs5:17

GitHub 近年来最重磅的发布:Stacked PRs

Better Stack

커뮤니티의 다른 글

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

2026년 9월 13일

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

2026년 9월 13일

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

2026년 9월 13일

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

2026년 9월 13일

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

2026년 9월 12일

Apple Won the AI Race

2026년 9월 12일

댓글 (0)

Log in to leave a comment

아직 작성된 글이 없습니다

© 2026 . All rights reserved.

TuBrief
구독 채널
비디오
커뮤니티
로그인

当巨大PR导致代码审查延误一周时,我所采用的Stacked PR实战迁移法

引入AI工具后,代码生成速度变得极快。然而,代码审查的速度却跟不上。根据2024年DORA(DevOps Research and Assessment)报告显示,AI采用率高的团队,PR平均体积增加了154%,而审查耗时却增加了91%之多。结果反而导致发布周期变慢了。如果把1000多行代码扔给别人要求一次性审查,无论谁都会感到眼睛疲劳。为了结束这种混乱局面,我们需要转换为将代码层层堆叠的Stacked PRs(堆叠PR)链式结构。

将1000行的代码块拆分为3个分支

盲目地裁剪代码会导致编译报错或依赖关系破坏。因此需要明确的标准。单个PR应限制在200行变更代码以内、修改文件少于10个,以便审查人员能在15分钟内完成。一个巨大的功能最多可分为3个子分支链:

  • Layer 1:数据库架构、Entity、DTO
  • Layer 2:业务逻辑、服务实现类
  • Layer 3:Controller、API端点

严格遵守这一顺序。分支名称也请固定为 feature/<功能名>/stack-<阶段>-<说明> 的形式。将已经缠绕在一起的1000行分支(legacy-giant-branch)拆解为链条的过程非常简单。

首先,更新 main 分支并备份原分支。

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

`

接下来,从 main 检出 Layer 1 分支,并仅通过樱桃拣选(cherry-pick)提交架构相关的提交。

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

`

现在以 Layer 1 为父级,顺次延伸出 Layer 2 和 Layer 3 即可。

`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

`

工具的选择也是一个考量因素。纯 Git CLI 不需要花钱但很费人工,而像 Graphite 这样的专用工具虽然方便,但会产生费用和基础设施依赖。

评估项目 Pure Git CLI GitHub CLI (gh stack) Graphite / External Tools
依赖追踪 手动设置分支 Base 本地 .git 及 GitHub metadata 独立远程引擎及 Local DB
变基自动化 各分支手动操作 执行 gh stack rebase 命令 更改提交时自动处理下级链条
学习曲线 高(需熟练掌握 Git 原理) 低(安装 CLI 扩展) 中(需适应独立专用 UI)
运营稳定性 100% 标准 Git 兼容 公共预览状态 非常高

当父PR被修改时,防止变基(Rebase)冲突

在使用 Stacked PR 时,收到父 PR 的修改请求往往是最痛苦的时刻。因为提交 Hash 发生变化会导致下方挂载的所有子分支全部失效。如果直接执行 git rebase,会导致提交内容重复。必须使用 git rebase --onto 语法来指定裁剪范围。

如果 Layer 1 进行了修改,请移动到 Layer 2,将修改前 Layer 1 的提交时间点到当前 HEAD 的内容重新放置在新的 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

`

Layer 3 也同样移至新的 Layer 2 之上。

`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

`

如果每次都手动执行这项工作,人类必然会犯错。请编写 Shell 脚本来自动化顺序变基。

`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

`

不要忘记在 Git 配置中开启冲突解决历史记录功能。它会自动跳过重复的冲突。

`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

`

阻止 CI 运行器成本浪费与合并顺序错乱

如果将 PR 拆分为 3 个,就会产生 CI 运行器运行次数增加 3 倍的问题。并非所有 PR 都需要运行沉重的 E2E 测试。请配置 GitHub Actions 环境,使底层仅运行扎实的单元测试,而整体集成验证仅在最顶层 PR 中执行。

在 .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

`

设置组织层面的分支保护规则也是必不可少的:

  1. 开启 GitHub Merge Queue 功能,强制按顺序合并已批准的堆栈 PR。
  2. 在 Repository Rulesets 中开启 ‘Require Linear History’ 以防止产生多余的合并提交(Merge Commit)。
  3. 通过 ‘Require Status Checks to Pass Before Merging’ 防止在底层 PR 尚未合并的状态下,上层 PR 先混入 main 的事故发生。

团队审查文化与 Squash Merge 后 UI 崩溃的应对方法

为了正常运行 Stacked PR,审查人员必须能够看到全局。请在 .github/PULL_REQUEST_TEMPLATE.md 中明确写出堆栈地图。

`markdown
Stack Overview
此 PR 是 Order Refactor Stack 链的一部分。

  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

  • 实现 OrderService 内支付状态变更逻辑
  • 添加 Domain Event 发布处理及 Repository 联动测试

Dependency Status

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

`

当底层 PR #101 通过 Squash Merge 进入 main 后,子 PR #102 的 GitHub UI Diff 会突然暴增。这是因为已合并的 #101 的代码全部被捕获为子 PR 的变更事项。由于在 Git Commit Graph 上,Squash 提交的 SHA 和父提交的 SHA 发生了变化,从而导致了该现象。请不要惊慌,按照以下顺序将子分支提交重新放置到 main 之上即可。

`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

`

将巨大的 1000 行 PR 进行拆分,不仅仅是处理 Git 技术的问题,更接近于一项彻底整理团队代码审查方式和整个发布链的工程任务。当你遇到杂乱的遗留分支时,请先建立备份,然后将其切分为 3 个阶段的图层试试看。不仅审查人员的疲劳会减轻,你自己也能更加清晰地掌控代码。