Git - 为什么在删除的文件上运行命令时需要双短划线?

时间:2013-04-12 13:54:27

标签: git git-log

考虑一个git存储库,其中一个文件曾被删除。

git rm path/to/file
git commit -a -m"testing"

好的,现在我想查看该文件的git log,但收到了经典错误消息:

git log path/to/file
fatal: ambiguous argument 'path/to/file': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions

解决方案很简单 - 添加--

git log -- path/to/file

但是......为什么?为什么需要这个?这里的理由是什么?不能git做一个有根据的猜测,这可能是一个文件一次?我理解“模棱两可”的问题 - 但从来没有这个名称的标签。如果文件一旦被删除,并且没有标签,那么选择“文件解释”始终是一个不错的选择。

另一方面,可以有一个名为与文件相同的标记,git log处理得非常好:

fatal: ambiguous argument 'path/to/file': both revision and filename
Use '--' to separate filenames from revisions

此行为似乎不一致。任何人都可以解释一下git的开发人员的想法吗?

3 个答案:

答案 0 :(得分:8)

git log可用于文件以及分支,标签等。

假设您有一个名为a/b/c的文件夹,您将使用

获取此文件夹的提交
git log a/b/c

没关系。

您还可以拥有一个名为d/e/f的分支。您将使用

获取此分支的提交
git log d/e/f

那也没关系。

如果git log应该处理的项目无法明确确定,事情就会变得复杂起来。如果你是愚蠢的并且也打电话给你的分支 a/b/c,那么git就没有任何线索可以打印其日志:分支 a/b/c目录的日志 a/b/c?因此,您必须更多地了解您想要接收的信息:

  • 显示分支 a/b/c的日志:
    git log a/b/c --
  • 显示当前分支中文件夹 a/b/c的日志:
    git log -- a/b/c
  • 显示a/b/c分支中文件夹 a/b/c的日志:
    git log a/b/c -- a/b/c

使用已删除的文件,您会遇到类似的问题:工作副本中既没有名为path/to/file的文件,也没有名为path/to/file的分支。这就是你必须指定你想要的东西的原因。

当然,git可以知道一个名为path/to/file 20.000修订版的文件,但这需要(最坏的情况)搜索项目的整个历史记录是否这样的文件是否存在。

通过在--之后明确指定文件路径,告诉git:

  

更难搜索该文件,即使需要数小时


结论(回答你的问题):
在您的情况下,需要--,否则git log通常会慢一些。

答案 1 :(得分:3)

为什么文件存在时的差异与不存在时的区别?让我们来看看案例:

  1. 修订版和文件名都存在。显然含糊不清。
  2. 存在修订版,文件名不存在。显然不含糊。
  3. 修订版不存在且文件名不存在。显然不含糊。
  4. 修订版不存在,文件名也不存在。暧昧?
  5. 确实是。

    要知道文件是否存在于某个路径中是指走历史,打开每个提交,打开每个树并走树,以查看此路径是否存在。在具有大量提交和深度路径的大型存储库中......这可能会变得昂贵,尤其是在慢速磁盘上。

    但是!你说。这究竟是git log filename究竟是什么呢?答案是肯定的,确实如此。不同之处在于,当我运行git log filename并且知道该文件存在时,git-log 知道我想花时间来获取此历史记录。

    相反,如果我运行git log foo并且foo不是当前存在的修订版或文件,那么它需要花时间来遍历整个图表,只是为了告诉我foo是不明确的。

    哎哟。

    所以欢迎你说git log -- filename告诉git你真的希望它走图表。否则,它会下降。

    旁注: git只是stat(2)你在命令行上给出的参数,以确定文件是否存在。它不会查找索引,也不会打开您的HEAD树。当然,它可以执行这些操作,这将允许您使用git log filename,其中filename是一个删除而不是提交提交。这似乎是一个非常合理的变化。

答案 2 :(得分:2)

  

从来没有这个名字的标签。

为什么这么说? git tag path/to/file工作正常。

它看起来非常简单:git rm仅获取路径名; git log获取引用名称和路径名,首先重新命名,任何可能是路径名的东西也可以是引用名称 - 这不是一个规则,可以作为定义的引用名称。< / p>

在小项目上,git log很容易决定如果它有效则必须在某个时刻成为源文件的路径,但此时你必须做出一个判断调用来平衡这里所有可能的搞砸的可能性和成本。您是否更有可能要求提供不再存在的文件的日志,或者您是否使用了现有的路径名或现有的ref? git log remote/ref很常见。我认为git只是假设一个名称不匹配任何电流最有可能成为一个错字。