The Staging Area & Commits
The Three Areas of Git
This is the concept beginners trip on, so slow down here. As you work, your files pass through three distinct places, and understanding the difference is what makes everything else in Git make sense:
Working Directory ──git add──▶ Staging Area ──git commit──▶ Repository (history)
(your edits, (a holding area: (permanent,
on disk right now) what's about to be committed
saved next) snapshots)
- The working directory is just your normal folder of files, exactly as you see them in an editor. Git is watching it, but nothing here is "saved" to history yet.
- The staging area (also called "the index") is a middle step most other tools don't have. It's a draft list of exactly which changes will go into the next commit. Editing a file does not automatically add it here - you choose.
- The repository is the permanent history: the sequence of committed snapshots you can always come back to.
Analogy: The staging area is a packing box sitting between your desk (working directory) and the moving truck (repository history).git addputs specific items into the box;git commitseals the box, labels it with a message, and loads it onto the truck for good. You decide exactly what goes in each box - you don't have to pack (or ship) everything on your desk at once.
| Command | Does |
|---|---|
git add file.txt | Stage one specific file |
git add . | Stage every changed/new file in and below the current folder |
git commit -m "message" | Permanently snapshot whatever is currently staged |
git commit -am "msg" | Stage all changes to already-tracked files and commit, in one step |
$ echo 'hello' > readme.md
$ git add readme.md
$ git commit -m "Add readme"
[main (root-commit) a1b2c3d] Add readme
1 file changed, 1 insertion(+)
That a1b2c3d in the output is the start of the commit's hash - a unique fingerprint Git generates from the snapshot's contents. Every commit gets one; you'll use these hashes constantly to refer to specific points in history later in this track. Under the hood, a commit is really just three things bundled together: a snapshot of every file exactly as it was staged, a pointer back to the commit that came before it (its "parent"), and metadata - author, timestamp, and your message. Chain enough commits together, each pointing at its parent, and you get the timeline git log shows you.
Tip: Write commit messages in the imperative: "Add login page", not "Added login page" or "Adds login page". It reads like a command the commit performs when applied - that's the Git convention, and tools/changelogs assume it.
Warning: Easy-to-miss trap: if yougit add file.txt, then keep editingfile.txtafter staging it, the extra edits are not included when you commit - only the exact version you staged goes in.git statuswill even tell you the file has "changes not staged for commit" a second time. When in doubt,git addagain right before you commit.