Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xcode/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
两者之间的区别。git中的(点)和*(星号)通配符_Git_Wildcard - Fatal编程技术网

两者之间的区别。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 -- *