What is the difference between git add [--all | -A]
and git add .
?
This answer only applies to Git version 1.x. For Git version 2.x, see other answers.
Summary:
git add -A stages all changes
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
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
Git Version 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
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 -u is equivalent to git add --update
Further reading:
Git for beginners: The definitive practical guide
Resources to learn Git
Learn Git Branching
Explain Git With D3
git diff-files -z --diff-filter=M --name-only | xargs -0 git add
to add only the modified files, but not the new files or the deletions.
git add .
only adds new files that are on the current path. I.e. if you have a new directory ../foo
, git add -A
will stage it, git add .
will not.
git add .
is equivalent to git add -A .
, which is equivalent to git add "*"
With Git 2.0, git add -A
is default: git add .
equals git add -A .
.
git add
git add -A
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.
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.
Things changed with Git 2.0 (2014-05-28):
-A is now the default
The old behavior is now available with --ignore-removal.
git add -u and git 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 . and 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:
If you are located directly at the working directory, then git add -A and git 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 . 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 -A
Stages new + modified files
git add .
Stages modified + deleted files
git add -u
git add :/
+ git add -u :/
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.
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 (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.
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.
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
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.
I hate the staging mechanism of git, which can not be found in other SCM tools. So I always use:
\git add --all && \git commit --all
(Even though with \git add --all
, \git commit
is enough)
for 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
git add
for version 2.35.1 of Git: git add --all <pathspec>
Older versions of Git: git add --no-all <pathspec>
But git add
followed by nothing, does not equal to git add --all
, and will do nothing:
https://i.stack.imgur.com/2Nb4w.png
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 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
Success story sharing
git add *
?git add -A -p
doesn't work as one would expect (ask interactively about untracked files)git add -A :/
orgit add -A .
git add -u
has becomegit add -u :/
with the latter parameter being a path, allowing you to -u certain directories,:/
handles the whole tree.git add -u
orgit add .
and by doing that it makes his life easier even after accounting for the extra mental tax added to ensure that there're no sync problems? I wonder why Git doesn't furthur splitadd -u
into two separate commandsadd -u1
andadd-u2
whereby one works for files starting with numerals and the other for files starting with non-numerals