Git撤销合并提交,丢失了一些文件。

3
所以我错误地将我的feature分支合并到了release上并进行了推送。 然后用反向提交的方式将其恢复,一切都很顺利。
问题出现在尝试将release合并到master时,发现有一些缺失的文件和奇怪的更改。 当这个损坏的合并实际上被推送到我的master分支时,问题变得更加令人担忧。
回顾撤销合并提交(W1),我发现所有这些缺失的文件都是在反向提交中删除的文件。
记住feature分支无论如何都要合并到master上,我想从master上的那个反向提交(W1)开始rebase -i,并像没有反向提交那样继续前进。
你认为有更好的解决方案吗?
谢谢大家! :) enter image description here 首先,感谢您的关注和回应!我在图片上添加了一些内容,以更好地解释情况。
实际上,我们不再关心图片中的release分支,它只影响一些文件,并且可以在master上存在而不会有任何主要问题。文件的添加和修改是在创建releasefeature之间在master中进行的。
我正在尝试重新设置master分支,在发布合并(M2)后删除(W1)。我知道我们失去了一些release历史记录,但我认为这是一个更好的解决方案,可以“保存”实际发布的代码,如果需要,我们可以从中开始一个新的repo。有大约1000个提交需要重新设置,一些冲突正在出现。我正在使用每个文件的最新正确版本来纠正每个明显的冲突。
编辑2
最终,我们重新设置了master分支,然后在分支顶部应用差异,就像“虚假重新设置”一样,这样更改就是可见和可更改的。
1个回答

3

更新:

根据您更新的问题,我了解到文件删除发生的原因。对我来说,这似乎是一种不寻常的情况组合。最有趣的一点是,与我一开始看到的相比,合并的还原操作更加危险。撤消合并(通过重置以在将其推送之前从历史记录中清除它)是典型的程序,并且可以避免这种问题-如果在推送之前捕获到该问题。但这在此时此地没有太大的帮助。

尽管有澄清,我仍然建议反对您提出的历史编辑,而且我在原始答案中包含了所有与该编辑相关的建议。请记住,如果您以一种编辑来自release的提交的方式重新定位master,则release仍将具有原始提交,您将拥有一个奇怪的、易于产生冲突的分裂历史记录,在某些合并操作上会存在冲突(因为重复提交执行相同的操作)。

如果您想将M1中的所有更改放回历史记录中,可以通过还原W1来完成,这样做会减少许多麻烦,虽然仍可能会出现一些冲突,但这是一个更简单的过程;不会创建上游rebase问题;并且在以后的合并操作中会减少冲突。


听起来您正在考虑编辑发布分支的历史记录。出于短期原因(需要“上游rebase”解析)和长期原因(发布分支将不再记录已发布内容),我建议反对它。当然,我可能误解了您的提议,因此让我们从一个共同的起点开始:

您当前拥有类似于

O --- x --- x --- x --- M2 <--(master)
 \     \               /
  \     x --- M1 --- W1 <--(release)
   \         /
    A ----- B --- C --- D <--(feature)

这段代码中的M1是将feature错误地合并到了release中,W1撤销了M1M2最终将release合并到了master

据我所知,所有这些都已经被推送了,其中一些反映在您发布版本的历史记录中,并且“问题”提交也已经成为master共享历史的一部分。因此,如果我是您,我会考虑几乎所有内容都是“铁板钉钉”的。

如果您最终决定使用rebase来“修复”发布分支,则需要考虑两件事:

1)最好从发布分支历史记录中删除M1W1,以便其结果树至少正确反映了您发布的内容。(我意识到最终将重新引入M1的工作,但这不是您发布的内容。)

2)完成后,您必须使用新的release引用重新执行M2合并(创建M2'),然后将master和自M2以来从master分支出的任何其他分支,都rebase到M2'。如果这是一个活动的存储库,它可能会很快变得复杂。

这就是为什么我不会这样做的原因。那么您还能做什么呢?

听起来release的输出看起来应该是正确的,因此我不清楚为什么这会对master产生任何不良影响,直到您尝试合并feature为止。毕竟,如果在W1中删除了一个文件,则该文件必须已经被M1添加(从release的角度来看),因此将其应用于master时通常不会有任何净变化。如果master出现问题,即使它不包含feature,也可能需要更多信息以了解原因(以及如何处理它)。

(或者,另一方面,如果在您开始尝试将release合并到主分支之前,feature已经被合并到master中-这可以解释为什么合并看起来很混乱-那么这将需要与我所建议的不同的解决方案。)

但是,根据问题的描述,如果您尚未合并“feature”,那么当您尝试将“feature”合并到“master”时,我会预计git会认为通过“M1”已经应用了添加文件的代码“ A”和“B”(然后在“W1”中进行的后续更改恰好撤消了它,但git并不太关心这一点)。
我猜您需要的是执行与“A”和“B”相同操作的新提交。您可以通过将“feature”变基到“M2”(或更高版本的“master”)来相对轻松地完成此操作。问题是,如果您告诉变基命令“master”是您的上游分支,则它将跳过“A”和“B”(因为这些提交已经包含在“master”中)。因此,您必须强制将上游分支设置为提交“O”。
因此,您可以查找提交“O”的SHA值,或者给其打上标签(例如“feature-root”),然后...
git rebase --onto master feature-root feature

yielding

                          A' --- B' --- C' --- D' <--(feature)
                         /
O --- x --- x --- x --- M2 <--(master)
 \     \               /
  \     x --- M1 --- W1 <--(release)
   \         /
    A ----- B --- C --- D

所以 CD 不重要(gc 最终会回收它们),AB (以及 M1)则保留在历史记录中(避免了最棘手的上游 rebase 问题),只有共享 feature 引用的用户需要担心上游 rebase 恢复。

谢谢您的回复,我已经研究了您所说的,并在主贴中更好地解释了情况。 - gienini

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接