简体   繁体   English

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

[英]Difference between "git add -A" and "git add ."

What is the difference between git add [--all | -A] git add [--all | -A]之间有什么区别? git add [--all | -A] and git add. git add [--all | -A]git add. ?

This answer only applies to Git version 1.x .此答案仅适用于Git 版本 1.x For Git version 2.x, see other answers.对于 Git 版本 2.x,请参阅其他答案。


Summary:概括:

  • git add -A stages all changes git add -A阶段所有更改

  • git add . stages new files and modifications, without deletions (on the current directory and its subdirectories).暂存新文件和修改,不删除(在当前目录及其子目录上)。

  • git add -u stages modifications and deletions, without new files git add -u阶段修改和删除,没有新文件


Detail:细节:

git add -A is equivalent to git add .; git add -u git add -A相当于git add .; git add -u git add .; git add -u . git add .; git add -u

The important point about git add .关于git add . is that it looks at the working tree and adds all those paths to the staged changes if they are either changed or are new and not ignored, it does not stage any 'rm' actions.是它查看工作树并将所有这些路径添加到暂存更改中,如果它们已更改或是新的且未被忽略,它不会暂存任何“rm”操作。

git add -u looks at all the already tracked files and stages the changes to those files if they are different or if they have been removed. git add -u查看所有跟踪的文件,并暂存对这些文件的更改(如果它们不同或已被删除)。 It does not add any new files, it only stages changes to already tracked files.它不会添加任何新文件,它只会暂存对已跟踪文件的更改。

git add -A is a handy shortcut for doing both of those. git add -A是执行这两项操作的便捷快捷方式。

You can test the differences out with something like this (note that for Git version 2.x your output for git add . git status will be different):您可以使用类似这样的方法测试差异(请注意,对于 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 Version 1.x 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 Version 2.x 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仅暂存修改和删除的文件

Long-form flags:长格式标志:

  • git add -A is equivalent to git add --all git add -A相当于git add --all
  • git add -u is equivalent to git add --update git add -u相当于git add --update

Further reading:进一步阅读:

With Git 2.0, git add -A is default: git add .对于Git 2.0, git add -A是默认的: git add . equals git add -A . 等于git add -A . . .

git add <path> is the same as " git add -A <path> " now, so that " git add dir/ " will notice paths you removed from the directory and record the removal. git add <path>现在与“ git add -A <path> ”相同,因此“ git add dir/ ”会注意到您从目录中删除的路径并记录删除。
In older versions of Git, " git add <path> " ignored removals.在旧版本的 Git 中,“ git add <path> ”会忽略删除。

You can say " git add --ignore-removal <path> " to add only added or modified paths in <path> , if you really want to.如果你真的想要的话,你可以说“ git add --ignore-removal <path> ”来在<path>中只添加添加或修改的路径。

git add -A is like git add :/ ( add everything from top git repo folder ). git add -A就像git add :/添加顶部 git repo 文件夹中的所有内容)。
Note that git 2.7 (Nov. 2015) will allow you to add a folder named " : "!请注意,git 2.7(2015 年 11 月)将允许您添加一个名为“ : ”的文件夹!
See commit 29abb33 (25 Oct 2015) by Junio C Hamano ( gitster ) .请参阅Junio C Hamano ( gitster )提交 29abb33 (2015 年 10 月 25 日)。


Note that starting git 2.0 (Q1 or Q2 2014) , when talking about git add .请注意,在谈论git add .时, 开始 git 2.0 (Q1 or Q2 2014) (current path within the working tree), you must use ' . (工作树中的当前路径),您必须使用 ' . ' in the other git add commands as well. ' 在其他git add命令中也是如此。

That means:这意味着:

" git add -A . " is equivalent to " git add .; git add -u . " git add -A . ”等价于“ git add .; git add -u .

(Note the extra ' . ' for git add -A and git add -u ) (注意git add -Agit add -u的额外“ . ”)

