繁体   English   中英

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

[英]GIT: how to merge changes, which were earlier removed from the merged commit

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

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

现在,当我查看 master 的 git log 时,log 看起来好像所有 106 个提交都合并到 master 中,并且在顶部出现了名为“merged develop into master”的合并提交。 现在我想将 develop 合并到 master 中,以便实际合并我之前从合并提交中删除的剩余文件,git 说虽然两个分支之间都有变化,但没有什么可以合并的,但由于我从合并提交我现在无法将这些更改移动到 master 中。 我是否需要从 master 中删除合并提交,或者有什么方法可以强制完全合并差异? 为了避免将来出现任何问题,这里应该采用什么正确的方法?

不幸的是,您的快捷方式误用了“合并”。 当您尝试合并两个分支,遇到冲突,手动解决它们,然后提交合并时,您是在告诉 Git 合并这两个分支(以及在这两个分支上进行的所有提交)的“正确”方式是选择手动解决提交。 如果您从develop “重新合并”,Git 不会否决您的手动冲突解决方案,因为您已经告诉 Git 正确的合并是什么,并且它不会试图反驳您(好吧,除非它真的很困惑) . Git 无法区分您为解决两次合并而进行的更改与您想要“保存以备后用”的更改之间的区别。

不得不重置错误的合并,但您可以通过以下方法相对自动地进行操作,而无需大惊小怪。 您提到自合并以来您对master又进行了一次提交。 如果那根本不存在,您可以跳过几个步骤,但我在下面给出了更通用的解决方案,如果您在masterdevelop上添加了额外的提交,这也将起作用。

我假设如下。

  • 当您进行“错误合并”时,您将develop合并到master (即,您在master运行git merge develop而不是相反)。
  • 在这一点上,您不太关心历史的外观,您只想从“错误合并”之前的develop获取“丢失”的更改(加上此后的其他更改,如果有的话)成功合并成master
  • 您尚未发布masterdevelop的任何地方,所以没有其他respositories依靠他们的历史。
  • 您当前已在干净的树中检出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我们维修分公司fix_merge rebase 后, 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重新分支。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM