1

我想查看给定文件的历史版本:.zshrc

这将向我显示此文件更改的所有提交:

git log .zshrc
...
...

现在对于给定的提交,我想查看整个文件。但下面实际上并没有显示该文件。它显示了该提交和先前提交之间的差异:

git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4 .zshrc

这根本不起作用:

git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc  

fatal: Path 'test/.zshrc' exists, but not '.zshrc'.
Did you mean 'bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:test/.zshrc' aka '2c0989168a2fbbaaa6ef31dc50616dd236c8b5d4:./.zshrc'?

最后,这符合预期。它将“猫”给定版本的文件

git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:./.zshrc

但是为什么git show这种不合逻辑和令人困惑的行为呢?

为什么git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4 .zshrc不同于git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc

git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc另外,即使 git 清楚地理解并建议我应该使用,为什么也不起作用: bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:test/.zshrc

为什么我不能使用相对路径:.zshrc而必须使用完全不必要的构造:./.zshrc

4

2 回答 2

2

为什么 git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4 .zshrc 与 git show bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc 不同

因为您正在运行git show <thing>,并且在第一种情况下<thing>只是一个提交。文件名充当提交差异的过滤器,因此您只能看到该特定文件的差异。

在第二种情况下(<commit>:<path>),<thing>是提交中的一个文件,所以你得到了它。

另外,为什么 git 显示 bbac89168a2fbbaaa6ef31dc50616dd236c8b5d4:.zshrc 不起作用...

我无法重现该特定问题(使用 git 2.31.1)。如果我有一个.zshrc在存储库顶层命名的文件,我可以运行git show <commit>:.zshrcgit 并显示文件内容。

但是为什么 git show 的行为如此不合逻辑和令人困惑呢?

其中一些命令已经存在了很长时间,人们已经开始依赖这种行为,尽管它可能令人困惑。近年来一直在努力为某些命令提供更现代的替代方案(参见例如git switch,它试图为以前属于的某些操作提供更明显的界面git checkout。我不知道是否git show已经成为这种类型的目标工作。

于 2021-09-09T03:25:41.993 回答
2

当您使用符号<commit hash>:<path>时,您可能会将其<path>视为从存储库根目录开始的绝对路径。

这将在任何情况下工作:在裸存储库中,使用外部工作树时......


开始路径./是命名相对路径的一种方法,它实际上向 git 表明:“尝试从我当前的工作目录中找出要在提交中检查的树”——当你有一个常规克隆时,这确实具有直观的含义回购,但在其他情况下可能会失败。


请注意, 的行为git show <commit> <path>也与 有很大不同git show <commit>:<path>

  • git show <commit> <path>会显示一个diff
    commit带来的diff <commit>,仅限于影响的东西<path>。它还将显示有关 commit的信息<commit>
  • git show <commit>:<path>将显示一个内容
    它将显示 git<path>为提交而存储的全部内容<commit>
    如果<path>指向一个文件(git 术语中的“a blob”),您将获得该文件的全部内容;如果<path>指向一个目录(git 术语中的“一棵树”),您将获得该目录的列表。

请注意,对于两个不同的命令如何解释它们的参数,或者一个相同的命令如何解释不同的参数,git 确实有不合逻辑和矛盾的选择。

这些选择中的大多数是以下原因的结果:

  • 一个命令首先是这样实现的,
  • 发布命令后,避免破坏依赖其行为的现有脚本或工作流非常重要。
于 2021-09-09T07:03:15.447 回答