重复提交可能是因为来自多个来源的变基
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
假设我在a2
feature/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
,我应该从master
和branch 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/merge
从origin/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
,它会产生重复的提交。
【讨论】:
以上是关于重复提交可能是因为来自多个来源的变基的主要内容,如果未能解决你的问题,请参考以下文章