Because git add -A or git add -u would operate (starting git 2.0 only) on the entire working tree , and not just on the current path.因为git add -Agit add -u将在整个工作树上运行(仅启动 git 2.0),而不仅仅是在当前路径上。

Those commands will operate on the entire tree in Git 2.0 for consistency with " git commit -a " and other commands .这些命令将在 Git 2.0 中对整个树进行操作,以与“ git commit -a ”和其他命令保持一致 Because there will be no mechanism to make " git add -u " behave as if " git add -u . ", it is important for those who are used to " git add -u " (without pathspec) updating the index only for paths in the current subdirectory to start training their fingers to explicitly say " git add -u . " when they mean it before Git 2.0 comes.因为没有机制可以使“ git add -u ”表现得像“ git add -u . ”,所以对于那些习惯于“ git add -u ”(没有路径规范)的人来说,只为路径更新索引很重要在当前子目录中开始训练他们的手指在 Git 2.0 到来之前明确说出“ git add -u . ”。

A warning is issued when these commands are run without a pathspec and when you have local changes outside the current directory , because the behaviour in Git 2.0 will be different from today's version in such a situation.当这些命令在没有路径规范的情况下运行并且当您在当前目录之外进行本地更改时会发出警告,因为在这种情况下 Git 2.0 中的行为将与今天的版本不同。

From Charles' instructions , after testing my proposed understanding would be as follows:根据查尔斯的指示,经过测试,我提出的理解如下:

# 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

This blog post might also be helpful to understand in what situation those commands may be applied: Removing Deleted Files from your Git Working Directory .这篇博文也可能有助于了解在什么情况下可以应用这些命令: Removing Deleted Files from your Git Working Directory

Things changed with Git 2.0 ( 2014-05-28 ): Git 2.0 ( 2014-05-28 ) 改变了一切

  • -A is now the default -A现在是默认值
  • The old behavior is now available with --ignore-removal .旧行为现在可以通过--ignore-removal获得。
  • git add -u and git add -A in a subdirectory without paths on the command line operate on the entire tree. git add -ugit add -A在没有命令行路径的子目录中对整个树进行操作。

So for Git 2 the answer is:所以对于 Git 2,答案是:

  • git add . and git add -A .git add -A . add new/modified/deleted files in the current directory在当前目录中添加新的/修改的/删除的文件
  • git add --ignore-removal . adds new/modified files in the current directory在当前目录中添加新的/修改的文件
  • git add -u . adds modified/deleted files in the current directory在当前目录中添加修改/删除的文件
  • Without the dot, add all files in the project regardless of the current directory.如果没有点,则添加项目中的所有文件,而不考虑当前目录。

In Git 2.x :Git 2.x中:

  • If you are located directly at the working directory , then git add -A and git add .如果您直接位于工作目录,那么git add -Agit add . work without the difference.工作没有区别。

  • If you are in any subdirectory of the working directory , git add -A will add all files from the entire working directory , and git add .如果您在工作目录的任何子目录中, git add -A将添加整个工作目录中的所有文件,然后git add . will add files from your current directory .将从您的当前目录添加文件。

And that's all.就这样。

A more distilled quick answer:一个更精炼的快速答案:

Does both below (same as git add --all )两者都在下面(与git add --all相同)

git add -A

Stages new + modified files暂存新文件 + 修改文件

git add .

Stages modified + deleted files阶段修改+删除文件

git add -u

Both git add .两者都git add . and git add -A will stage all new, modified and deleted files in the newer versions of Git.并且git add -A将在较新版本的 Git 中暂存所有新的、修改的和删除的文件。

The difference is that git add -A stages files in "higher, current and subdirectories" that belong to your working Git repository.不同之处在于git add -A在属于您的工作 Git 存储库的“更高、当前和子目录”中暂存文件。 But doing a git add .但是做一个git add . only stages files in the current directory and subdirectories following it ( not the files lying outside, ie, higher directories).仅暂存当前目录和其后的子目录中的文件(而不是位于外部的文件,即更高的目录)。

Here's an example:这是一个例子:

/my-repo
  .git/
  subfolder/
    nested-file.txt
  rootfile.txt

