Commits are snapshots not diffs (2020)
From a storage perspective, describing commits as snapshots seems like a bad mental model. Suppose I have a directory that is 100MB in size. If I take a snapshot of it, my snapshot would be 100MB in size. If I take a 2nd snapshot of it tomorrow, my 2nd snapshot would also be 100MB in size. My total storage needs would now be 300MB.<p>Whereas if I had used git, and created 2 additional commits, each making a change to a small text file, my total storage size would be barely larger than 100MB. Describing the commits as a diff, as opposed to a snapshot, leads to a better intuitive understanding of why this would be the case.<p>Not to mention other features the article discussed, such as cherry-picking. What does it even mean to &quot;cherry-pick a snapshot&quot;? In comparison, cherry-picking a diff and applying it to your current state, is far more intuitive.<p>And let&#x27;s not forget commit messages. If a commit is a snapshot, I would expect the commit-message to be descriptive of the entire snapshot. Whereas if a commit is a diff, I would expect the commit message to be descriptive of the diff. Which is exactly how most people use commit messages.<p>Obviously both &quot;diffs&quot; and &quot;snapshots&quot; are leaky abstractions. If you insist on using the &quot;snapshot&quot; abstraction, you will need to resolve all of the above points of confusion by adding more complexity to your abstraction. And if you prefer to use the &quot;diff&quot; abstraction, you will eventually need to explain that a commit is actually a combination of diffs, along with some other metadata like a pointer to a parent commit. As a teaching tool, you can make either abstraction work. But I find it far more intuitive and useful to think of commits as &quot;diffs + some metadata&quot;.