从提交中git checkout文件后,git diff没有显示任何更改?

4

我对git checkout的行为感到困惑。如果我想获取文件的以前版本并进行如下操作:

git checkout HEAD^^ Xml/Config-Profile.xml
git status

I get:

On branch master
Your branch is up-to-date with 'origin/master'

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified: Xml/Config-Profile.xml

如果我运行 git diff,却没有差异。我已经弄清楚了,如果我运行 git diff --cached,它会显示更改,所以我猜这意味着我的 checkout 命令从存储库的 HEAD^^ 提交中提取并更新了“仅索引”? 我的担心是(我无法直接从 checkout 手册页面获取信息):
1)为什么只更新了索引?为什么它不像我刚刚用某个(先前的)文件副本替换了工作目录中的 Config-Profile.xml 文件一样?
2)我想让我感到困惑的是,也许这只是语义方面的问题,如果我在我的工作目录中编辑一个文件,并决定我不喜欢它并执行 git checkout,它将替换工作目录中的文件。在陈述完之后,我猜测 git checkout 将最新的文件从索引中提取到工作目录中,而不是从存储库中的最新提交中提取文件?
3)有一个命令可以将文件直接从提交中提取到工作目录中,就好像我自己手动编辑到那个点一样吗?或者我需要创建一个自定义别名?
提前感谢。

当两个人的回答略有不同但都是“正确”的时候,你该怎么做? :) @user3426575 尝试回答了我真正想要的第三个问题,但他是第二个回答的。 我猜我只是不知道正确的礼仪。 - Terry
2个回答

5

git checkout 命令更新了索引(index)和工作目录(working tree)。

git diff 命令将工作目录与索引进行比较。

git diff --cached 命令将索引与 HEAD 进行比较。

git help checkout 命令介绍了 git checkout <tree-ish> -- <pathspec> 的用法:

    The <tree-ish> argument can be used to specify a specific tree-ish 
    (i.e. commit, tag or tree) to update the index for the given paths
    before updating the working tree.

如果您只想更新您的工作树,您可以使用以下命令重置索引: ```bash git reset ``` 请注意,这将不会更改您的提交历史记录。
git reset HEAD Xml/Config-Profile.xml

根据你的git status输出所建议的。


既然你先回答了,我就接受你的回答。不过,为了回答我的最后一个问题,基本上我自己创建了一个别名。recover = !sh -c 'git checkout $1 $2 && git reset HEAD $2'。我想这是来自我们以前的SCM,如果你执行了“获取以前的版本”,它只会用请求的副本替换你的工作副本,并将其视为已更改的文件(与你手动修改文件没有区别),你可以随意处理(丢弃或提交)。 - Terry

1
当给git checkout提供提交和路径时,它会从提交更新路径到工作树和索引中。 git diff在没有参数的情况下比较工作树和索引。由于两者都使用相同的文件进行更新,因此您看不到任何更改。

是否有一种命令可以将一个文件直接从提交中拉入工作目录,就好像我手动编辑到那个点一样?还是我需要创建自定义别名?

你可以这么做:
git show HEAD:Xml/Config-Profile.xml > Xml/Config-Profile.xml

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