恢复通过“我们的”策略解决的合并提交

时间:2019-09-13 14:08:38

标签: git git-merge git-merge-conflict

我的一位同事将我们的开发部门通过'--strategy = ours'或一系列有效地导致放弃开发变更的操作合并回功能部门。

我试图找到一种还原合并提交以将更改恢复的方法,但是我找不到一个简单的配方:

  • git revert -m 1 merge-sha1 不起作用,因为与第一个父对象没有任何变化
  • git revert -m 2 merge-sha1 确实将开发更改带入了我们的分支,但似乎也摆脱了许多我们不想保留的未开发的更改。 li>

我在网上搜索,发现了一些有关此类或类似情况的文章,但找不到正确解决这种混乱局面的正确方法。最后,在错误合并之前,我们从头开始创建了一个新分支。这种情况如何彻底解决?

编辑:

为了更好地解释:

--A--B--C--D--E--F--G--H--I
         \           \
          D'--E'--F'--M--G'

M是错误的合并,它丢弃了从DG的所有更改。 使用第一个选项(-m 1),什么也不会发生。使用第二个选项(-m 2),还原似乎可以删除D'-F'中发生的更改以及添加已删除的更改。

对不起,忘记添加git reset是不可行的选择,因为合并已被推送到远程仓库,并且不允许git push --force

2 个答案:

答案 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一起运行,因此它的树与FF'(两者中的第一个父项)匹配:

我不太确定为什么要用质数标记一些提交(D'-E'-F'等),但是如果M 应该是真正的合并,而不是{ {1}},您需要重新运行合并。您可以按照自己喜欢的任何方式执行此操作,但最简单的方法是检出其任一父级,分别在--oursG处,然后使用其另一父级的哈希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' / \___________/ 的所有其他用户进行调整),或者您可以在此处放置一个临时名称(标签或分支)br2git 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 mergeM2,以产生G'。您可以使用M3随机选择git merge -s resolveF'中的一个作为合并基础,如果在创建虚拟合并基础时存在合并冲突,则可能不会太杂乱。如果您正确地创建了G(对于“正确”的某种定义),则M2的结果将是相同的。

最后,Git不在乎如何到达最终提交图以及这些提交中的快照。 Git真正关心的只是保留提交(保留图形)。分支 names 仅用于查找提示提交:图中的入口点。各种单独的命令,例如-s resolvegit diff,比较特定的提交,也许从图中 找到它们,然后从那里做一些有趣的事情,因此您可能需要特定的提交具有特定的内容,因此使它们尽可能有趣。

同时,git cherry-pick本身只是查看图形以查找合并基础,然后进行两个(差异(从合并基础到每个提示提交)以查找更改,然后合并更改。当然也有一些例外:git merge使用与真正合并相同的图形链接进行新的mergecommit,但完全忽略了两个分支技巧之一,因此不必费心寻找合并基础,它只是重用当时的提交中的树。并且,如上文所述,-s ours找到 all 个合并基础。通常只有一个,因此没有什么特别的,但是有多种方法可以获取多个合并基础,为此,-s recursive仅合并合并基础以生成新的(临时)提交以用作合并基础。 (完成“作为一个词的合并”过程后,它将释放临时提交,以供Git通常的垃圾收集过程回收。)

答案 1 :(得分:0)

如果要恢复为特定的提交,只需运行git reset <sha1>。无论后继的提交类型如何,此方法都应起作用。运行git log在合并之前找到最新的提交,然后将其重置。