3 ms·
> The mental model is not even difficult - you can describe it in a sentence or two. > * Each commit is a snapshot of your code at a certain point. > That's it
by sreevisakh 5y ago
> The mental model is not even difficult - you can describe it in a sentence or two.
> * Each commit is a snapshot of your code at a certain point.
> That's it.
Unfortunately, it's a bit more nuanced than that. What you described is only git's storage format. Git operations and UI unfortunately isn't consistent with that model. Take for example, interactive rebasing. By your definition, if we delete a commit, the subsequent commits should remain unchanged - because commits are only snapshots after all. But that isn't what happens. The change introduced by that commit gets deleted from all subsequent commit. Commits are treated as diffs here.
Git UI switches between snapshot and diff model quite often. Merges and rebases are all patch operations. Novice users can get away with being oblivious to this change for most operations till merges. But rebases require you to be aware of it. Even for experienced git users, large multi-commit interactive rebases are hard because git simply hides all the nuances of patching (you are better off rebasing in small chunks). This becomes immediately clear when you use a tool like quilt or stgit. In my opinion, this is something that prevents beginners from going beyond clone-commit-merge workflow and being able to create beautiful commit history like that of the kernel.
- TrianguloY 5y ago> By your definition, if we delete a commit, the subsequent commits should remain unchanged And that's exactly what happens. On a rebase, the original commits are not deleted, but the command creates new ones that matches the same diffs (unless there is a problem like an empty commit or a conflict). Normally those unused commits are 'lost' because no branch/pointer are now pointing to it, unless you have another branch which does. Later the gc removes those orphaned commits (although I think you do can restore them before that happens).
- IshKebab 5y ago> if we delete a commit, the subsequent commits should remain unchanged They are. You can get to them using the reflog. > Commits are treated as diffs here. Not exactly. For the rebase operation Git calculates the diff between subsequent commits and then reapplies them to make new commits, but the commits themselves are never treated as diffs. > Git UI switches between snapshot and diff model quite often. It doesn't. It allows you to perform operations that result in or consume diffs, but of course it does! They're useful things to do. How else would it work? It never treats commits themselves as diffs because that doesn't make any sense. Only the differences between two commits are treated as diffs (hence the name!)