该命令git add [--all|-A]
似乎与 相同git add .
。它是否正确?如果不是,它们有何不同?
11 回答
此答案仅适用于Git 版本 1.x。对于 Git 版本 2.x,请参阅其他答案。
概括:
git add -A
阶段所有更改git add .
暂存新文件和修改,不删除(在当前目录及其子目录上)。git add -u
阶段修改和删除,没有新文件
细节:
git add -A
相当于 git add .; git add -u
。
重要的一点git add .
是,它查看工作树并将所有这些路径添加到暂存更改中,如果它们已更改或是新的且未被忽略,它不会暂存任何“rm”操作。
git add -u
查看所有已跟踪的文件并暂存对这些文件的更改(如果它们不同或已被删除)。它不会添加任何新文件,它只会暂存对已跟踪文件的更改。
git add -A
是做这两个的方便快捷方式。
您可以使用类似这样的方法测试差异(请注意,对于 Git 版本 2.x,您的输出git add .
git status
会有所不同):
git init
echo Change me > change-me
echo Delete me > delete-me
git add change-me delete-me
git commit -m initial
echo OK >> change-me
rm delete-me
echo Add me > add-me
git status
# Changed but not updated:
# modified: change-me
# deleted: delete-me
# Untracked files:
# add-me
git add .
git status
# Changes to be committed:
# new file: add-me
# modified: change-me
# Changed but not updated:
# deleted: delete-me
git reset
git add -u
git status
# Changes to be committed:
# modified: change-me
# deleted: delete-me
# Untracked files:
# add-me
git reset
git add -A
git status
# Changes to be committed:
# new file: add-me
# modified: change-me
# deleted: delete-me
Git 版本 1.x
命令 | 新文件 | 修改文件 | 已删除的文件 | 描述 |
---|---|---|---|---|
git add -A |
✔️ | ✔️ | ✔️ | 暂存所有(新的、修改的、删除的)文件 |
git add . |
✔️ | ✔️ | ❌</td> | 仅在当前文件夹中暂存新文件和修改文件 |
git add -u |
❌</td> | ✔️ | ✔️ | 仅暂存修改和删除的文件 |
Git 版本 2.x
命令 | 新文件 | 修改文件 | 已删除的文件 | 描述 |
---|---|---|---|---|
git add -A |
✔️ | ✔️ | ✔️ | 暂存所有(新的、修改的、删除的)文件 |
git add . |
✔️ | ✔️ | ✔️ | 在当前文件夹中暂存所有(新的、修改的、删除的)文件 |
git add --ignore-removal . |
✔️ | ✔️ | ❌</td> | 仅暂存新文件和修改后的文件 |
git add -u |
❌</td> | ✔️ | ✔️ | 仅暂存修改和删除的文件 |
长格式标志:
git add -A
相当于git add --all
git add -u
相当于git add --update
进一步阅读:
在Git 2.0 中,git add -A
默认值是:git add .
equalsgit add -A .
。
git add <path>
现在与“”相同git add -A <path>
,因此“git add dir/
”会注意到您从目录中删除的路径并记录删除。
在旧版本的 Git 中,"git add <path>
" 忽略删除。如果你真的想要,你可以说“
git add --ignore-removal <path>
”来只添加添加或修改的路径。<path>
git add -A
就像git add :/
(添加顶部 git repo 文件夹中的所有内容)。
请注意,git 2.7(2015 年 11 月)将允许您添加一个名为“ :
”的文件夹!
请参阅Junio C Hamano ( ) 的提交 29abb33(2015 年 10 月 25 日)。 gitster
请注意,从 git 2.0 (Q1 or Q2 2014) 开始,在谈论git add .
(工作树中的当前路径)时,您也必须.
在其他git add
命令中使用 ' '。
这意味着:
“
git add -A .
”等价于“git add .; git add -u .
”
(注意额外的 ' .
'git add -A
和git add -u
)
因为git add -A
or将在整个工作树上git add -u
运行(仅启动 git 2.0),而不仅仅是在当前路径上。
这些命令将在 Git 2.0 中对整个树进行操作,以与 "
git commit -a
" 和其他命令保持一致。因为没有机制让“git add -u
”表现得像“git add -u .
”,所以对于那些习惯于“git add -u
”(没有路径规范)只为当前子目录中的路径更新索引的人来说,重要的是开始训练他们的手指明确地说“git add -u .
“当他们在 Git 2.0 到来之前的意思时。当这些命令在没有路径规范的情况下运行并且当您在当前目录之外进行本地更改时会发出警告,因为在这种情况下 Git 2.0 中的行为将与今天的版本不同。
根据查尔斯的指示,经过测试,我提出的理解如下:
# For the next commit
$ git add . # Add only files created/modified to the index and not those deleted
$ git add -u # Add only files deleted/modified to the index and not those created
$ git add -A # Do both operations at once, add to all files to the index
这篇博文也可能有助于了解在什么情况下可以应用这些命令:Removing Deleted Files from your Git Working Directory。
Git 2.0 ( 2014-05-28 )改变了一切:
-A
现在是默认的- 旧行为现在可用于
--ignore-removal
. git add -u
并git add -A
在命令行上没有路径的子目录中对整个树进行操作。
所以对于 Git 2,答案是:
git add .
并git add -A .
在当前目录中添加新的/修改的/删除的文件git add --ignore-removal .
在当前目录中添加新的/修改的文件git add -u .
在当前目录中添加修改/删除的文件- 如果没有点,则添加项目中的所有文件,而不考虑当前目录。
在Git 2.x中:
如果您直接位于工作目录,那么
git add -A
和git add .
工作没有区别。如果您在工作目录的任何子目录中,将
git add -A
添加整个工作目录中的所有文件,git add .
并将添加当前目录中的文件。
就这样。
一个更精炼的快速答案:
两者都在下面(与git add --all相同)
git add -A
暂存新文件 + 修改文件
git add .
阶段修改+删除文件
git add -u
git add .
equalsgit add -A .
仅从当前文件夹和子文件夹将文件添加到索引。
git add -A
将文件添加到工作树中所有文件夹的索引。
PS:信息与Git 2.0 (2014-05-28) 有关。
两者都git add .
将git add -A
在较新版本的 Git 中暂存所有新的、修改的和删除的文件。
不同之处在于将git add -A
文件暂存到属于您的工作 Git 存储库的“更高、当前和子目录”中。但是git add .
只在当前目录和它之后的子目录中执行文件(而不是位于外部的文件,即更高的目录)。
这是一个例子:
/my-repo
.git/
subfolder/
nested-file.txt
rootfile.txt
如果您当前的工作目录是/my-repo
,并且您这样做了rm rootfile.txt
,那么cd subfolder
,后跟git add .
,那么它将不会暂存已删除的文件。但是,git add -A
无论您从哪里执行命令,都肯定会进行此更改。
我希望这可以增加一些清晰度。
!The syntax is
git add <limiters> <pathspec>
! Aka
git add (nil/-u/-A) (nil/./pathspec)
限制器可以是 -u 或 -A 或 nil。
Pathspec 可以是文件路径或点,'.' 表示当前目录。
关于 Git 如何“添加”的重要背景知识:
- Git 永远不会自动识别那些以点为前缀的不可见文件(dotfiles)。它们甚至从未被列为“未跟踪”。
- Git 从不添加空文件夹。它们甚至从未被列为“未跟踪”。(一种解决方法是在跟踪文件中添加一个可能不可见的空白文件。)
- Git状态不会显示子文件夹信息,即未跟踪的文件,除非该子文件夹中至少有一个文件被跟踪。在此之前,Git 将整个文件夹视为超出范围,即“空”。它没有被跟踪的项目。
- 指定文件规范 = '.' (点)或当前目录不是递归的,除非
-A
还指定。点严格指当前目录 - 它省略了在上面和下面找到的路径。
现在,鉴于这些知识,我们可以应用上面的答案。
限制器如下。
-u
=--update
= 跟踪文件的子集 => 添加 = 否;改变 = 是;删除 = 是。=>如果项目被跟踪。-A
=--all
(没有这样-a
,这会给出语法错误)=所有未跟踪/跟踪文件的超集,除非在 2.0 之前的 Git 中,其中如果给出了点文件规范,则只考虑该特定文件夹。=>如果该项目被识别,git add -A
将找到它并添加它。
路径规范如下。
- 在 Git 2.0 之前的版本中,对于两个限制器(update 和 all),新的默认是对整个工作树进行操作,而不是当前路径(Git 1.9 或更早版本),
- 但是在 v2.0 中,可以将操作限制在当前路径:只需添加显式点后缀即可(这在 Git 1.9 或更早版本中也有效);
git add -A .
git add -u .
总之,我的政策是:
- 确保要添加的任何块/文件都在
git status
. - 如果由于不可见的文件/文件夹而缺少任何项目,请单独添加它们。
- 拥有一个好的
.gitignore
文件,以便通常只有感兴趣的文件未被跟踪和/或无法识别。 - 从存储库的顶层,“git add -A”添加所有项目。这适用于所有版本的 Git。
- 如果需要,从索引中删除任何所需的项目。
- 如果有大错误,请执行“git reset”以完全清除索引。
该-A
选项添加、修改和删除索引条目以匹配工作树。
在 Git 2 中,该-A
选项现在是默认选项。
根据Git 文档,当.
添加限制更新范围到您当前所在的目录时
如果使用 -A 选项时给出 no
<pathspec>
,则更新整个工作树中的所有文件(旧版本的 Git 用于限制对当前目录及其子目录的更新)。
我要补充的一件事是,如果使用--interactive
or-p
模式,那么git add
将表现得好像使用了 update ( -u
) 标志而不添加新文件。