重复提交可能是因为来自多个来源的变基

Posted

技术标签:

【中文标题】重复提交可能是因为来自多个来源的变基【英文标题】:duplicated commits might because rebase from multiple sources 【发布时间】:2019-03-30 18:39:51 【问题描述】:

为了开发一个特性,我创建了一个特性分支(称为feature/a)。

feature/a的开发过程中,我发现存在一个bug,所以我从master创建了一个bug分支(称为fix/b)。

修复此错误并提交后,我再次检查了feature/a,然后运行git rebase origin/master。但是因为它依赖于fix/b,所以我跑了git rebase origin/fix/b。在这两次变基期间,我修复了一些冲突。

然后我继续工作feature/a,在我完成feature/a 之后,就在我请求拉取请求之前,我意识到有很多重复的提交。为什么有很多重复的提交?我认为这可能是因为我从混合来源重新调整了基础,但我试图在本地复制但没有发生。

另一个问题,在这种情况下,什么是正确的策略?有人有什么想法吗?


更新 #1

对不起,我忘了提,当时fix/b 还没有合并回master。所以情况更像是下面这样:

master --> m1 --> m2
 |\
 | \
 |  feature/a --> a1 --> a2
 |
fix/b --> b1 --> b2

假设我在a2feature/a,理想情况下我预计会发生以下情况: * git rebase master,图表应变为: --> m1 --> m2 --> a1 --> a2 * git rebase fix/b,图表应变为: --> m1 --> m2 --> b1 --> b2 --> a1 --> a2

但是,在我的情况下,图表更像下图: --> m1 --> m2 --> b1 --> b2 --> m1 --> m2 --> b1 --> b2 --> a1 --> a2

我无法在我的本地 git 存储库中重现。

我的问题实际上是:如果有两个分支(A 和 B),它们都没有合并到 master,并且一个依赖于另一个(branch A 依赖于 branch B)。在这种情况下,要继续开发branch A,我应该从masterbranch B 变基吗?

【问题讨论】:

你应该运行git rebase origin/fix/b。假设您实际上确实将错误修复直接提交给master,那么git rebase origin/master 应该将该错误修复提交给feature/a。我认为这是您问题的根源。 对不起,我忘了说,在我修复fix/b之后,我请求拉取请求,但是需要时间合并回master,这意味着此时fix/b没有合并回master 还没有。 这并没有真正改变我的评论。我认为你不应该重新定位两次。 【参考方案1】:

无论何时进行变基,都会在目标分支 (feature/a)、变基分支 (origin/master) 和 (origin/fix/b) 中创建新的提交。由于origin/master 已经有origin/fix/b 提交,当您从origin/master 变基时,您会在目标分支feature/a 中看到重复提交。

您应该做的是,您应该将origin/master 视为所有合并/变基的共享分支。因此,在将 fix/b 合并到 origin/master 之后,您应该将 origin/master 重新定位到目标分支 feature/a

如果你想保留历史,你应该去合并。如果您想要更清晰的历史记录,请使用 rebase。无论哪种情况,您都应该将origin/master 保留为共享分支,并将rebase/mergeorigin/master 保留到您的分支中。这里是feature/a

git checkout feature/a
git merge origin/master #if you are fond of merge, to keep history accurately
git rebase origin/master #if you are fond of rebase, to keep history cleaner

【讨论】:

感谢您的意见。实际上我才意识到我没有提到fix/b 还没有合并回master。我更新了我的问题,你能看看吗,谢谢。【参考方案2】:

让我们看看你的变基序列,因为考虑到patch id mechanism,类似的提交不应该被变基两次。 意思是,您不应该看到 m1/m2 重复两次。然而,你看到了它们。

假设我在feature/a 上的a2,理想情况下我预计会发生以下情况:git rebase master,图表应该变成

     (master)
 m1 --> m2 --> a1' --> a2' (feature/a)
   \
     -> b1 --> b2 (fix/b)

git rebase fix/b,图应该变成:

m1 --> m2 --> b1 --> b2 --> a1 --> a2

嗯...不:您在 fix/b 之上重播功能/a(现在包括 master 提交),但 master 仍然存在。

 m1 --> m2 (master)
   \
     -> b1 --> b2 --> m1' --> m2' --> a1'' --> a2'' (feature/a)

因此重复m1/m2

一般来说,来自master 的提交不应该被rebase。

简单地将fix/b 合并到feature/a 是最好的,以便在受益于fix/b 的同时快速继续开发功能/a。

     (master)
 m1 --> m2 --> a1' --> a2' --> M (feature/a)
   \                          /
     -> b1 ----------------> b2 (fix/b)

【讨论】:

【参考方案3】:

我觉得这个question&answer解释得很好。

基本上,最后一步push,我们应该git push --force-with-lease。如果我们做git push,它会产生重复的提交。

【讨论】:

以上是关于重复提交可能是因为来自多个来源的变基的主要内容,如果未能解决你的问题,请参考以下文章

在推入 Git 之前合并多个提交 [重复]

在没有变基的情况下恢复合并

合并/其他提交交错后的交互式变基

SourceTree中的变基使用说明

Git更改未推送提交的作者[重复]

git 修改已提交的 commit