pr是分支生命周期的中间状态,未合并则分支存活,已合并未删除会污染分支列表和ci流水线;pr创建后可继续push但风险高,推荐锁定分支、仅允许rebase修复,新需求须另开分支;合并后应立即删除远端分支以防堆积和误触发ci;每个pr须聚焦单一变更,通过清晰分支名、原子化提交和规范模板保障可追溯性。

PR 不是提交代码的终点,而是分支生命周期的中间状态——没合并的 PR 意味着分支还活着,已合并但未删除的分支会持续污染 git branch 列表和 CI 流水线。
PR 提交后,原分支还能不能继续 push?
能,但风险极高。GitHub 默认允许向已关联 PR 的分支推送新 commit,这些 commit 会自动追加进 PR 的 diff 中。看似方便,实则埋下三类问题:
- 评审者看到的不是最初提交的逻辑,而是“不断生长”的混合体,难以定位变更意图
- CI 重新运行可能失败,而失败原因混在一堆无关 commit 里,排查成本陡增
- 若多人共用同一分支(如
feature/login-flow),push 冲突或覆盖他人修改几乎不可避免
推荐做法:PR 创建后锁定该分支,只允许通过 rebase -i 整合本地 fix(如修复 CI 报错),禁止新增功能逻辑;新需求必须开新分支 + 新 PR。
为什么 merge 后要立刻删掉远端分支?
GitHub 在 merge PR 时默认不删除远端分支,但保留它会导致:
-
git branch -r列表膨胀,origin/feature/x堆积成百上千个“已死”分支 - CI 工具(如 GitHub Actions)仍会监听这些分支的 push 事件,触发无意义构建
- 新人执行
git fetch && git checkout feature/x时,误以为该功能还在开发中
操作上,merge 完成后立即执行:
git push origin --delete feature/x。可在 GitHub PR 页面勾选 “Delete branch when merged”(需仓库管理员开启该设置),但别依赖——手动删更可控。
如何避免“一个 PR 对应多个不相关改动”?
本质是分支粒度失控。常见诱因:开发者把 main 拉到本地后,直接在同一个分支上顺手修 bug、加日志、调样式,最后推一个含 20+ commit 的 PR。
- 每个 PR 只解决一件事:要么实现
auth/token-refresh,要么修复api/user-list-404,绝不混搭 - 分支名即意图:
fix/empty-cart-crash、feat/payment-webhook-v2,拒绝dev、update这类模糊命名 - 本地 commit 信息要可读:
git commit -m "fix: prevent null ref in cart reducer",而非"fix bug"
如果发现 PR 里夹带了无关修改,不要硬着头皮合并——拆分支、重置 HEAD、新建 PR。花 10 分钟拆分,比花 2 小时解释“为什么这个样式修改会影响登录态”划算得多。
CI 失败时,该 rebase 还是 merge main?
选 rebase,除非你明确需要 main 的某次特定提交(比如刚合入的 shared config)。理由很实在:
-
git merge origin/main会在 PR 历史里插入一个 merge commit,污染线性历史,且让 diff 难以阅读 -
git rebase origin/main把你的 commit “挪”到最新main顶端,保持历史干净,CI 重跑也只验证你的改动 - 但注意:rebase 后必须
git push --force-with-lease origin feature/x,否则远程分支会拒绝更新
团队若强制要求线性历史(如用 git log --oneline 快速追溯),那就必须禁用 GitHub 的 “Merge pull request” 按钮,只允许 squash and merge 或 rebase and merge —— 否则前端工程师提交的 15 个 commit,会被后端合并成一个“Merge branch 'main' into feature/x”,彻底丢失演进痕迹。
分支不是文件夹,PR 不是按钮。它们共同构成代码流转的契约:分支定义“谁在改什么”,PR 定义“改得对不对”。契约一旦松动,协作就退化成各自为政。











