为什么git checkout 文件的行为类似于重置已暂存的文件再检出未暂存的文件?

3

我在Git文档中看到了这个语句:

Checking out a file is similar to using git reset with a file path, except it updates the working directory instead of the stage

链接:https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting

部分内容:“Git Checkout文件”

现在假设我有一个存储库和其中一个文件test.txt

首先,工作目录是干净的:

On branch master
nothing to commit, working tree clean

现在我修改了test.txt,运行git add之后,git status显示如下:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   test.txt

现在我运行git checkout HEAD test.txt,并得到以下结果:

Updated 1 path from 58e7043
< p >< code > git status 的输出:
On branch master
nothing to commit, working tree clean

根据文档,test.txt索引中的版本应该保持不变,在工作目录中的版本应该改回到指向HEAD的提交的版本,导致文件在工作目录和索引之间存在不同版本,那么此时不应该输出git status吗?但是git status没有显示这个 - 为什么呢?
通常情况下,要从暂存的文件转到干净的工作树,我必须使用git reset HEAD <filename>,然后使用git checkout HEAD <filename>来执行该文件,但是在这里看起来都执行了??
我感到困惑。
编辑 - 还有有趣的是,如果我在暂存文件test.txt之后运行git checkout test.txt而不是git checkout HEAD test.txt,我会得到:
Updated 0 paths from the index

尽管这两个表单应该是等价的,其中前者默认也是使用HEAD方法提交的(?)

我又有些困惑了。

1个回答

4
首先,那不是官方文档,我认为这是一种情况,在这种情况下,Atlassian在比较两个命令之间非常肤浅。有时,就像这次一样,相同的git命令根据您使用的选项执行非常不同的操作。在SO上,您可以找到深入探讨该主题的好答案。
只是为了回答你的问题,这里是关于 git checkout with a pathspec的官方文件的内容:
覆盖与pathspec匹配的文件的内容。当未给出(通常是提交)时,用索引中的内容覆盖工作树。当给出时,用中的内容覆盖索引和工作树。
您处于第二种情况,即给出了<tree-ish>HEAD),这是预期的行为:索引和工作目录都被旧版本的test.txt覆盖。
相反,如果您使用git checkout test.txt,并且test.txt已经暂存,那么工作目录或索引都不会改变,因为您基本上是用索引版本替换工作目录版本,但它们显然是一样的。
Atlassian文章试图表达的是:
  • git checkout <pathspec>主要在工作目录上操作(如果提供了<tree-ish>,则还在索引上)
  • git reset仅在索引上操作。
产生误解的原因是在git reset中,<tree-ish>默认为HEAD。相反,如果指定<tree-ish>git checkout的行为会有所不同。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接