Get AI summaries of any video or article — Sign up free
Git Tutorial: Difference between "add -A", "add -u", "add .", and "add *" thumbnail

Git Tutorial: Difference between "add -A", "add -u", "add .", and "add *"

Corey Schafer·
4 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Use “git add -A” (or plain “git add” on Git version 2) to stage new, modified, and deleted files across the working tree.

Briefing

Git add’s different flags all target the staging area, but they differ sharply in which kinds of changes they include: modified vs. new (untracked) vs. deleted, and whether the command is scoped to the current directory or the entire working tree. The biggest practical takeaway is that “git add -A” (or “git add” in newer Git) stages everything—new, modified, and deleted—across the whole working tree, while “git add -u” stages only modified and deleted changes and leaves new files out.

Starting from a working directory containing a mix of states—top-level deletions, top-level modifications, subdirectory deletions, subdirectory modifications, a dotfile, and both new and untracked files—the tutorial demonstrates how each syntax behaves after staging and checking with git status. “git add -A” stages modified, deleted, and new files across the entire working tree, even if the command is run from inside a subdirectory; the scope still reaches upward to include changes one directory level above. The same “all” behavior can be achieved by specifying a directory after the command (e.g., “git add -A <dir>”), which restricts staging to that directory and avoids touching changes outside it.

A key nuance: “git add -A” is also the default behavior for “git add” in Git version 2, so omitting “-A” yields the same result as “git add -A” when run from the working tree root. In Git version 1, omitting “-A” behaved differently by not staging deletions; to replicate the older behavior, the command “git add --no-all” (or “git add --ignore-removal” in the longer form) is used, which prevents deleted files from being staged.

“git add -u” (shorthand for “--update”) stages modified and deleted files but intentionally skips untracked/new files. Like “-A,” it can be scoped by adding a directory argument; running “git add -u <dir>” stages updates within that directory while leaving new files untracked and also excluding changes outside the specified directory.

The tutorial also contrasts “git add .” with “git add -A.” When run from the top-level directory, “git add .” matches “git add -A” because both effectively cover the working tree. But once inside a subdirectory, “git add .” only stages changes within the current directory, not in parent directories—so deletions and modifications one level up won’t be staged. Finally, it warns against “git add *”: the asterisk is a shell glob, not a Git-aware selector. That means it can miss deleted files (since they aren’t present on disk) and hidden dotfiles, leading to inconsistent staging results depending on where the command is run. The recommended approach is to use explicit, Git-native forms like “git add -A” or “git add -u” (optionally with a directory argument) rather than relying on shell expansion.

Cornell Notes

“git add -A” stages everything—new, modified, and deleted—across the entire working tree, even when run from a subdirectory. In Git version 2, plain “git add” defaults to the same behavior as “git add -A”; in Git version 1, omitting “-A” would skip deletions unless “--no-all” (or “--ignore-removal”) is used to force that older behavior. “git add -u” stages only modified and deleted files, skipping untracked/new files. “git add .” matches “git add -A” only when run from the repo root; inside a subdirectory it won’t stage changes in parent directories. “git add *” is discouraged because shell globbing can exclude deleted files and hidden dotfiles, producing surprising results.

What’s the practical difference between “git add -A” and “git add -u”?

“git add -A” stages modified, deleted, and new (untracked) files across the working tree. “git add -u” stages only modified and deleted files, explicitly skipping untracked/new files. In the tutorial’s mixed-state example, “-A” brings in new files and deletions, while “-u” leaves new files out but still stages deletions and modifications.

Why does “git add” behave differently across Git versions?

In Git version 2, “git add” without flags defaults to the same behavior as “git add -A,” meaning deletions are included. In Git version 1, omitting “-A” would ignore deleted files. To reproduce the Git v1-style behavior, the command uses “git add --no-all” (or the longer “--ignore-removal”), which prevents deletions from being staged.

How does scoping change the meaning of “git add -A <dir>” and “git add -u <dir>”?

Adding a directory argument restricts staging to that directory. “git add -A <dir>” stages new, modified, and deleted changes only within <dir>, leaving top-level changes untouched. Similarly, “git add -u <dir>” stages only modified and deleted changes within <dir>, and it still won’t stage new/untracked files.

When is “git add .” equivalent to “git add -A,” and when isn’t it?

From the repo root, “git add .” matches “git add -A” because both cover the whole working tree. But after changing into a subdirectory, “git add .” only stages changes within that current directory; it won’t stage changes in parent directories (including files one level up).

Why is “git add *” considered risky?

The asterisk is a shell glob, not a Git-aware selector. Shell expansion can omit deleted files (since they no longer exist on disk) and hidden dotfiles. The tutorial shows that “git add *” can stage some deletions unexpectedly or miss them entirely, and it can also skip hidden files—so results vary based on directory location and what the shell passes to Git.

Review Questions

  1. If you want to stage deletions and modifications but not new untracked files, which flag should you use: -A, -u, or .?
  2. What behavior changes when you run “git add .” from inside a subdirectory instead of from the repo root?
  3. Why can “git add *” fail to stage hidden files or deletions even when you expect “add everything” behavior?

Key Points

  1. 1

    Use “git add -A” (or plain “git add” on Git version 2) to stage new, modified, and deleted files across the working tree.

  2. 2

    Use “git add -u” to stage only modified and deleted files; it will not stage untracked/new files.

  3. 3

    Adding a directory argument after “git add -A” or “git add -u” restricts staging to that directory and excludes changes outside it.

  4. 4

    “git add .” stages changes in the current directory; it matches “git add -A” only when run from the repo root.

  5. 5

    Avoid “git add *” because shell globbing can omit deleted files and hidden dotfiles, leading to inconsistent staging.

  6. 6

    If you need Git version 1-style behavior that skips deletions, use “git add --no-all” (or “--ignore-removal”).

Highlights

“git add -A” stages modified, deleted, and new files across the entire working tree—even when run from a subdirectory.
“git add -u” stages modified and deleted files but leaves untracked/new files unstaged.
“git add .” stops at the current directory boundary; run it from a subdirectory and it won’t stage changes one level up.
“git add *” is unreliable because the shell, not Git, decides what gets passed in—often excluding deletions and hidden dotfiles.

Topics

  • Git add Flags
  • Staging Area
  • Deleted Files
  • Untracked Files
  • Shell Globbing