The Staging Area
Edit config.json, run git add, then change one line again, and your next commit keeps the earlier version, not what sits on disk. Three copies of one file exist at once, and one command chose between them.
- ▸
.git/indexis one binary file:git addrewrites a single row in it and touches nothing else. - ▸Stage a file, then edit it, and the commit keeps the staged bytes, not what is now on disk.
- ▸
git status's two letters are two separate diffs: a file can differ from your commit and what you staged.
A file called config.json holds {"port": 8080}. You change the port to 9090 and save. You run git add config.json. Then, still tinkering, you change the port to 7070 and commit.
Which port is in the commit?
The answer is 9090, the value from when you ran git add, not the 7070 sitting in the file. To see why, count the places one path can live:
- The working tree: the actual config.json on disk, the bytes your editor writes. Right now it holds 7070.
- The index: a single file at .git/index. It holds a list of paths, and for config.json it records the version you last added, 9090.
- The last commit: the snapshot the current branch points at. Before this commit it held 8080.
Three places, one filename, three different versions at the same moment. git add copied the working tree's 9090 into the index. git commit built the new snapshot from the index, so it took 9090 and never looked at the 7070 still on disk.
Every move in this topic is a transfer between these three places. Once you know which command writes which place, git status stops being a wall of letters and becomes a report on three files you can name.