Almost every Git command is about moving changes between these areas, so this model makes the rest click.
Git keeps your project in three places at once, and understanding them explains most commands.
- The working tree is the files on disk that you edit with your editor.
- The index (also called the staging area) is a draft of the next commit. It starts as a copy of the last commit, and you update it explicitly.
- The repository (
.git) holds the committed snapshots.HEADpoints at the commit you currently have checked out.
The normal flow is: edit files in the working tree, git add to copy the changes you want into the index, then git commit to turn the index into a new permanent snapshot.
Why have a middle step? Because it lets you shape commits. You may have touched five files while fixing a bug and tidying up; you can stage just the bug fix, commit it with a clear message, then stage and commit the tidy-up separately. git add -p even lets you stage individual hunks within a file.
This model also explains the two kinds of diff. git diff compares working tree against the index (what you have not staged yet), while git diff --staged compares the index against HEAD (what will go into the next commit).
Files also have a tracking state: untracked (Git has never been told about them), tracked and unmodified, modified, or staged. git status reports exactly these states.
Example
echo "hello" > a.txt
git status --short # ?? a.txt (untracked)
git add a.txt
git status --short # A a.txt (staged)
git commit -m "Add a.txt"
echo "world" >> a.txt
git status --short # M a.txt (modified, not staged)
git diff # working tree vs index
git add a.txt
git diff --staged # index vs HEAD: what the next commit containsRemember
- Working tree -> git add -> index -> git commit -> repository
- The index is the draft of your next commit
- git diff = unstaged changes; git diff --staged = what you are about to commit
Watch out for
- Editing a file again after git add and committing — only the staged version is committed, not the later edit.