这是我可以解决的问题的可重现的例子:
设置
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的合并算法)。
不幸的是,我目前的情况比这复杂得多,所以我无法完全撤销提交。有没有一种简单的方法可以重新合并master
和branch2
之间的差异,而无需重写历史记录?
答案 0 :(得分:2)
在git中,合并提交应该具有来自其所有父项的所有必要更改。因此,如果提交者故意决定像您一样选择某个版本的文件,那么生成的提交将被视为“正确合并”,并且无法执行“进一步合并”。
这种行为有其原因。假设在第一次合并提交后对file2.txt
中的branch2
进行了额外更改,然后执行branch2
到master
的另一次合并(非常典型的情况,不是它?)。什么应被视为file2.txt
的正确状态。我希望第二次合并只包含两次合并之间的更改,对吧?但是,当git收集自历史开始以来未应用的file2.txt
的所有更改时,您需要其他一些行为。那会很烦人。
然而,您可以进行“替代合并”。也就是说,在master
分支(在您的示例中,'init commit')上合并之前跳转到提交,然后再次发出git merge
。
如果历史记录重写不适合您的需要,您可以在该提交中创建一个新分支b3
,执行合并,然后将b3
合并回master。当然,您将在file2.txt
收到合并冲突,并应通过为其提供“适当的变体”来解决它。