If your current working directory is /my-repo , and you do rm rootfile.txt , then cd subfolder , followed by git add .如果您当前的工作目录是/my-repo ,并且您执行rm rootfile.txt ,那么cd subfolder ,然后是git add . , then it will not stage the deleted file. ,那么它不会暂存已删除的文件。 But doing git add -A will certainly stage this change no matter where you perform the command from.但是无论您从哪里执行命令,执行git add -A肯定会进行此更改。

git add . equals git add -A .等于git add -A . adds files to index only from current and children folders.仅从当前文件夹和子文件夹将文件添加到索引。

git add -A adds files to index from all folders in working tree. git add -A将文件添加到工作树中所有文件夹的索引中。

PS: information relates to Git 2.0 (2014-05-28). PS:信息与Git 2.0 (2014-05-28) 有关。

I hope this may add some more clarity.我希望这可以增加一些清晰度。

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

Limiters may be -u or -A or nil.限制器可以是 -u 或 -A 或 nil。

Pathspec may be a filepath or dot, '.' Pathspec 可以是文件路径或点,'.' to indicate the current directory.表示当前目录。

Important background knowledge about how Git 'adds':关于 Git 如何“添加”的重要背景知识:

  • Invisible files, those prefixed with a dot, (dotfiles) are never automatically recognized by Git. Git 永远不会自动识别那些以点为前缀的不可见文件(dotfiles)。 They are never even listed as 'untracked'.它们甚至从未被列为“未跟踪”。
  • Empty folders are never added by Git. Git 从不添加空文件夹。 They are never even listed as 'untracked'.它们甚至从未被列为“未跟踪”。 (A workaround is to add a blank file, possibly invisible, to the tracked files.) (一种解决方法是在跟踪文件中添加一个可能不可见的空白文件。)
  • Git status will not display subfolder information, that is, untracked files, unless at least one file in that subfolder is tracked. Git状态不会显示子文件夹信息,即未跟踪的文件,除非该子文件夹中至少有一个文件被跟踪。 Before such time, Git considers the entire folder out of scope, a la 'empty'.在此之前,Git 将整个文件夹视为超出范围,即“空”。 It is empty of tracked items.它没有被跟踪的项目。
  • Specifying a filespec = '.'指定文件规范 = '.' (dot), or the current directory, is not recursive unless -A is also specified. (点)或当前目录不是递归的,除非还指定了-A Dot refers strictly to the current directory - it omits paths found above and below.点严格指当前目录 - 它省略了在上面和下面找到的路径。

Now, given that knowledge, we can apply the answers above.现在,鉴于这些知识,我们可以应用上面的答案。

The limiters are as follows.限制器如下。

  • -u = --update = subset to tracked files => Add = No; -u = --update = 跟踪文件的子集 => 添加 = 否; Change = Yes;改变 = 是; Delete = Yes.删除 = 是。 => if the item is tracked. =>如果项目被跟踪。
  • -A = --all (no such -a , which gives syntax error) = superset of all untracked/tracked files , unless in Git before 2.0, wherein if the dot filespec is given, then only that particular folder is considered. -A = --all (没有这样的-a ,它给出语法错误)= 所有未跟踪/跟踪文件的超集,除非在 2.0 之前的 Git 中,其中如果给出了点文件规范,则只考虑该特定文件夹。 => if the item is recognized, git add -A will find it and add it. =>如果项目被识别, git add -A会找到它并添加它。

The pathspec is as follows.路径规范如下。

  • In Git before 2.0, for the two limiters (update and all), the new default is to operate on the entire working tree, instead of the current path (Git 1.9 or earlier),在 Git 2.0 之前的版本中,对于两个限制器(update 和 all),新的默认是对整个工作树进行操作,而不是当前路径(Git 1.9 或更早版本),
  • However, in v2.0, the operation can be limited to the current path: just add the explicit dot suffix (which is also valid in Git 1.9 or earlier);但是在 v2.0 中,可以将操作限制在当前路径:只需添加显式点后缀即可(这在 Git 1.9 或更早版本中也有效);

