我同意文档不是很清晰。通过测试,我发现了三个关于文件操作的差异:
总结:
reset --merge
总是放弃索引(暂存更改);如果任何文件上存在未暂存和已暂存的更改,则中止操作。reset --keep
保留索引,但取消暂存;如果重置目标触及相同的文件,则中止操作。测试场景:
echo First > file.txt
git add file.txt
git commit -m 'first'
git tag v1
echo Second >> file.txt
git commit -am 'second'
git tag v2
echo New > newfile.txt
git add newfile.txt
git commit -m 'third'
git tag v3
echo 'More stuff' >> file.txt
git add file.txt
现在我们有三个提交,'file.txt' 在v1和v2之间发生了变化,但在v2和v3之间没有发生变化。
在这种情况下:
git reset --merge v2
会丢弃那些更改git reset --keep v2
会保留它们,但取消暂存它们。如果我们尝试重置为v1:
git reset --merge v1
会丢弃更改git reset --keep v1
则会拒绝:
error: Entry 'file.txt' would be overwritten by merge. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git echo "Even more things" >> file.txt
现在两者都失败了,但出现的错误信息略有不同:
git reset --merge v1
error: Entry 'file.txt' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git reset --keep v1
error: Entry 'file.txt' would be overwritten by merge. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
echo Unrelated > unrelated.txt
git add unrelated.txt
echo Stuff >> unrelated.txt
现在有些奇怪:
git reset --merge v1
error: Entry 'unrelated.txt' not uptodate. Cannot merge.
fatal: Could not reset index file to revision 'v1'.
git reset --keep v1
保留两组更改,但未暂存。
为了完整起见,这两种情况表现相同:重置成功,文件保持未暂存状态。
在处理合并冲突时,它们是不同的,例如这将生成一个冲突。
git init
echo 333 > foo.txt
git add foo.txt
git commit -m 333
git checkout -b feature
echo 444 > foo.txt
git commit -am 444
git checkout master
echo 555 > foo.txt
git commit -am 555
git merge feature
那么
$ git reset --keep
fatal: Cannot do a keep reset in the middle of a merge.
$ cat foo.txt
<<<<<<< HEAD
555
=======
444
>>>>>>> feature
对比
$ git reset --merge
$ cat foo.txt
555