问题
The command git add [--all|-A]
appears to be identical to git add .
. Is this correct? If not, how do they differ?
回答1:
This answer only applies to Git version 1.x. For Git version 2.x, see other answers.
Summary:
git add -A
stages all changesgit add .
stages new files and modifications, without deletionsgit add -u
stages modifications and deletions, without new files
Detail:
git add -A
is equivalent to git add .; git add -u
.
The important point about 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.
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. 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.
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 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
回答2:
Here is a table for quick understanding:
Git Version 1.x:
Git Version 2.x:
Long-form flags:
git add -A
is equivalent togit add --all
git add -u
is equivalent togit add --update
Further reading:
- Git for beginners: The definitive practical guide
- Got 15 minutes and want to learn Git? (in an interactive way)
- Learn Git Branching
- Explain Git With D3
回答3:
With Git 2.0, git add -A is default: git add . equals 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.
In older versions of Git, "git add <path>
" used to ignore removals.You can say "
git add --ignore-removal <path>
" to add only added or modified paths in<path>
, if you really want to.
git add
is like git add :/
(add everything from top git repo folder).
Note that git 2.7 (Nov. 2015) will allow you to add a folder named ":
"!
See commit 29abb33 (25 Oct 2015) by Junio C Hamano (gitster).
Note that starting git 2.0 (Q1 or Q2 2014), when talking about git add .
(current path within the working tree), you must use '.
' in the other git add
commands as well.
That means:
"
git add -A .
" is equivalent to "git add .; git add -u .
"
(Note the extra '.
' for git add -A
and git 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.
Those commands will operate on the entire tree in Git 2.0 for consistency with "
git commit -a
" and other commands. 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.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.
回答4:
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.
回答5:
A more distilled quick answer:
Does both below (same as git add --all)
git add -A
Stages new + modified files
git add .
Stages modified + deleted files
git add -u
回答6:
Things changed with Git 2.0:
-A
is now the default- The old behavior is now available with
--ignore-removal
. git add -u
andgit add -A
in a subdirectory without paths on the command line operate on the entire tree.
So for Git 2 the answer is:
git add .
andgit add -A .
add new/modified/deleted files in the current directorygit add --ignore-removal .
adds new/modified files in the current directorygit add -u .
adds modified/deleted files in the current directory- Without the dot, add all files in the project regardless of the current directory.
回答7:
In Git 2.x:
If you are located directly at the working directory, then
git add -A
andgit 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, andgit add .
will add files from your current directory.
And that's all.
回答8:
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.
Pathspec may be a filepath or dot, '.' to indicate the current directory.
Important background knowledge about how Git 'adds':
- Invisible files, those prefixed with a dot, (dotfiles) are never automatically recognized by Git. They are never even listed as 'untracked'.
- Empty folders are never added by 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. Before such time, Git considers the entire folder out of scope, a la 'empty'. It is empty of tracked items.
- Specifying a filespec = '.' (dot), or the current directory, is not recursive unless
-A
is also specified. 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; 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. => if the item is recognized,git add -A
will find it and add it.
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),
- 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);
git add -A .
git add -u .
In conclusion, my policy is:
- Ensure any hunks/files to be added are accounted for in
git status
. - If any items are missing, due to invisible files/folders, add them separately.
- Have a good
.gitignore
file so that normally only files of interest are untracked and/or unrecognized. - From the top level of the repository, "git add -A" to add all items. This works in all versions of Git.
- Remove any desired items from the index if desired.
- If there is a big bug, do 'git reset' to clear the index entirely.
回答9:
git add .
equals 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.
P.S.: information relates to Git 2.0.
回答10:
Both git add .
and git add -A
will stage all new, modified and deleted files in the newer versions of Git.
The difference is that git add -A
stages files in "higher, current and subdirectories" that belong to your working Git repository. But doing a git add .
only stages files in the current directory and subdirectories following it (not the files lying outside, i.e., 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 .
, 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.
回答11:
The -A
option adds, modifies, and removes index entries to match the working tree.
In Git 2 the -A
option is now the default.
When a .
is added that limits the scope of the update to the directory you are currently in, as per the Git documentation
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).
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.
来源:https://stackoverflow.com/questions/572549/difference-between-git-add-a-and-git-add