2024-10-02 08:14:36 发布
网友
我在Django项目中初始化了一个新的git回购。所有文件(包括子目录和pipfile中的文件)都是在我运行git add*时暂存的,除了\u atomic-writegxd2tirf文件。为什么这个被排除在外
现在,您已经通过几个不同的命令(特别是git add和echo)体验到了这一点,是时候进行概括了
git add
echo
在类Unix系统(包括Linux、macOS终端windows等)上,或者在windows上使用bash作为命令解释器时,您使用的是一种称为shell的编程语言。有不同的shell编程语言(bash、dash、sh、zsh、fish等等,出于历史原因,大多数都倾向于在名称中使用sh),但它们都倾向于共享某些属性。其中之一是它们如何扩展要传递给命令的命令行参数
bash
sh
$ mkdir t && cd t && touch .a .b c d e $ ls -A .a .b c d e $ echo * c d e
在这个临时目录中有五个文件1(除了标准的两个名为.和..的文件ls -A省略)。但是echo *只扩展到其中三个。这是因为*扩展故意忽略了名称2以.开头的任何文件
.
..
ls -A
echo *
*
有些shell有一个选项可以打开或关闭此选项:例如,在bash中,可以设置dotglob选项。(用户可能不应该过多地摆弄这些选项,以免在使用其他人的shell或其他shell时感到意外,但最好知道它们的存在。)
dotglob
Shell编程语言主要是围绕运行其他程序的思想而构建的。因此,当shell生成一个提示符,如$或>或shell的标准提示符,并且您键入一系列空格分隔的单词时,shell会将这些单词拆分,并将其中一个用作命令名,其余部分用作命令的参数,然后运行该命令。因此,输入:
$
>
git add *
让shell运行带有参数add和*的git命令。但是*本身被shell特别处理,扩展为文件名,不包括以点开头的文件名。因此git命令只能看到参数:
add
git
add c d e
(每行一个参数)。git的第一个参数是子命令,在本例中是add,其余参数由子命令解释。3
由于*被shell扩展,Git从来没有看到过*,也从来没有机会用*做自己的事情。但是,您可以保护*不受shell的影响:
在这里,shell将双引号视为一种保护。这使得shell无法解释*。shell本身解释了双引号,因此echo没有看到双引号。它只看到星号*
$ echo '"*"' "*"
这次我使用单引号作为外层。它们还告诉shell保护内容,即不要解释双引号或星号。所以这次echo看到了双引号和星号
shell的引用规则因shell而异,这可能会变得非常复杂。所有这些都与Git本身无关:不管运行哪个命令,shell都在执行相同的解释
如果您确实设法将文字星号传递给Git,Git将自己解释星号,并且它的解释不同于shell。因此git add '*'的行为不同
git add '*'
如果您使用Windows和CMD.EXE,请注意CMD.EXE本身的可编程性不如shell,并且具有更简单的命令行规则。在某些方面,这使得它的使用更容易和更可预测。这是它的优点,也是它的缺点:典型Unix shell的可编程性使使用它们编写整个系统成为可能
CMD.EXE
1在Unix世界中,即使是目录(或文件夹,如果您喜欢该术语)也是一种文件。有时人们用file这个词来表示文件和目录,但因为我排除了.和..,这是目录文件,除了这个脚注,我不需要再提它了
2在类似Unix系统的分层文件系统中,文件不一定只有一个名称。这里,单词name实际上是指在一些包含目录中找到的组件名。例如,Git中的文件名可能是path/to/.file。但是,在Unix文件系统级别,这是一个名为path的目录,其中包含一个名为to的目录,其中包含一个组件名为.file的文件。对于shell,文件名的末尾部分有一个点,因此echo path/to/*将不匹配它
path/to/.file
path
to
.file
echo path/to/*
3这种将顶级命令与子命令结合使用的模式最近变得越来越普遍,但只有部分Unix系统是这样工作的。特别是在Python中,您可以使用argparse来模拟这种行为
argparse
git add*只处理名称不以“”开头的文件。 另一种方法可以是对所有文件运行git add.,或者对以“”(点)开头的文件名运行git add
现在,您已经通过几个不同的命令(特别是
git add
和echo
)体验到了这一点,是时候进行概括了在类Unix系统(包括Linux、macOS终端windows等)上,或者在windows上使用
bash
作为命令解释器时,您使用的是一种称为shell的编程语言。有不同的shell编程语言(bash、dash、sh、zsh、fish等等,出于历史原因,大多数都倾向于在名称中使用sh
),但它们都倾向于共享某些属性。其中之一是它们如何扩展要传递给命令的命令行参数在这个临时目录中有五个文件1(除了标准的两个名为
.
和..
的文件ls -A
省略)。但是echo *
只扩展到其中三个。这是因为*
扩展故意忽略了名称2以.
开头的任何文件有些shell有一个选项可以打开或关闭此选项:例如,在bash中,可以设置
dotglob
选项。(用户可能不应该过多地摆弄这些选项,以免在使用其他人的shell或其他shell时感到意外,但最好知道它们的存在。)Shell编程语言主要是围绕运行其他程序的思想而构建的。因此,当shell生成一个提示符,如
$
或>
或shell的标准提示符,并且您键入一系列空格分隔的单词时,shell会将这些单词拆分,并将其中一个用作命令名,其余部分用作命令的参数,然后运行该命令。因此,输入:让shell运行带有参数
add
和*
的git
命令。但是*
本身被shell特别处理,扩展为文件名,不包括以点开头的文件名。因此git
命令只能看到参数:(每行一个参数)。
git
的第一个参数是子命令,在本例中是add
,其余参数由子命令解释。3由于
*
被shell扩展,Git从来没有看到过*
,也从来没有机会用*
做自己的事情。但是,您可以保护*
不受shell的影响:在这里,shell将双引号视为一种保护。这使得shell无法解释
*
。shell本身解释了双引号,因此echo
没有看到双引号。它只看到星号*
这次我使用单引号作为外层。它们还告诉shell保护内容,即不要解释双引号或星号。所以这次
echo
看到了双引号和星号shell的引用规则因shell而异,这可能会变得非常复杂。所有这些都与Git本身无关:不管运行哪个命令,shell都在执行相同的解释
如果您确实设法将文字星号传递给Git,Git将自己解释星号,并且它的解释不同于shell。因此
git add '*'
的行为不同如果您使用Windows和
CMD.EXE
,请注意CMD.EXE
本身的可编程性不如shell,并且具有更简单的命令行规则。在某些方面,这使得它的使用更容易和更可预测。这是它的优点,也是它的缺点:典型Unix shell的可编程性使使用它们编写整个系统成为可能1在Unix世界中,即使是目录(或文件夹,如果您喜欢该术语)也是一种文件。有时人们用file这个词来表示文件和目录,但因为我排除了
.
和..
,这是目录文件,除了这个脚注,我不需要再提它了2在类似Unix系统的分层文件系统中,文件不一定只有一个名称。这里,单词name实际上是指在一些包含目录中找到的组件名。例如,Git中的文件名可能是
path/to/.file
。但是,在Unix文件系统级别,这是一个名为path
的目录,其中包含一个名为to
的目录,其中包含一个组件名为.file
的文件。对于shell,文件名的末尾部分有一个点,因此echo path/to/*
将不匹配它3这种将顶级命令与子命令结合使用的模式最近变得越来越普遍,但只有部分Unix系统是这样工作的。特别是在Python中,您可以使用
argparse
来模拟这种行为git add*只处理名称不以“”开头的文件。 另一种方法可以是对所有文件运行git add.,或者对以“”(点)开头的文件名运行git add
相关问题 更多 >
编程相关推荐