两者之间的区别。git中的(点)和*(星号)通配符
我有一个本地存储库,并试图放弃自上次提交以来对它所做的所有更改两者之间的区别。git中的(点)和*(星号)通配符,git,wildcard,Git,Wildcard,我有一个本地存储库,并试图放弃自上次提交以来对它所做的所有更改 git checkout HEAD -- * 指挥部。即使更改在某个子目录中,一切都正常工作。但是当我添加一些未跟踪的文件(满足.gitignore中的掩码)时,比如说'Ignored.txt'到存储库的根目录,上面的命令会失败,并显示消息 error: pathspec 'Ignored.txt' did not match any file(s) known to git 相比之下 git checkout HEAD --
git checkout HEAD -- *
指挥部。即使更改在某个子目录中,一切都正常工作。但是当我添加一些未跟踪的文件(满足.gitignore
中的掩码)时,比如说'Ignored.txt'到存储库的根目录,上面的命令会失败,并显示消息
error: pathspec 'Ignored.txt' did not match any file(s) known to git
相比之下
git checkout HEAD -- .
一切正常。所以我想知道:
git中的
和*
通配符有什么区别
Git没有看到星号。它由shell扩展到当前目录中的所有文件名和目录名(不以点开头)。点不是通配符,它只是表示“当前目录”。所以 签出当前目录及其所有子目录,即git知道的所有内容。带星号的git可以看到
git checkout HEAD -- tracked-file1 tracked-file2 Ignored.txt
但它不知道如何签出被忽略的文件:因此出现了错误。这就是文件全球化
表示“当前目录”,而*
表示“替换所有可能的值”。通常情况下,bash(如果您使用的是bash)将接受*并实际替换所有可能的值(如果您只提供一个*作为参数),然后(在替换所有值后)将其移交给git。只有在没有匹配值的情况下(例如,您编写了“blahblah*”,并且没有与模式匹配的文件),bash才会放弃替换该值,并将“*”移交给git。首先要知道的是,
不是通配符
和*
都可以是路径规范(这就是您在使用的命令中使用它们的意思)。要了解如何解释路径规范,可以查看git词汇表()中的路径规范
但另一个复杂的问题是,在您的“失败”示例中,git没有收到*
的pathspec,因为您的shell在将其传递给git之前正在扩展*
。因此,为了完全理解这种行为,您还可以参考shell的文档,了解它如何预处理命令行
要将*
作为路径规范传递,而不受shell的干扰,可以将其转义。(假设您使用的是bash或类似的东西,这可能看起来像
git checkout -- '*'
不过,这取决于使用的是哪个shell。)主要的区别根本不在于Git
因为它不在Git中,所以它是否有任何区别,如果有,区别是什么,取决于您使用的not Git命令解释器
Shell vs Git
在Unix ish系统(包括Linux)上,命令解释器(或“shell”)为您展开*
。各种shell,如bash
和zsh
和fish
和tcsh
和dash
等(大多数shell的名称以sh
结尾),将*
解释为“当前工作目录中的大多数文件”。这种扩展称为
这些shell不会以任何方式解释和扩展
。这意味着:
git xyzzy -- .
使用三个参数调用git
,-
和
。但是:
git xyzzy -- *
如果当前工作目录中有名为a
,b
,a
,b
,c
,d
,e
,则使用七个参数调用xyzy
,b
,c
,d
,和e
Git并不经常使用工作目录
Git主要对存储在存储库中的提交感兴趣。为了构建新的提交,Git使用其索引(也存储在存储库中)。索引实际上以一种特殊的、仅限Git的压缩格式保存文件,这种格式与提交中的格式基本相同
文件的索引副本是可写的,而任何文件的提交副本都是只读的。(从技术上讲,Git只是将对象保留在其主对象数据库中,而索引和提交副本都只是对这些对象的引用。您不能覆盖任何对象,但可以添加新对象并切换索引引用;您不能更改提交的引用。其效果是,提交中的文件被冻结,而提交中的文件被冻结。)索引已解冻/可写。)
这种仅限Git的内部文件格式对您、用户和计算机上的大多数程序都没有用处。所以这些文件必须展开。它们会扩展到您的工作树中,该工作树位于可能有子目录(子文件夹)的目录(或文件夹)中。您可以将当前工作目录设置为这些工作树目录中的任何一个。然后,shell将展开*
,找到工作树中当前目录中的文件名
Git主要使用您当前的工作目录来查找存储库数据库,Git的真实文件所在的位置。工作树副本仅供您随意摆弄
一些Git命令确实使用工作树
当然,git checkout
和git add
都以各种方式使用工作树。但是,请注意,由于工作树供您使用,因此您可以将存储库本身不存在的文件放入其中
文件可以在工作树中,但不能在索引中。(实际上,索引位于“工作树”和存储库之间,并为Git提供了一个存储将进入下一次提交的文件的位置。)在工作树中处于这种状态但不在索引中的文件称为未跟踪
Git天生不知道未跟踪的文件。但是它们在您的工作树中(根据定义),因此如果这也是您当前的工作目录,并且您使用*
并让shell将*
扩展到
git xyzzy -- *
git checkout -- *