← 返回日报
精读 预计 1 分钟

Updating Stacked Pull Requests with git rebase --onto

摘要

文章描述了一个常见问题:多个互相依赖的 pull request 中,上游 commit 被 squash(例如 B 与 A 合并成新 commit E)后,下游 PR 的历史不会自动更新,导致子 commit 仍指向旧 parent B,从而使分支关系错乱。作者指出可以使用 git rebase --onto <newparent> <oldparent> 将后续 commit(如 C)重新挂到新的 parent(E)上,从而修复依赖关系。文章同时说明,普通 rebase 适用于仅追加 commit 的情况,而 --onto 更适合处理父 commit 被替换的场景,最后还提到可以结合 git push --force-with-lease 更安全地推送更新后的分支。

荐读理由

在上游 PR 被 squash 改写提交后,用 git rebase --onto <新父提交> <旧父提交> 重新调整下游分支的父提交,使后续 stacked PR 不再基于已被替换的 commit,并结合 force-with-lease 安全推送更新远端分支。

原文

Updating Stacked Pull Requests with git rebase --onto

2026-06-18

Sometimes I find myself in the situation where I have multiple pull requests that build off of each other.

TODO

Then, a reviewer asks me to squash commit B into commit A, creating a new commit E. I do so, but now my second pull request is all messed up!

TODO

When Git created commit E, it didn't tell commit B's children that their new parent should be commit E. This means that commit C still thinks its parent is commit B!

TODO TODO

While this behavior is a sensible default, in this scenario we don't want it. We can tell commit C that its new parent is commit E by rebasing it with the following command:

git switch second-pr

git rebase --onto E B
TODO

The general form of this command is git rebase --onto <newparent> <oldparent>, and it's very useful when updating stacked pull requests where the parent commit has been replaced. You don't need it if the base pull request only had new commits added, though, in which case you would use a normal git rebase without the --onto option. Once you do rebase your second pull request, take a look at the --force-with-lease option of git push to safely push your changes to the remote.

TODO TODO

Thank you to sEver on Stack Overflow for the answer that inspired this article!

Lobsters · 1 赞 · 0 评 讨论 → 阅读原文 →

这条对你有帮助吗?