Staging Changes
git add moves changes into the staging area — the draft of your next commit. Staging lets you decide exactly what goes into each commit, so one commit can hold one logical change even if you've been editing many files at once.
Adding a file
git status -s
?? granola.txt ?? omelette.txt ?? pancakes.txt
git add pancakes.txt git status -s
A pancakes.txt ?? granola.txt ?? omelette.txt
git add prints nothing when it works. pancakes.txt is now staged (A for added); the other two are still untracked.
Several files, folders and patterns
You can list several files, a folder (which adds everything inside it), or a wildcard pattern:
git add omelette.txt granola.txt git status -s
A granola.txt A omelette.txt A pancakes.txt
git add src/ # everything in the src folder git add "*.txt" # every .txt file, in all folders (quote the pattern)
Adding everything
The most common forms add all changes at once:
| Command | Stages |
|---|---|
git add . | New, modified and deleted files in the current folder and below |
git add -A (--all) | New, modified and deleted files in the whole repository |
git add -u (--update) | Modified and deleted files only — new files stay untracked |
Run from the top folder, git add . and git add -A do the same thing. They're convenient, but check git status first so you don't stage a stray log file or password by accident — the .gitignore file in lesson 14 prevents most of these accidents.
echo "Pancakes: flour, milk, eggs, sugar" > pancakes.txt echo "Shakshuka: eggs, tomatoes, peppers" > shakshuka.txt git add -u git status -s
M pancakes.txt ?? shakshuka.txt
-u staged the modified pancakes.txt but left the new shakshuka.txt untracked.
Unstaging
Staged something by mistake? git restore --staged takes it back out of the staging area. Your edits in the working tree are not touched:
git add shakshuka.txt git restore --staged pancakes.txt git status -s
M pancakes.txt A shakshuka.txt
In older tutorials you'll see git reset HEAD <file> for this. It still works; git restore was added in Git 2.23 to give this job a clearer name.
Staging part of a file
Sometimes one file contains two unrelated edits — a bug fix and a new feature, say — and you want them in separate commits. git add -p (--patch) walks through each changed section of the file, called a hunk, and asks what to do with it:
git add -p pancakes.txt
| Key | Action |
|---|---|
| y | Stage this hunk |
| n | Skip it |
| s | Split it into smaller hunks |
| e | Edit the hunk by hand |
| q | Quit; hunks you've already answered keep their choice |
| ? | Show help |
Most code editors offer the same thing graphically: select some lines in the Git panel and choose "Stage selected ranges".
Seeing what's staged
git status lists files; to see the actual lines that will be committed, use git diff --staged (lesson 12):
git add pancakes.txt git diff --staged pancakes.txt
diff --git a/pancakes.txt b/pancakes.txt index a05992e..fe8185b 100644 --- a/pancakes.txt +++ b/pancakes.txt @@ -1 +1 @@ -Pancakes: flour, milk, eggs +Pancakes: flour, milk, eggs, sugar
Empty folders aren't tracked
Git tracks files, not folders. A folder with nothing in it never shows up in git status:
mkdir photos git status -s
M pancakes.txt A shakshuka.txt
If a project needs an empty folder to exist (for example a place for uploads), the convention is to put an empty file called .gitkeep inside it. The name has no special meaning to Git — any file would do.
touch photos/.gitkeep git status -s
M pancakes.txt A shakshuka.txt ?? photos/
Try it yourself
Create three files, stage two of them with one git add command, then unstage one with git restore --staged. Predict the output of git status -s before running it.