git reset --merge vs git reset --keep

13 git git-reset

我已经阅读 了文档,但是我很难理解它们之间的区别

git reset --merge
Run Code Online (Sandbox Code Playgroud)

git reset --keep
Run Code Online (Sandbox Code Playgroud)

请提供简单的解释和/或示例.

Ste*_*ett 8

我同意文档不是很清楚.从测试中,我发现了三个不同之处,与文件发生的情况有关:

  • 已经上演了变化
  • 没有非分期更改

综上所述:

  • 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
Run Code Online (Sandbox Code Playgroud)

我们现在有三个提交,'file.txt'在v1和v2之间发生变化,但在提交v2和v3之间没有变化.

索引和新HEAD之间没有变化

在这种情况下:

  • git reset --merge v2 扔掉那些变化
  • git reset --keep v2 保留它们,但不要让它们失效.

索引和新HEAD之间的变化

如果我们改为尝试重置为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'.
    
    Run Code Online (Sandbox Code Playgroud)

索引和新HEAD之间的更改以及未分级更改

    git echo "Even more things" >> file.txt
Run Code Online (Sandbox Code Playgroud)

现在,两者都失败了,但错误消息略有不同:

对不相关文件的分阶段和非分阶段更改

echo Unrelated > unrelated.txt
git add unrelated.txt
echo Stuff >> unrelated.txt
Run Code Online (Sandbox Code Playgroud)

现在这有点奇怪:

  • git reset --merge v1

    error: Entry 'unrelated.txt' not uptodate. Cannot merge.
    fatal: Could not reset index file to revision 'v1'.
    
    Run Code Online (Sandbox Code Playgroud)
  • git reset --keep v1

    两组更改都保留,但未分级.

没有分阶段的更改,但是没有进行更改

为了完整起见,这两者的行为相同:重置成功,文件保持未分级.


小智 7

它们在处理合并冲突时是不同的,例如这会产生冲突

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
Run Code Online (Sandbox Code Playgroud)

然后

$ git reset --keep
fatal: Cannot do a keep reset in the middle of a merge.

$ cat foo.txt
<<<<<<< HEAD
555
=======
444
>>>>>>> feature
Run Code Online (Sandbox Code Playgroud)

相对

$ git reset --merge

$ cat foo.txt
555
Run Code Online (Sandbox Code Playgroud)