Session 5 · Adding and staging files#
The big idea#
Git does not save everything you changed automatically. You pick what goes into the next snapshot by
staging it with git add, then git commit saves exactly what is staged. The staging area lets you build
a clean, focused commit even when you have touched many files.
Everyday example: packing a courier box. Your desk has many things on it (the working folder). You choose only the items for this order, put them in the box (staging), check the box, and then seal and label it (commit). Everything else stays on the desk for another box.
Staging in practice#
git config --global user.name "Dev User"
git config --global user.email "dev@example.com"
git config --global init.defaultBranch main
git init -q site
cd site
touch app.js style.css README.md
echo '--- 1. stage one file only'
git add style.css
git status -s
echo '--- 2. stage everything except README.md'
git add -- ':!README.md'
git status -s
echo '--- 3. stage only part of a file (git add -p)'
git commit -q -m "Start the site"
seq -f 'line %g' 1 20 > style.css
git add style.css && git commit -q -m "Add styles"
sed -i -e '1s/.*/line 1 (edited)/' -e '20s/.*/line 20 (edited)/' style.css
printf 'y\nn\n' | git add -p style.css | grep '^[-+@]\|Stage'
git status -s
echo '--- staged part versus the rest'
git diff --staged --stat
git diff --stat
echo '--- take a file back out of the staging area'
git restore --staged style.css
git status -s
--- 1. stage one file only
A style.css
?? README.md
?? app.js
--- 2. stage everything except README.md
A app.js
A style.css
?? README.md
--- 3. stage only part of a file (git add -p)
--- a/style.css
+++ b/style.css
@@ -1,4 +1,4 @@
-line 1
+line 1 (edited)
(1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? @@ -17,4 +17,4 @@ line 16
-line 20
+line 20 (edited)
(2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]?
MM style.css
?? README.md
--- staged part versus the rest
style.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
style.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- take a file back out of the staging area
M style.css
?? README.md
Reading git status -s (short status): the left column is the staging area, the right column is the
working folder.
Code |
Meaning |
|---|---|
|
New file Git has never seen (untracked) |
|
New file staged for the next commit |
|
Modified and staged |
|
Modified but not staged |
|
Staged, and then modified again |
What the demo did:
git add style.cssstaged one file;app.jsandREADME.mdstayed??.git add -- ':!README.md'staged everything exceptREADME.md. The:!is a pathspec exclude. Now onlyREADME.mdis??.git add -pshowed the edited file one hunk (a block of changes) at a time. We changed line 1 and line 20, which are far apart, so Git asked twice:yfor the first,nfor the second. The resultMMmeans part of the file is staged and part is not.git restore --staged style.csstook the file back out of the staging area. Its edits are kept in the working folder (M).
Useful variations#
Command |
Stages |
|---|---|
|
One file |
|
Everything in this folder and below |
|
Only files Git already tracks (changes and deletions) |
|
Files matching a pattern (quote it) |
|
Chosen hunks, with a prompt for each |
|
Un-stage (keeps the edits) |
Common mistakes#
git add .without looking first. It will happily stage logs, passwords and build output. Rungit statusbefore and after.Thinking
git addsaves the file. It only stages it. Nothing is stored in history untilgit commit.Editing after staging. Git stages the file as it was when you added it. Edit it again and it shows
MM; add it again to include the new edits.Misreading the two status columns. Left is staged, right is not staged.
Using
git checkout .orgit restore .to “un-stage”. Those throw away your edits. To un-stage usegit restore --staged.
Hands-on exercises#
Exercise 1. Create app.js, style.css and README.md. Stage only style.css and show the short status.
Solution
touch app.js style.css README.md
git add style.css
git status -s
Output: A style.css, then ?? README.md and ?? app.js.
Exercise 2. Stage every file except README.md using a pathspec.
Solution
git add -- ':!README.md'
git status -s
app.js and style.css show A , and README.md stays ??.
Exercise 3. Edit a committed file in two places far apart and stage only the first change with git add -p.
Solution
seq -f 'line %g' 1 20 > style.css && git add style.css && git commit -m "Add styles"
sed -i -e '1s/.*/line 1 (edited)/' -e '20s/.*/line 20 (edited)/' style.css
git add -p style.css # answer y for the first hunk, n for the second
git status -s # MM style.css
git diff --staged then shows only the line 1 change, and plain git diff shows the line 20 change.
Practice#
Take the Session 5 quiz. The original Q2 Adding and Staging Files page is in the reference section.