GIT:如何合并先前从合并提交中删除的更改



我有两个分支,develop和master。我想挑选一些关于一个特定功能的提交,从开发到主功能。但是从dev到master的cherry-pick提交数量大约为106,这意味着我必须遍历所有这些提交才能过滤掉相关的提交。为了避免不得不经历每次提交的更改,然后挑选单个或一系列的更改,我想走捷径:D。我将development合并到master中,在合并提交中大约有115个文件更改。

我浏览了每个文件,并删除了那些与该功能无关的更改。对于某些文件,我完全删除了它们,对于一些文件,我只进行了部分更改,并删除了不必要的更改。在浏览了所有115个文件后,剩下大约55个经过过滤的文件,这些文件与我在合并提交中提交的功能相关。

现在,当我查看master的git日志时,日志显示好像所有106个提交都被合并到了master中,并且在顶部显示了我的名为"merged-development-to-master"的合并提交。现在我想将development合并到master中,以便真正合并我之前从合并提交中删除的剩余文件,git说没有什么可以合并的,尽管两个分支之间都有更改,但由于我从合并提交删除了这些更改,我现在无法将这些更改移到master中。我需要从主文件中删除合并提交吗?或者有任何方法可以强制完全合并差异吗?为了避免未来出现任何问题,应该采取什么正确的方法?

不幸的是,您的快捷方式误用了"merge"。当你试图合并两个分支,获取冲突,手动解决它们,然后提交合并时,你告诉Git,合并这两个分支(以及所有在这两个分枝上进行的提交)的"正确"方式是选择手动解决提交的方式。如果你从develop"重新合并",Git不会否决你的手动冲突解决方案,因为你已经告诉Git什么是正确的合并,它也不会试图反驳你(好吧,除非它真的很困惑)。Git无法区分您为解决两个合并所做的更改与您希望"稍后保存"的更改。

必须重置错误的合并,但以下是如何相对自动地完成合并,而不需要太多麻烦。您提到自合并后您在master上又进行了一次提交。如果根本没有,你可以跳过几个步骤,但我在下面给出了更通用的解决方案,如果你在masterdevelop上都添加了额外的提交,它也会起作用。

我假设如下。

  • 当您进行"错误合并"时,您将develop合并到master中(即,您在master上运行git merge develop,而不是相反)
  • 在这一点上,您不太关心历史记录的外观,您只想从"坏合并"之前的develop中获得"丢失"的更改(加上此后的其他更改,如果您有)成功合并到master
  • 您尚未在任何地方发布masterdevelop,因此没有其他发布依赖于它们的历史记录
  • 您当前已在干净的树中签出了master

与任何混乱的Git操作一样,在这里对存储库进行完整备份(cp -agit clone mirror)不是一个坏主意。

首先,让我们命名糟糕的合并。在你的日志中找到它的散列,并为它创建一个标签。(在你的情况下,它是master^,但更常见的是,你可能必须搜索它。)

git tag bad_merge 8354cbeb
git log bad_merge  # !! double check that this points to the bad merge !!

现在,我们将查看一个新的fix_merge分支。我们将从bad_merge:开始

git checkout -b fix_merge bad_merge

然后,我们将把分支回滚到"坏合并"之前的master状态,但保持工作目录不变(因此它包含手动编辑以将第一个功能添加到master):

git reset HEAD^

我们将重新推荐这些手动编辑:

git add -A
git commit -m 'fix_merge: add first feature to master'

现在,我们要做一个有点复杂的重新基准。(如果由于合并失败,在master上没有任何提交,那么这是不必要的步骤。)

git checkout master
git branch master_backup   # make a copy in case something goes wrong
git rebase --onto fix_merge bad_merge master

这将在master分支上所做的更改从坏合并后的移植到其当前状态(即,从bad_mergemaster的树的部分)ONTO我们修复的分支fix_merge。再碱基后,master将指向移植的分支。不应该有冲突,因为bad_mergefix_merge中的树完全匹配;只是提交历史被重写了,因为一个有合并,另一个没有。

我们现在有以下情况:

  • master的历史记录,而不是从develop进行合并,现在只需提交一次手动编辑即可添加第一个功能,再加上自错误合并以来在master上所做的额外工作。它缺少的是从develop(糟糕地)合并而来的历史。

  • develop分支现在有第一个功能的(复杂)历史,加上您在错误合并之前开发的但希望"保存以备将来使用"的功能,再加上您此后所做的额外工作(在您的情况下没有,但此解决方案也适用于这些功能)。

如果你从develop中精心挑选了第一个功能,这或多或少就是你的处境,只是它都是在一次提交而不是多次提交中精心挑选的。现在,如果将develop合并为master:

git checkout master    # probably already there, but make sure
git merge develop

并解决任何冲突——可能会有很多冲突,因为Git试图将develop分支中第一个功能的所有单独提交与master中的大型单片提交相匹配,所以这可能是一个丑陋的合并——然后你可以提交合并:

git commit

并且您最终应该成功地将master与来自develop的所有更改合并,无论是在错误提交之前还是之后。

此时,您可能需要考虑将master合并回develop,或者完全放弃develop并从master重新分支它。

我认为这里需要做的是添加一个小的更改来开发分支(让它成为一个额外的空间),然后切换到mastergitmergedevelop将添加更改,包括您之前删除的已删除更改然后git-push为了避免未来的问题,我认为每个功能都应该在一个分支上,一旦完成,就会合并到主

相关内容

  • 没有找到相关文章

最新更新