我一直在一个单独的分支big-feature
上开发一项主要的长期功能。在开发过程中,我还对master
进行了较小的无关更新(嗯,从技术上讲,我一直在master
对其分支上进行较小的更新,然后将它们合并到master
中。 )
每次我对master
进行一些更改时,我都习惯将master
合并到big-feature
中,以使功能分支不会偏离{{ 1}},并且希望在大型功能完成后合并会更容易。
但是,在最近的一些工作之后,我不小心将master
合并到big-feature
中。我试图用master
来纠正这一点,实际上以前的代码状态似乎已经恢复了。但是,我仍然看到revert
的提交历史中列出了来自big-feature
的提交的完整历史,顶部还有一个master
和merge
。
问题是,当我现在对revert
进行小幅更改并尝试将master
合并到master
中时,big-feature
的所有代码都还原为big-feature
。我只能猜测master
中的revert
被合并到master
中并删除了big-feature
中的所有提交。
希望这是半连贯的。
问题:
big-feature
合并到master
的策略是一个坏主意吗? P.S。在错误合并之前,我还尝试了big-feature
到hard reset
的提交,但这并没有从master
中删除所有提交,这让我感到惊讶吗?
答案 0 :(得分:2)
我不小心将大型功能合并为主人。我试图通过还原来纠正这一点
这不是撤消合并的方法。
还原是整个 new 提交,它是人为创建的,其方式是将对它之前的某些提交的否定添加到未来的历史中。
撤消合并的方法是在进行合并时所在的分支上,然后简单地reset --hard
退回一个提交,即回到合并提交之前的提交。它没有名称,因此您必须使用HEAD~1
表示法或使用该提交的SHA。合并提交被丢弃,并且很容易,我们回到了合并之前的状态。
(您说过您尝试过,但是没有给出实际的命令,因此没有理由认为您正确地给出了命令。)
在此示例中,我在master
上创建了提交A,B和C,在feature
上创建了Z,并且我已经将feature
合并到master
中-您可以断定是因为(1)我在{em>上master
,(2)合并提交是master
的一部分,而不是feature
的一部分:>
* a65559d (HEAD -> master) merge commit
|\
| * c6c9d90 (feature) Z
* | caa732e C
* | 11bbc44 B
|/
* 92e934a A
记下SHA编号。假设我们对此举表示遗憾。因此,我们的目标是删除a65559d
,以便将master
返回到caa732e
,即合并feature
之前的位置。我们目前在{em> {em} master
上,所以我们所要做的只是说:
git reset --hard caa732e
结果:
* c6c9d90 (feature) Z
| * caa732e (HEAD -> master) C
| * 11bbc44 B
|/
* 92e934a A
正是我们想要的。
答案 1 :(得分:1)
注意::仅当您能够覆盖历史记录时,此答案才适用。仅当您没有将更改推送到远程,或者您知道FACT不会影响其他开发人员时(例如,没有人员,或者您可以与从事该项目的每个人进行交流,您才应该这样做)做)
我该如何解决?
我假设您将big-feature
合并为母版时发生的事情是fast-forward merge。
在那种情况下,使用git reset
重置为某些特定的提交可能不起作用,因为我们对master
和big-feature
的提交可能已经混合了。相反,我们可以使用git reflog
在进行合并之前找到状态master
所在的状态,然后将master
重置为该状态。
git reflog master # Show the history of updates to the tip of master.
# Find the line that says "master{n}: merge big-feature: Fast-forward"
# and note the reference number n
git switch master # checkout master if necessary
git reset --keep master@{n+1} # Now reset master to the reference just before merge
我定期将master合并为大功能的策略不是一个好主意吗?
如果再次可以覆盖历史记录,我建议您定期rebasing在feature
的{{1}}分支上使用。这样可以为您带来一个好处,就是您的master
分支上的历史记录很整洁,这使得与分支的交互变得更加容易,包括在这种情况下。
答案 2 :(得分:0)
我怀疑这里的问题是,当您现在将master
合并到big-feature
中时,Git沿着合并还原提交进行操作,此操作在功能上撤消了{ {1}}。尽管可能有一种更为优雅的方式来处理此问题,但一种简单的解决方案是仅从big-feature
中挑选您想要包含在master
中的提交:
big-feature
以上假设# from big-feature
git cherry-pick ABCD
是ABCD
中提交的SHA-1哈希,其中包含您要带入master
的次要修补程序。
使用这种方法需要更多的工作,因为您需要确切地确定需要提交哪些提交,但是它避免了不再适用于您的合并蛮力方法。