“ git add -A”和“ git add”之间的区别


2917

该命令git add [--all|-A]似乎与相同git add .。它是否正确?如果没有,它们有何不同?

Answers:


4240

这个答案只适用于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

41
两者之间的区别如何git add *
Jared

3
太糟糕了git add -A -p,无法按预期工作(以交互方式询问未跟踪的文件)
Erik Kaplun 2014年

2
请更新答案。应该是:git add -A :/git add -A .
Gabriel Llamas 2014年

5
有关信息,在较新版本的git git add -ugit add -u :/,后一个参数是路径,允许您-u某些目录,:/处理整个树。
Brizee 2014年

15
@ CharlesBailey,Git非常喜欢无缘无故地使事情变得复杂。是否存在一个真正的用例,某个人会特别需要它,git add -u或者git add .这样做,即使考虑了为确保没有同步问题而增加的额外精神税,也使他的生活更加轻松?我不知道为什么Git不会再分解add -u为两个单独的命令add -u1add-u2而一个命令适用于以数字开头的文件,而另一个命令适用于非数字开头的文件
Pacerier,2015年

946

这是用于快速了解的表格:

Git版本1.x

在此处输入图片说明

Git版本2.x

在此处输入图片说明

长格式标志:

  • git add -A 相当于 git add --all
  • git add -u 相当于 git add --update

进一步阅读:


1
谢谢你的桌子。有没有一种方法可以仅添加已修改的文件。没有新文件或已删除文件
Gokul NK 2015年

3
@Gokul:根据这篇文章,您可以git diff-files -z --diff-filter=M --name-only | xargs -0 git add用来仅添加修改后的文件,而不能添加新文件或删除文件。
维尔(Ville)

93
这并非完全正确,因为git add .仅添加当前路径上的新文件。即,如果您有一个新目录../foogit add -A将暂存该目录,否则git add .将不会。
Milo Wielondek

2
因此,git add .等价于git add -A .,等价于git add "*"
flow2k

我仍然对git add“ *”感到困惑,请您再详细说明一下吗?
HS Umer farooq,

176

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(2014年第一季度或2014年第二季度)开始,当谈论git add .(工作树中的当前路径)时,您还必须.在其他git add命令中使用' 。

这意味着:

git add -A .”等同于“ git add .; git add -u .

