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

Posted

技术标签:

【中文标题】“git add -A”和“git add”之间的区别。【英文标题】:Difference between "git add -A" and "git add ." 【发布时间】:2010-10-09 00:33:28 【问题描述】:

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

【问题讨论】:

【参考方案1】:

此答案仅适用于 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 add *的区别呢? 太糟糕了 git add -A -p 无法正常工作(以交互方式询问未跟踪的文件) 请更新答案。应该是:git add -A :/git add -A . 有关信息,在较新版本的 git 中,git add -u 已变为 git add -u :/,后一个参数是路径,允许您 -u 某些目录,:/ 处理整个树。跨度> @CharlesBailey,Git 真的喜欢无缘无故地让事情变得复杂。是否有一个真正的用例,其中某人会特别需要git add -ugit add .,这样做会让他的生活更轻松,即使在考虑了额外的心理税以确保没有同步问题?我想知道为什么 Git 不进一步将 add -u 拆分为两个单独的命令 add -u1add-u2,其中一个适用于以数字开头的文件,另一个适用于以非数字开头的文件【参考方案2】:

Git 版本 1.x

Command New Files Modified Files Deleted Files Description
git add -A ✔️ ✔️ ✔️ Stage all (new, modified, deleted) files
git add . ✔️ ✔️ Stage new and modified files only in current folder
git add -u ✔️ ✔️ Stage modified and deleted files only

Git 版本 2.x

Command New Files Modified Files Deleted Files Description
git add -A ✔️ ✔️ ✔️ Stage all (new, modified, deleted) files
git add . ✔️ ✔️ ✔️ Stage all (new, modified, deleted) files in current folder
git add --ignore-removal . ✔️ ✔️ Stage new and modified files only
git add -u ✔️ ✔️ Stage modified and deleted files only

长格式标志:

git add -A 等价于 git add --all git add -u 等价于 git add --update

延伸阅读:

Git for beginners: The definitive practical guide Resources to learn Git Learn Git Branching Explain Git With D3

【讨论】:

感谢您的餐桌。有没有办法只添加修改过的文件。没有新文件或已删除文件 @Gokul:根据this post,您可以使用git diff-files -z --diff-filter=M --name-only | xargs -0 git add只添加修改过的文件,不能添加新文件或删除的文件。 这并不完全正确,因为git add . 只会添加当前路径上的新文件。 IE。如果你有一个新目录../foogit add -A 会暂存它,git add . 不会。 所以,git add .等价于git add -A .,也就是等价于git add "*" 我仍然对 git add "*" 感到困惑,你能详细说明一下吗?【参考方案3】:

Git 2.0, git add -A is default: git add . equals git 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 :/ (add everything from top git repo folder)。 请注意,git 2.7(2015 年 11 月)将允许您添加一个名为“:”的文件夹! 见commit 29abb33(2015 年 10 月 25 日)Junio C Hamano (gitster)。


注意starting git 2.0 (Q1 or Q2 2014),在谈到git add .(工作树中的当前路径)时,您也必须在其他git add 命令中使用'.'。

这意味着:

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

(注意git add -Agit 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”(没有路径规范)的人来说,只为当前子目录中的路径更新索引很重要开始训练他们的手指在 Git 2.0 到来之前明确说出“git add -u .”。

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

【讨论】:

@NickVolynkin 太好了!很高兴看到 SO 的国际社区按预期工作。供参考:ru.***.com/a/431840 @VonC,很好,Git 人实际上厚着脸皮说他们的更新将“使事情更加一致”。他们的所作所为造成了更多的混乱和不一致。有 26 个字母,他们不得不重新使用已经使用过的标志。【参考方案4】:

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

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

P.S.:信息与 Git 2.0 (2014-05-28) 有关。

【讨论】:

【参考方案5】:

Things changed 与 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 .在当前目录添加修改/删除的文件 不加点,添加项目中的所有文件,不管当前目录。

【讨论】:

我不认为这是正确的。使用 git v2.10.windows.2 'git add' 返回“未指定,未添加任何内容”。 'git add -A' 添加所有更改的文件。这表明“-A”不是默认值。 最后一点“不带点,不管当前目录如何,添加项目中的所有文件。”不起作用。当我说 codegit addcode (不带 .)时,对于带有提示的消息,指定我是否想说 codegit add 。 代码【参考方案6】:

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 肯定会进行此更改。

【讨论】:

【参考方案7】:

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

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

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

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

我要补充的一件事是,如果使用 --interactive-p 模式,那么 git add 的行为就像使用了更新 (-u) 标志,而不是添加新文件。

【讨论】:

【参考方案8】:

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

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

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

Pathspec 可以是文件路径或点,'.'表示当前目录。

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

Git 永远不会自动识别那些以点为前缀的不可见文件(点文件)。它们甚至从未被列为“未追踪”。 Git 永远不会添加空文件夹。它们甚至从未被列为“未跟踪”。 (解决方法是在跟踪文件中添加一个可能不可见的空白文件。) Git status 不会显示子文件夹信息,即未跟踪的文件,除非该子文件夹中至少有一个文件被跟踪。在此之前,Git 将整个文件夹视为超出范围,即“空”。它没有被跟踪的项目。 指定文件规范 = '.' (点)或当前目录不是递归的,除非还指定了-A。点严格指当前目录 - 它省略了在上面和下面找到的路径。

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

限制器如下。

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

pathspec如下。

在 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”以完全清除索引。

【讨论】:

【参考方案9】:

更简洁的快速回答:

是否两者都在下面(与 git add --all 相同)

git add -A

阶段新的 + 修改的文件

git add .

阶段修改+删除文件

git add -u

【讨论】:

您好,如果您只想暂存修改过的文件怎么办?你会怎么做? 你好,好问题。据我所知,没有一个简单的标志.. git diff-files -z --diff-filter=M --name-only | xargs -0 git add from -> ***.com/questions/14368093/… 其实是git add :/ + git add -u :/【参考方案10】:

来自Charles' instructions,经过测试我提出的理解如下:

# 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

【讨论】:

这在 2.0 中不再适用。添加 。等于为同一路径添加-A,唯一的区别是树的其他路径中是否有新文件【参考方案11】:

Git 2.x 中:

如果您直接位于工作目录,那么git add -Agit add . 可以正常工作。

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

仅此而已。

【讨论】:

以上是关于“git add -A”和“git add”之间的区别。的主要内容,如果未能解决你的问题,请参考以下文章

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

git add -A /git add -u/git add .的用法

git checkout .和git checkout -f的区别;git add . git add -u git add -A的区别

git checkout .和git checkout -f的区别;git add . git add -u git add -A的区别

git add -A 和 git add . 的区别

git add -A 和 git add . 的区别