Live data from Hacker News

Commits are shapshots, not diffs

github.blog

1–10 of 154 posts

Re: Commits are shapshots, not diffs

#3
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?

Re: Commits are shapshots, not diffs

#4

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?

If I have a 100-line file and on 'main' it changes near the top, but in my 'topic' branch it changes near the bottom, then I can cherry-pick 'topic' onto 'main' and Git will resolve the diff correctly. The resulting diff or patch would only change in the line numbers for the context of the diff.

This is of course a very simple example. You might hit a conflict in your "git cherry-pick" command which gives you an opportunity to resolve the unexpected diff issue in an appropriate way, which ends up with a different diff than before.

Re: Commits are shapshots, not diffs

#5
Conceptually, a git commit is a snapshot. Simple as that. The user doesn't need to worry about how git manages its data internally.

> I believe that Git becomes understandable if we peel back the curtain and look at how Git stores your repository data.

This strikes me as misleading in the same way this StackOverflow answer [0] is misleading. In terms of how git stores data, commits are not always snapshots. Internally, git sometimes uses delta compression to reduce storage space. This is of no concern to the user, conceptually a commit is still a snapshot, but it's just not true that git naively stores each commit as a full snapshot.

Peeling back the curtain isn't helpful to someone trying to understand the basic git model. Also, as the article makes no mention of delta compression or of 'packfiles', it seems to me it hasn't pulled back the curtain at all.

[0] https://stackoverflow.com/a/8198276/

Re: Commits are shapshots, not diffs

#7

Conceptually, a git commit is a snapshot. Simple as that. The user doesn't need to worry about how git manages its data internally. > I believe that Git becomes understandable if we peel back the curtain and look at how Git stores your repository data. This strikes me as misleading in the same way this StackOverflow answer [0] is misleading. In terms of how git stores data, commits are not always snapshots. Internall…

The delta compression in Git is about storing the file contents of an object as a diff against another object. This changes the literal size on-disk, but it doesn't change the logical unit.

In fact, the delta chains used by Git for space compression have no direct relation to the object model DAG. From the perspective of a user using Git, these deltas are completely invisible.

Edit: perhaps to help this point... If Git stores an object using a delta, that doesn't change the object ID of that object compared to storing it uncompressed.

Re: Commits are shapshots, not diffs

#8
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.

Re: Commits are shapshots, not diffs

#9
Git is the leakiest abstraction in the history of abstractions.

Diffs are a "natural" object for version control yet got doesn't actually use them and as we can see in this article, multiple git commands leak this implementation detail.

Re: Commits are shapshots, not diffs

#10

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?

You're right that the commit produced by the cherry-pick operation won't be identical to the commit being cherry-picked. It's the diffs that are identical, not the final result.

It's analogous to how the difference between 5 and 15 is equal to the difference between 105 and 115.

Post reply on HN