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

问题描述 投票:2回答:2

我有两个分支,开发和掌握。我想樱桃挑选一些关于从开发到主人的特定功能的提交。但是从开发到掌握的樱桃提取的提交数量大约为106,这意味着我必须通过所有提交才能过滤掉相关的提交。为了避免必须经历每次提交的更改然后挑选个别或一系列的那些,我想采取捷径:D。我合并开发成master,合并提交中有大约115个文件更改。

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

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

git git-merge git-commit git-cherry-pick git-merge-conflict
2个回答
1
投票

不幸的是,你的捷径误用了“合并”。当您尝试合并两个分支,获取冲突,手动解析它们,然后提交合并时,您告诉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_merge之后的树的一部分到master)上移动到我们修复的分支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重新分支它。


0
投票

我认为你需要做的是添加一个小的变化来开发分支(让它成为一个额外的空间)然后切换到主git merge开发将添加更改,包括你先前删除的删除的更改然后git push为了避免将来的问题是在我看来,每个功能都应该在一个分支上,一旦完成将合并到主人

© www.soinside.com 2019 - 2024. All rights reserved.