new - undo git add

Difference between “git add-A” and “git add.” (7)

The command git add [--all|-A] appears to be identical to git add .. Is this correct? If not, how do they differ?

Things changed with Git 2.0:

  • -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

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.

Finally I think I get this, many thanks to you all. 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, ie 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. => iff the item is tracked.
  • -A = --all (no such -a, which gives syntax error) = superset of all untracked/tracked files , unless in Git < 2.0, wherein if the dot filespec is given, then only that particular folder is considered. => iff the item is recognized, git add -A will find it and add it.

The pathspec is as follows.

  • In Git <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),
  • 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);

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.
  • 1A.If any items are missing, due to invisible files/folders, add them separately.
  • 2.Have a good gitignore so that normally only files of interest are untracked and/or unrecognized.
  • 3.From the top level of the repo, "git add -A" to add all items. This works in all versions of git.
  • 4.Remove any desired items from the index if desired.
  • 6.If there is a big bug, do 'git reset' to clear the index entirely.

Late to the party but this question also deserves a more distilled quick answer.

git add -A 

Does both below (same as git add --all)

git add . 

Stages new + modified files

git add -u 

Stages modified + deleted files

So from Charles instructions above, after testing my proposed understanding would be as follow:

# For the next commit
$ git add .   # add to index only files created/modified and not those deleted
$ git add -u  # add to index only files deleted/modified and not those created
$ git add -A  # do both operation at once, add to index all files

This link might also be helpfull to understand in what situation those commands may be applied: Removing Deleted Files from your Git Working Directory.

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.