我最近刚刚写了一篇关于这个主题的博客:
我们如何使这个功能分支保持最新?合并最新的上游提交很容易,但是您希望避免创建合并提交,因为当推送到上游时不会受到赞赏:然后您将有效地重新提交上游更改,并且这些上游提交将获得一个新的哈希 (因为他们有了一个新的父母)。这一点尤其重要,因为当您将这些更新推送到您的个人 GitHub 功能分支时,这些合并的提交将反映在您的 GitHub 拉取请求中(即使您在发出拉取请求之后这样做。)
这就是为什么我们需要变基而不是合并:
git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel
git 的 rebase 选项和 rebase 命令都将保持你的树干净,并避免合并提交。但请记住,那些是你的第一个提交(你发出你的第一个拉取请求)正在被重新设置,并且现在有一个新的提交哈希,这与仍然在你的远程 github repo 分支中的原始哈希不同.
现在,将这些更新推送到您的个人 GitHub 功能分支将在这里失败,因为两个分支不同:本地分支树和远程分支树“不同步”,因为这些不同的提交哈希。Git 会告诉你先git pull --rebase
,然后再推,但这不会是一个简单的快进推,因为你的历史被改写了。不要那样做!
这里的问题是您将再次获取最初更改的提交,并且这些提交将合并到您的本地分支之上。由于处于不同步状态,此拉取并不完全适用。你会得到一个破碎的历史,你的提交出现了两次。当您将所有这些推送到您的 GitHub 功能分支时,这些更改将反映在原始拉取请求中,这将变得非常非常难看。
AFAIK,实际上没有完全干净的解决方案。我发现的最佳解决方案是强制将您的本地分支推送到您的 GitHub 分支(实际上是强制进行非快进更新):
根据 git-push(1):
Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.
所以不要拉,像这样强制推动:
git push svg +user-non-unique
或者:
git push svg user-non-unique --force
这实际上会用本地分支中的所有内容明显覆盖您的远程分支。远程流中的提交(并导致失败)将保留在那里,但将是悬空提交,最终将被 git-gc(1) 删除。没什么大不了的。
正如我所说,这是 AFAICS 最干净的解决方案。这样做的缺点是,您的 PR 将使用那些最新提交进行更新,这些提交将在以后获得,并且可能在 PR 的评论历史记录中显得不同步。没什么大问题,但它可能会令人困惑。