(请注意,额外的.' git add -A和和git add -u

因为git add -Agit add -u会在整个工作树上(而不是仅在当前路径上)运行(仅启动git 2.0)。

这些命令将在Git 2.0中的整个树上运行,以与“ git commit -a”和其他命令保持一致。因为没有机制使“ git add -u”行为像“ git add -u .”,所以对于习惯于“git add -u(没有pathspec)仅更新当前子目录中路径的索引的要开始训练他们的手指明确说出“ git add -u .“当他们在Git 2.0出现之前就说了这句话。

当这些命令在没有路径规范的情况下运行并且在当前目录之外进行本地更改时,将发出警告,因为在这种情况下,Git 2.0中的行为将不同于今天的版本。


3
@NickVolynkin太好了!很高兴看到SO国际社会按预期工作。供参考:ru.stackoverflow.com/a/431840
VonC

@VonC,尼斯,Git员工实际上很高兴地说他们的更新将“使事情更加一致”。他们所做的事情造成了更多的混乱和矛盾。有26个字母,它们不得不重用已经使用的标志。
2015年

136

根据查尔斯的指示,经过测试,我的理解如下:

# 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

这篇博客文章也可能有助于理解在什么情况下可以应用这些命令:从Git Working Directory中删除已删除的文件


6
在2.0中不再如此。添加。等于为同一路径添加-A,唯一的区别是树的其他路径中是否有新文件
Claudiu Creanga

41

Git 2.0(2014-05-28改变事情

  • -A 现在是默认值
  • 现在可以使用来执行以前的行为--ignore-removal
  • git add -ugit add -A在命令行上没有路径的子目录中对整个树进行操作。

因此对于Git 2,答案是:

  • git add .git add -A .在当前目录中添加新的/修改的/删除的文件
  • git add --ignore-removal . 在当前目录中添加新文件/修改过的文件
  • git add -u . 在当前目录中添加修改/删除的文件
  • 不带点,请添加项目中的所有文件,而不管当前目录如何。

4
我认为这是不正确的。使用git v2.10.windows.2'git add'返回'未指定内容,未添加内容'。'git add -A'添加所有更改的文件。这表明“ -A”不是默认值。
中微子

34

一个更简化的快速答案:

在下面都做(与git add --all一样

git add -A

暂存新文件和修改过的文件

git add .

阶段修改和删除文件

git add -u

5
您好,如果您只想暂存修改过的文件怎么办?你会怎么做?
TheGrapeBeyond

2
您好,很好的问题。据我所知,没有一个简单的标志。git diff-files -z --diff-filter = M --name-only | xargs的-0从GIT中添加- > stackoverflow.com/questions/14368093/...
K. Kilian的林德伯格

2
实际上是git add :/+git add -u :/
Nick Volynkin

27

Git 2.x中

  • 如果您直接位于工作目录,那么git add -Agit add .工作没有区别。

  • 如果您在工作目录的任何子目录中,git add -A则将添加整个工作目录中的所有文件,git add .并将添加当前目录中的文件。

就这样。


12

我希望这可以增加一些清晰度。

!The syntax is
git add <limiters> <pathspec>
! Aka
git add (nil/-u/-A) (nil/./pathspec)

限制符可以是-u或-A或nil。

Pathspec可以是文件路径或点“。”。指示当前目录。

有关Git如何“添加”的重要背景知识:

  • Git永远不会自动识别以点为前缀的不可见文件(点文件)。他们甚至从未被列为“未跟踪”。
  • 空文件夹不会由Git添加。他们甚至从未被列为“未跟踪”。(一种解决方法是向跟踪的文件中添加一个可能不可见的空白文件。)
  • Git状态将不会显示子文件夹信息,即未跟踪的文件,除非已跟踪该子文件夹中的至少一个文件。在此之前,Git认为整个文件夹超出范围,称为“空”。它没有跟踪的项目。
  • 指定filespec ='。除非-A也指定,否则(点)或当前目录不是递归的。点严格指的是当前目录-它忽略了上下目录。

现在,有了这些知识,我们可以应用上面的答案。

限制器如下。

  • -u= --update=跟踪文件的子集=>添加=否;更改=是;删除=是。=> 是否跟踪该项目。
  • -A= --all(不这样-a,会导致语法错误)=所有未跟踪/已跟踪文件的超集,除非在2.0之前的Git中,如果给出了点filespec,则仅考虑该特定文件夹。=> 如果该项目被识别,git add -A将找到并添加它。

pathspec如下。

  • 在2.0之前的Git中,对于两个限制器(更新和全部),新的默认设置是对整个工作树进行操作,而不是对当前路径(Git 1.9或更早版本)进行操作,
  • 但是,在v2.0中,该操作可以限于当前路径:只需添加显式点后缀(在Git 1.9或更早版本中也有效);

git add -A .

git add -u .

总之,我的政策是:

  1. 确保要添加的所有块/文件都在 git status
  2. 如果由于看不见的文件/文件夹而缺少任何项目,请分别添加它们。
  3. 有良好的 .gitignore文件,以便通常仅关注和/或无法识别感兴趣的文件。
  4. 在存储库的顶层,使用“ git add -A”添加所有项目。这适用于所有版本的Git。
  5. 如果需要,请从索引中删除所有需要的项目。
  6. 如果存在大错误,请执行“ git reset”以完全清除索引。

12

git add .等于git add -A .仅将文件添加到当前文件夹和子文件夹中以建立索引。

git add -A 将文件添加到工作树中所有文件夹的索引中。

PS:与Git 2.0有关的信息(2014-05-28)。


9

两者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无论您从何处执行命令,执行操作都一定会登台此更改。


3

-A选项添加,修改和删除索引条目以匹配工作树。

在Git 2中,该-A选项现在是默认选项。

.根据Git文档,添加a 将更新范围限制为您当前所在的目录时

如果<pathspec>在使用-A选项时未给出任何值,则将更新整个工作树中的所有文件(旧版本的Git用于将更新限制为当前目录及其子目录)。

我要添加的一件事是,如果使用--interactive-p模式,git add则将表现为使用了update(-u)标志,而不添加新文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.