git add -A .

git add -u .

In conclusion, my policy is:总之,我的政策是:

  1. Ensure any hunks/files to be added are accounted for in git status .确保要添加的任何块/文件都包含在git status中。
  2. If any items are missing, due to invisible files/folders, add them separately.如果由于不可见的文件/文件夹而缺少任何项目,请单独添加它们。
  3. Have a good .gitignore file so that normally only files of interest are untracked and/or unrecognized.拥有一个良好的.gitignore文件,以便通常只有感兴趣的文件未被跟踪和/或无法识别。
  4. From the top level of the repository, "git add -A" to add all items.从存储库的顶层,“git add -A”添加所有项目。 This works in all versions of Git.这适用于所有版本的 Git。
  5. Remove any desired items from the index if desired.如果需要,从索引中删除任何所需的项目。
  6. If there is a big bug, do 'git reset' to clear the index entirely.如果有大错误,请执行“git reset”以完全清除索引。

The -A option adds, modifies, and removes index entries to match the working tree. -A选项添加、修改和删除索引条目以匹配工作树。

In Git 2 the -A option is now the default.在 Git 2 中, -A选项现在是默认选项。

When a .当一个. is added that limits the scope of the update to the directory you are currently in, as per the Git documentation根据Git 文档,添加了将更新范围限制为您当前所在目录的内容

If no <pathspec> is given when -A option is used, all files in the entire working tree are updated (old versions of Git used to limit the update to the current directory and its subdirectories).如果在使用 -A 选项时没有给出<pathspec> ,则整个工作树中的所有文件都会被更新(旧版本的 Git 用于限制对当前目录及其子目录的更新)。

One thing that I would add is that if the --interactive or -p mode is used then git add will behave as if the update ( -u ) flag was used and not add new files.我要补充的一件事是,如果使用--interactive-p模式,那么git add将表现得好像使用了更新( -u )标志而不是添加新文件。

It's useful to have descriptions of what each flag does.描述每个标志的作用很有用。 By using a CLI like bit you'll have access to flag descriptions as you're typing.通过使用类似bit的 CLI,您可以在键入时访问标志描述。

I hate the staging mechanism of git, which can not be found in other SCM tools.我讨厌 git 的 staging 机制,这是其他 SCM 工具中找不到的。 So I always use:所以我总是使用:

\git add --all && \git commit --all

(Even though with \git add --all , \git commit is enough) (即使使用\git add --all\git commit就足够了)


for add : add

--no-ignore-removal  --all     | add, modify, and remove index entries to match the working tree
--ignore-removal     --no-all  | add, modify             index entries to match the working tree

--intent-to-add                | add an entry for the path to the index,  with no content

-A is short for --all -A--all的缩写

git add <pathspec> equals to: git add <pathspec>等于:

for version 2.35.1 of Git: git add --all <pathspec>对于 Git 2.35.1 版本: git add --all <pathspec>
Older versions of Git: git add --no-all <pathspec>旧版本的 Git: git add --no-all <pathspec>

But git add followed by nothing, does not equal to git add --all , and will do nothing:但是git add后跟什么都不做,不等于git add --all ,并且什么都不做:

在此处输入图像描述

git add --all (omitting <pathspec> ): handle all files in the entire working tree (old versions of Git used to limit the update to the current directory and its subdirectories). git add --all (省略<pathspec> ):处理整个工作树中的所有文件(旧版本的 Git 用于限制对当前目录及其子目录的更新)。

git commit --all git commit --all

Tell the command to automatically stage files that have been modified and deleted,.告诉命令自动暂存已修改和删除的文件。 new files you have not told Git about are not affected你没有告诉 Git 的新文件不受影响

Some explanations here are not valid in new versions of git.这里的一些解释在git的新版本中是无效的。

git v2.39 (Currently this version is latest - 11 January 2023): git v2.39(目前这个版本是最新的——2023年1月11日):

在此处输入图像描述

我在解释中使用了什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM