Why the Same File Is Reported as Both Staged and Not Staged
Last timeThe Graph of Commits
One path can hold three different versions at once, and the two letters in a status line are two independent comparisons between them rather than one verdict on the file.
Three places, not two
A tracked file has a version on disk and a version in the last commit, and
almost every confusing message comes from there being a third version in
between. The repository used here has three files and four commits on its main
line. Read the middle layer out directly.
$ git ls-files --stage
100644 33769db0109a55e7ca266e647c5b6ae6b7df93ad 0 readme.md
100644 5b6cf77b6348d72977eab587467cbf306a1bc31c 0 render.py
100644 04f61ebb94a49f4b9e30a0d840b49c0a9b655e90 0 settings.ini
$ git cat-file -p 'HEAD^{tree}'
100644 blob 33769db0109a55e7ca266e647c5b6ae6b7df93ad readme.md
100644 blob 5b6cf77b6348d72977eab587467cbf306a1bc31c render.py
100644 blob 04f61ebb94a49f4b9e30a0d840b49c0a9b655e90 settings.ini
$ wc -c < .git/index
289
$ cat readme.md render.py settings.ini | wc -c
143Each line of the staged list is four things: a mode, a forty character object
name, a stage number which is 0 unless a merge is unresolved, and the path. That
is the entire structure. There is no copy of any file in it, no record of what
changed, and no partial commit waiting to be finished.
Two consequences follow immediately, and both are usually learned the hard way
instead. Staging is fast because it writes one object and rewrites one short
line, no matter how large the file is. And what you staged is not disturbed by
editing the file afterwards, because the staged line holds the name of the bytes
as they were when you staged them, and those bytes are in the store under that
name whatever the file on disk says now.
So the three places are the working copy, which is the files themselves, the
staged list, which is one line per path naming an object, and the last commit,
which is a tree in the store naming an object per path. Every state a path can
be in is some arrangement of three object names, and every command is a move
between two of the three.
Adding writes the object there and then
The claim that staging writes an object is worth checking rather than believing,
because the whole behaviour of the staged list depends on it. The committed
version of the settings file is the object 04f61eb. Change the width in it and
ask for the name of the new content without storing anything.
The lesson stops here
7 more paragraphs to go
You have read the opening. The rest of the argument, the problems that check whether it landed, and the lines worth keeping at the end all come with a plan.
The first lesson of every course in the library reads the whole way through, free, so you can see exactly what the rest of them are.
See the planThe contentsThis is the reading half
Starting the course gives you your own copy of it. Every idea on every page has problems standing under it, marked with a reason rather than a tick, and any sentence you do not believe can be opened and argued with. None of that can happen on a page nobody owns.
The contents