我在Git中遇到一个问题,我无法修复。我搜索了类似的案例,但我无法找到适合我情况的好方案。
我基本上有2个分支,master和bugfix。 Bugfix是在我们完成发布时从master获得的。每次我们修复bugfix中的内容并执行bugfix发布时,我们需要将其合并到master中。 Master包含新功能(当然不应该合并到bugfix中)。碰巧有人错误地将master与bugfix合并。
This is what happened:
master: x1---x2
\
bugfix: y1--y2--M
where M is the merge between bugfix and master
对此的解决方案是恢复合并,我使用“git revert -m 1 M”(M在这里是合并中的SHA),如here所述。我做了一个恢复,因为我们已经在bugfix分支中有其他变化,我们不想丢失,这对于bugfix分支工作正常。
Current state:
master: x1--x2------------x---x
bugfix: y1--x1--y2--x2--M--y--y--R1
where R1 is the revert of M
当我们需要在master中合并bugfix分支时,问题会出现。如我发布的链接中所述,恢复修复了代码更改但不修复历史记录,这意味着当我在master中合并bugfix时,revert将生效并从master(x1和x2)中删除更改。在将其合并到master中之前,我能做的是修复bugfix中的revert。
Solution:
master: x1--x2------------x---x--------M
/
bugfix: y1--x1--y2--x2--M--y--y--R1--R2
where R2 is the revert of R1
这可行,但不是最终的解决方案,因为每次我们进行合并时,我们都需要这样做“还原恢复”。我一直在寻找一个永久性的解决方案,现在看来,唯一的选择就是从bugfix分支的历史记录中删除主提交(x1和x2)。但是这里仅使用x1和x2作为示例,实际上我们有更多的提交并且解析bugfix分支的历史是非常困难且容易出错的。我确信Git可以帮助我做到这一点,但我不知道如何。
任何想法都会非常有用。
答案 0 :(得分:2)
我个人建议重写历史记录(请参阅Useless的答案)并告诉您的团队。但这要求每个人都有一定程度的git知识。如果重写方法对你来说风险太大,可以选择以下方法:
每当您将A
合并到B
时,git会将所有可从A
但不能B
到B
的提交/更改添加到git checkout -b bugfix-revert bugfix
git revert R1
git checkout master
git merge bugfix-revert
git branch -d bugfix-revert
。你的还原就是其中之一。正如你所注意到的那样,没有重写你就无法做任何事情。
您必须将revert合并为master。如你所愿,保留你在master中恢复的内容,你还需要撤消master上的revert(=从master可以访问)。实现这一目标的最佳方法是使用以下命令:
[master] x1---x2----------------------H
\ /
[bugfix-revert] \ M''
\ /
[bugfix] y1--y2----M--y3--y4--M'--y5
在这些命令之后,每个分支都处于你想要的状态,你可以从现在开始再次合并bugfix。您的历史记录如下:
master
正如您所看到的,M'
包含H
,但其更改不在M''
中,因为M'
取消了这些更改。 master
永远不会应用于bugfix
,因为它已包含它。状态{{1}}没有改变,也没有改变。
答案 1 :(得分:1)
为什么不首先创建一个没有错误合并的新bugfix分支?您需要与所有人协调切换分支,以确保没有提交丢失
所以你有:
[master] x1---x2
\
[bugfix] y1--y2--M--y3--y4--M'
(其中M'
是M
的回归。但是,您可以创建一个新分支:
$ git branch bugfix-fix y4
[master] x1---x2
\
[bugfix] y1--y2--M--y3--y4--M'
^^
[bugfix-fix]
将其从有问题的合并和回复中分离出来
$ git rebase --onto y2 M bugfix-fix
[master] x1---x2
\
[bugfix] y1--y2--M--y3--y4--M'
\
[bugfix-fix] y3'--y4'
然后,当您确认所需的所有内容都在bugfix-fix
之后,您就可以重命名这两个分支
$ git branch -m bugfix bugfix-broken
$ git branch -m bugfix-fix bugfix
(你需要强行推动这个,这是安全的,只要你与可能已经签出的所有人协调)。
答案 2 :(得分:-1)
你的解决方案是正确的......你需要'还原恢复',然后再与你的bugfix分支合并(以引入在第一次错误合并后完成的任何错误修复提交),就像你已经显示的那样。这将从y1和y2提交中恢复修复,保持历史记录正确并提取在第一个错误合并点之后执行的更新更改。
你不需要为将来的合并而担心这个,因为最后一个合并点是历史中git会尝试进行合并的地方,而不是它之前的任何东西(你需要做的同样的确切原因)还原')......
不知道为什么你说这会使bugfix处于破碎状态。以下工作正常。您可以根据需要继续处理错误修复分支,而不必担心不得不还原任何东西(除非您显然再次执行相同的操作......)。如果您将来需要再次与master合并,您可以毫无问题(无需做任何特殊处理),因为git知道历史记录,并且只会从两个分支最后一个共同点查找合并问题/冲突(这个最后合并)。
https://github.com/g19fanatic/stackoverflow-16713251-496405
这是一个link,其中Linus描述了这个问题,并将我上面提出的解决方案作为纠正它的一种可能方法......