我是Git的新手,我有一个关于在Git中添加文件的问题。我发现了关于git add .和git add -a、git add --all、git add -a等之间的差异的多个stackoverflow问题,但我找不到一个解释git add *所做操作的地方。我甚至看过Git添加手册页,但没有用。我用它代替了git add .,我的同事问我为什么。我没有答案。我一直在用git add *。
git add .和git add *是否相同?一个只从当前目录添加更改的文件,而另一个只从当前目录和子目录添加文件(递归)?
在另一个堆栈问题中,有一个很好的图表列出了git add -agit add .和git add -u之间的区别,但没有git add *。
。
注意:我理解使用星号作为通配符意味着什么(添加具有给定扩展名的所有文件)。例如,git add *.html将添加所有扩展名为.html的文件(但忽略.css和.js等)。
谢谢你的帮助!
- 那张图表是从哪里来的?我又试了一次git add .,它把一个删除的文件放了出来,没问题,不像那一行的X所说的那样。
- @大卫,这张图片来自这个答案,适用于旧版本的Git。
- 图片过时了!git 2.x是不同的:i.stack.imgur.com/kvolu.jpg
add *表示添加当前目录中的所有文件,名称以点开头的文件除外。这是您的shell功能,Git只接收文件列表。
add .在shell中没有特殊的含义,因此git递归地添加整个目录,几乎相同,但包括名称以点开头的文件。
- 因此,git add .添加所有文件、文件夹和子文件夹,包括.gitignore和以点开头的任何其他内容,而git add *将添加除以点开头的文件、文件夹和子文件夹以外的任何文件、文件夹和子文件夹?那是准确的吗?
- 这确实是正确的。另外,如果文件在子目录中,git add *仍然会添加以点开头的文件。
- git add .也尊重.gitignore,而git add *会在任何非点文件被gitignore时抛出一个错误。使用git add .比git add *好得多。
- 测试-在我的情况下不准确-Git Add*适用于我的.htaces文件-有什么想法吗?
- @Radmation,这可能是因为目录中没有其他文件。如果没有匹配的文件,则shell不会展开"*"。然后,Git用不同的规则自行扩展它,忽略了前导点。
- @丹尼斯在这个目录中有很多文件,包括index.php页面和许多其他目录以及其他目录。
- @如果没有看到你的设置和手动调查,我就没有进一步的假设了。对不起的。:)
- 值得注意的是:如果从cmd.exe在DOS/Windows上调用git,则扩展*的是git,而不是shell。在这种情况下,Git会找到点文件。
- @这是因为Windows不考虑隐藏点文件。cmd可能不包括具有hidden属性的文件,但我不使用它,因此无法验证。
- @thor84no:git甚至可以在Linux系统上找到点文件,如果您引用*来保护它不受shell的攻击。这不是隐藏位的问题,只是Git的编译规则不同。
*不是git的一部分,它是shell解释的通配符。*扩展到当前目录中的所有文件,然后才传递给git,git是add的全部文件。.是当前目录本身,git add将添加它和它下面的所有文件。
- 那么,是否每个人都有理由使用星号?用它代替句号有什么好处吗?反之亦然?我肯定我在一个教程中看到过。否则我就不会使用它了。我不是什么命令行的人(毫无疑问,你已经猜到了)。
- *避免隐藏文件(即文件名以.开头的文件)。无论如何,如果你不添加特定的文件,我只使用git add -u或者git add -A,如果你创建新的文件。
- 既然你们都回答了我的问题,我就很难决定该把谁归功于我。我选择丹尼斯是因为他比你少。所以我想给他绿卡会比给你带来更多的好处。我希望这有道理?但我真的很欣赏这两种解释。谢谢!
在shell中使用dot .通常意味着"当前目录"。
在shell上使用星号*时,将使用名为file-globbing的功能。例如,在bash上,函数glob()就是这样做的。glob(man 7 glob版)的手册页说明:
DESCRIPTION
1 2 3 4
| Long ago, in UNIX V6, there was a program /etc/glob that would expand
wildcard patterns. Soon afterward this became a shell built-in.
These days there is also a library routine glob(3) that will perform this
function for a user program. |
Wildcard matching
1
| A string is a wildcard pattern if it contains one of the characters '?', '*' or '['. |
Globbing
1 2
| Globbing is the operation that expands a wildcard pattern
into the list of pathnames matching the pattern. |
号
这意味着,当您将参数传递给命令行上包含'?'、'*'或'['的任何程序时,首先全局化将通配符模式扩展为文件列表,然后将这些文件作为参数提供给程序本身。
丹尼斯清楚地描述了'git add .'和'git add *'之间的含义差异:
git add希望添加文件列表。在上面的例子中,shell分别展开*或.,并将结果作为git add的参数。现在的区别是,使用git add .git将扩展到当前目录,而git add *将触发文件全局化,这样扩展到所有不以点开头的文件和目录。
为了清楚起见,我将答案放在下表中:
。
附加说明(灵感来自@reka18评论):
注1。在没有附加参数的情况下执行的git add -A和git add -u命令将是整个工作目录范围内的附加优化(子目录或文件名的掩码指示)工作(如果我们在目录的工作子目录中执行该命令)。
注2..和*分别是目录路径(当前目录)和通配符,用于说明命令的路径。例如,如果在工作目录的某些子目录中执行git add .或git add *命令,那么它们的操作仅在该子目录中使用,而不是在整个工作目录中使用。
注3。通过为文件添加路径或掩码(例如,git add -A app/controllers或git add -u app\styles\*),可以进一步细化git add -A和git add -u命令。
- 那么,从git v2.x开始,git add -A和git add .是相同的?
- 谢谢你@reka18,有一个很好的问题。它激励我完成我的答案…回答您的问题:如果您在工作目录中调用它,则为否,但如果在子目录中调用它,则为是(git add -A适用于整个工作目录,git add .始终是当前目录)。