在“选择性”或“部分”合并之后重新合并

时间:2016-04-19 19:43:44

标签: git merge

这是我可以解决的问题的可重现的例子:

设置

mkdir test-git
cd test-git
git init
echo 'Hello, world.' > file1.txt
git add .
git commit -m 'init commit'
git branch branch2
git checkout branch2
echo 'Hello, universe' > file1.txt
echo 'Foobar' > file2.txt
git add .
git commit -m 'commit 2'

我想将branch2合并到master中,但只对file1.txt进行了更改,所以这就是我所做的:

git checkout master
git merge branch2 --no-commit --no-ff
git reset -- file2.txt
git commit -m 'Partially Merged Branch2 into Master!'

所以这里我意识到这可能不是一个好主意......让我说我改变了主意,现在我想合并file2.txt。我可以跑:

git merge branch2
  

回复:已经是最新的。

如果我运行git diff branch2 --name-status它会返回D file2.txt,所以我想当我取消暂存file2.txt时,它会将其作为删除进行跟踪?我仍然不完全理解为什么我不能合并,它不会添加文件(我显然不太了解git的合并算法)。

不幸的是,我目前的情况比这复杂得多,所以我无法完全撤销提交。有没有一种简单的方法可以重新合并masterbranch2之间的差异,而无需重写历史记录?

1 个答案:

答案 0 :(得分:2)

在git中,合并提交应该具有来自其所有父项的所有必要更改。因此,如果提交者故意决定像您一样选择某个版本的文件,那么生成的提交将被视为“正确合并”,并且无法执行“进一步合并”。

这种行为有其原因。假设在第一次合并提交后对file2.txt中的branch2进行了额外更改,然后执行branch2master的另一次合并(非常典型的情况,不是它?)。什么应被视为file2.txt的正确状态。我希望第二次合并只包含两次合并之间的更改,对吧?但是,当git收集自历史开始以来未应用的file2.txt的所有更改时,您需要其他一些行为。那会很烦人。

然而,您可以进行“替代合并”。也就是说,在master分支(在您的示例中,'init commit')上合并之前跳转到提交,然后再次发出git merge

如果历史记录重写不适合您的需要,您可以在该提交中创建一个新分支b3,执行合并,然后将b3合并回master。当然,您将在file2.txt收到合并冲突,并应通过为其提供“适当的变体”来解决它。