我的一位同事将我们的开发部门通过'--strategy = ours'或一系列有效地导致放弃开发变更的操作合并回功能部门。
我试图找到一种还原合并提交以将更改恢复的方法,但是我找不到一个简单的配方:
我在网上搜索,发现了一些有关此类或类似情况的文章,但找不到正确解决这种混乱局面的正确方法。最后,在错误合并之前,我们从头开始创建了一个新分支。这种情况如何彻底解决?
编辑:
为了更好地解释:
--A--B--C--D--E--F--G--H--I
\ \
D'--E'--F'--M--G'
M
是错误的合并,它丢弃了从D
到G
的所有更改。
使用第一个选项(-m 1
),什么也不会发生。使用第二个选项(-m 2
),还原似乎可以删除D'
-F'
中发生的更改以及添加已删除的更改。
对不起,忘记添加git reset
是不可行的选择,因为合并已被推送到远程仓库,并且不允许git push --force
。
答案 0 :(得分:1)
...我在网上搜索,发现了一些有关此类或类似情况的文章,但找不到正确解决此混乱局面的正确方法。最后,在错误合并之前,我们从头开始创建了一个新分支。这种情况如何彻底解决?
实际上 是正确/简洁的方法-尽管您本身不需要新的分支,因为分支名称对Git并不那么重要。< / p>
[给出此图]
--A--B--C--D--E--F--G--H--I <-- br1 \ \ D'--E'--F'--M--G' <-- br2
[where]
M
是错误的合并,它丢弃了从D到G的所有更改...
所有 revert 选项通过将M
与它的两个父项之一进行比较来起作用。由于M
与--ours
一起运行,因此它的树与F
或F'
(两者中的第一个父项)匹配:
我不太确定为什么要用质数标记一些提交(D'-E'-F'
等),但是如果M
应该是真正的合并,而不是{ {1}},您需要重新运行合并。您可以按照自己喜欢的任何方式执行此操作,但最简单的方法是检出其任一父级,分别在--ours
和G
处,然后使用其另一父级的哈希ID运行F'
。通常,我建议保留两者的第一亲和第二亲属性,所以我会这样做:
git merge
照常完成合并,如果Git本身不提交,则提交它:
git checkout <hash-of-G>
git merge <hash-of-F'>
然后,根据您要查看的内容,选择 _________
/ \
--A--B--C--D--E--F--G--H--I \ <-- br1
\ \ M2 <-- HEAD
D'--E'--F'--M--G' / <-- br2
\___________/
并选择重设G'
以指向结果:
br2
(但这是非快进的情况,需要 _________
/ \
--A--B--C--D--E--F--G--H--I \ <-- br1
\ \ M2--G" <-- br2
D'--E'--F'--M--G' /
\___________/
的所有其他用户进行调整),或者您可以在此处放置一个临时名称(标签或分支)br2
, git checkout br2
临时名称,然后删除临时名称:
git merge
请注意,在生成合并 _________
/ \
--A--B--C--D--E--F--G--H--I \ <-- br1
\ \ M2--M3 <-- br2
D'--E'--F'--M--G'-----/---/
\___________/
时,合并基数既是M3
,又是F'
,因此G
将在默认情况下对这两个进行递归合并,以用作合并基础;然后,它将针对该虚拟合并库合并git merge
和M2
,以产生G'
。您可以使用M3
随机选择git merge -s resolve
或F'
中的一个作为合并基础,如果在创建虚拟合并基础时存在合并冲突,则可能不会太杂乱。如果您正确地创建了G
(对于“正确”的某种定义),则M2
的结果将是相同的。
最后,Git不在乎如何到达最终提交图以及这些提交中的快照。 Git真正关心的只是保留提交(保留图形)。分支 names 仅用于查找提示提交:图中的入口点。各种单独的命令,例如-s resolve
和git diff
,比较特定的提交,也许从图中 找到它们,然后从那里做一些有趣的事情,因此您可能需要特定的提交具有特定的内容,因此使它们尽可能有趣。
同时,git cherry-pick
本身只是查看图形以查找合并基础,然后进行两个()差异(从合并基础到每个提示提交)以查找更改,然后合并更改。当然也有一些例外:git merge
使用与真正合并相同的图形链接进行新的mergecommit,但完全忽略了两个分支技巧之一,因此不必费心寻找合并基础,它只是重用当时的提交中的树。并且,如上文所述,-s ours
找到 all 个合并基础。通常只有一个,因此没有什么特别的,但是有多种方法可以获取多个合并基础,为此,-s recursive
仅合并合并基础以生成新的(临时)提交以用作合并基础。 (完成“作为一个词的合并”过程后,它将释放临时提交,以供Git通常的垃圾收集过程回收。)
答案 1 :(得分:0)
如果要恢复为特定的提交,只需运行git reset <sha1>
。无论后继的提交类型如何,此方法都应起作用。运行git log
在合并之前找到最新的提交,然后将其重置。