Live data from Hacker News

Commits are shapshots, not diffs

github.blog

21–30 of 154 posts

Re: Commits are shapshots, not diffs

#21

Why does thinking about commits as snapshots make cherry-pick and rebase easier to understand? I've always thought of and taught commits as diffs because git does a good job of abstracting away the distinction. EDIT: To be clear, I think this is one of the _few_ abstractions that git doesn't leak. It does a pretty bad job everywhere else.

A snapshot is easy to understand. It's just the contents of a file at a point in time.

Diffs can have different definitions, and I've never seen a complete rigorous one for whatever git uses, if anything. Loosely a "diff" is the changes between one version an another. But to understand what cherry-pick does, we (or maybe just I) need more than a loose definition.

Using snapshots makes `rebase` trivial. The contents of a commit doesn't change. Just the link to its predecessor. Using a diff model, it requires all kinds of fancy changes.

Re: Commits are shapshots, not diffs

#22
post #6

Is it normal to need that level of understanding of the inner machinery of a software to use it?

I don't quite agree with the author that you need to understand that commits are implemented as snapshots, but yes, you need to understand quite a bit of how git works behind the scenes in order to use it effectively. This is because git tries to hide more than it should, which leads to confusion when things Go Wrong.

Re: Commits are shapshots, not diffs

#23
I don't look at it as either.

I simply look at it as a change in code at a location.

The commit ID of that change in the history chain is calculated based on the commit ID before it and the one before that is calculated based on the one before that all the way down to the very first commit. (Similar conceptually to blockchain)

So if you rebase or cherry pick or anything you will be building on top of a new commit ID so git will calculate a new commit ID for your new commit even though the code change is the same.

It's pretty simple... if you understand that concept you can get 90% of the way there with git.

Re: Commits are shapshots, not diffs

#24

I have never understood cherry-pick for this very reason. This helps, but I'm still confused. > The git cherry-pick command creates a new commit with an identical diff to whose parent is the current commit. How can two diffs ever be considered equivalent when they include a changed file that had different starting contents? Can they?

I find it easiest to think in terms of diffs as patches. It’s just a bunch of search and update commands. Sure, there’s some hairiness around files moving or whatever, but for me, a cherry pick is just getting a patch file and applying it in the appropriate place. It doesn’t care about the file it’s being applied to, it just needs to find similar content in the file so it can apply itself.

Re: Commits are shapshots, not diffs

#25

Why does thinking about commits as snapshots make cherry-pick and rebase easier to understand? I've always thought of and taught commits as diffs because git does a good job of abstracting away the distinction. EDIT: To be clear, I think this is one of the _few_ abstractions that git doesn't leak. It does a pretty bad job everywhere else.

A snapshot is easy to understand. It's just the contents of a file at a point in time. Diffs can have different definitions, and I've never seen a complete rigorous one for whatever git uses, if anything. Loosely a "diff" is the changes between one version an another. But to understand what cherry-pick does, we (or maybe just I) need more than a loose definition. Using snapshots makes `rebase` trivial. The contents o…

> Using snapshots makes `rebase` trivial. The contents of a commit doesn't change. Just the link to its predecessor.

It's the exact opposite. When you rebase, you want to apply the changes you're rebasing atop other existing changes.

If you just copy over the snapshot, you break everything. Rebasing a snapshot basically smashes your history and is utterly useless. That would make a rebase-pull… implicitly revert every intermediate commit.

Although AFAIK Git really uses the merge machinery to perform rebases: conceptually (I don't know if it does that technically) it merges each commit to rebase onto the rebase target, then copies over the commits without the old (rebased-from) parent.

Re: Commits are shapshots, not diffs

#27

Why does thinking about commits as snapshots make cherry-pick and rebase easier to understand? I've always thought of and taught commits as diffs because git does a good job of abstracting away the distinction. EDIT: To be clear, I think this is one of the _few_ abstractions that git doesn't leak. It does a pretty bad job everywhere else.

It does a good job in simple scenarios.

It breaks down often. I've seen plenty of horribly botched merges and rebases that took many hours to fix up.

We learn to work around this by adapting and limiting our workflows.

Most devs are just so used to git that a different model like Pijul is hard to reason about or see the benefits of, but improvement is definitely possible.

Re: Commits are shapshots, not diffs

#28
For a simple, easy to understand overview of git, nothing beats The Git Parable [1]. Every time I talk to someone starting out with Git I recommend they read it first. Once they understand Git through that lens, usually I find the rest falls into place.

[1] https://tom.preston-werner.com/2009/05/19/the-git-parable.ht...

Re: Commits are shapshots, not diffs

#29
Strictly speaking, it's a moot point. Snapshots and diffs are easily convertable to one another, which allows to present either way no matter the underlying structure.

We can talk though about how the data is actually represented in storage. Here efficiency comes forward, and good compression algorithms will detect a small change for a big dataset. But that's not necessarily what would be present to the user - though it could be.

Re: Commits are shapshots, not diffs

#30

Why does thinking about commits as snapshots make cherry-pick and rebase easier to understand? I've always thought of and taught commits as diffs because git does a good job of abstracting away the distinction. EDIT: To be clear, I think this is one of the _few_ abstractions that git doesn't leak. It does a pretty bad job everywhere else.

A snapshot is easy to understand. It's just the contents of a file at a point in time. Diffs can have different definitions, and I've never seen a complete rigorous one for whatever git uses, if anything. Loosely a "diff" is the changes between one version an another. But to understand what cherry-pick does, we (or maybe just I) need more than a loose definition. Using snapshots makes `rebase` trivial. The contents o…

> I've never seen a complete rigorous one for whatever git uses, if anything

Isn't that the point of a conceptual model? Thinking of commits as diffs abstracts away the actual implementation, which allows me to understand cherry picks and rebasing without worrying about object OIDs and trees. I can think of those actions as "applying the diffs onto other commits", even though technically it can't be implemented that way.

Post reply on HN