3

I always thought of git index just a staging area, i e. when nothing is staged after git commit, index is empty, where as head is the sum of all previous commited indexes reached from the head.

Apparently this mindset is wrong, regarding how git reset --soft <ref> preserves the index according to doc. When i soft reset from clean working directory to earlier commit, the changes introduced on later commits are staged automatically, i.e added to index. Or more precisely, they aren't added on the index of the current commit, but the whole index is transferred.

Does this mean the index of clean commit directory actually contains the changes of previous commit, as well as the head does? Does commiting actually commits the difference between head and index? Does cleanliness and diffs of the working directory mean the difference to the index, rather than to the head? What is exactly the index as a data structure, how does git add or git commit change it? How it evolves commit after commit, how it relates to the concept of snapshot and deltas?

Tuomas Toivonen
  • 21,690
  • 47
  • 129
  • 225

1 Answers1

5

The index indeed acts as a staging area, but like the rest of Git, it is a snapshot and not a diff. The index of a clean commit directory is identical to the last commit, not empty. This is a common misconception because most of the time you think about the index as a delta, and git tries its hardest to show you deltas. For example, git status seems to show you the index, but actually, it "displays the differences between the index file and the current HEAD commit". git status shows you the delta computed between the two snapshots.

With this in mind, the rest of your questions are easy to explain. After you soft reset, the HEAD moves back and the index stays where it is. The later commits aren't really staged automatically; they remain where they are, just that git status will show a new delta based on the new HEAD. git commit also does not affect the index (unless you use -a), it just stores it in a new commit and updates HEAD, which is why git status becomes empty.

See What does the git index contain EXACTLY? for the implementation details, though I don't think it would add much to your conceptual understanding.

Allen Z.
  • 1,560
  • 1
  • 11
  • 19
  • So does `git add` actually update the index data structure? And `git commit` is just like okay, take a snapshot of the current index and create a new pointer (commit) to it and point head/branch to this commit. Also, when you say "displays the differences between the index file and the current HEAD commit", do you mean "the differences between the index file and head (staged changes) *or* the working tree (unstaged)"? How else it could show unstaged changes or untracked content? Also, it's very hard to grasp how HEAD and index actually store these snapshots, or what is actually a snapshot. – Tuomas Toivonen Sep 10 '17 at 13:06
  • Yes, `git add` and `git rm` are the main commands for modifying the index. `git status` shows separate diffs for staged and unstaged changes. I only quoted the staged part of the documentation, but you can read the whole thing. HEAD is a pointer to a commit, and a commit is an immutable snapshot. A snapshot stores the entire state of your workspace at a point in time (excluding unstaged files). See [Git is a functional data structure](https://blog.jayway.com/2013/03/03/git-is-a-purely-functional-data-structure/) and [Git Objects](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects). – Allen Z. Sep 10 '17 at 18:30
  • Thank you for this answer. Index != ‘git status’. ‘Git status’ == index minus last commit. Then when you commit, that commit’s “index” becomes your index or staging area. I guess then untracked/unstated changes aren’t part of the index? Got status just happens to display those in addition to showing the aforementioned difference? – ds-bos-msk Apr 19 '19 at 04:18
  • Yes, I was only talking about the first section reported by git status. The description for [git status](https://git-scm.com/docs/git-status) defines the other two sections, which show changes outside the index. – Allen Z. Apr 19 '19 at 16:06