Live data from Hacker News

Commits are shapshots, not diffs

github.blog

51–60 of 154 posts

Re: Commits are shapshots, not diffs

#51
post #50

Snapshots and diffs are just a storage implementation detail, no? Can you not calculate one from the other?

> Can you not calculate one from the other?

Yes, you can.

> Snapshots and diffs are just a storage implementation detail, no?

If this is what you think, the headline is truly awful; git commits are stored as diffs where possible.

Re: Commits are shapshots, not diffs

#52

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…

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

This "simple" model is completely useless when trying to understand what merges, cherry picks, rebases, and patches actually do. Snapshots don't naturally do anything, and can't be combined in any way.

If you think in terms of snapshots, then you have to also start thinking about diff algorithms, and how different diff algorithms can give completely different meanings to what a "merge" or a "rebase" actually mean. Which is true, but given that git comes with one specific diff algorithm built in, and beginners should DEFINITELY not mess with it, it muddies the waters quite a bit.

Re: Commits are shapshots, not diffs

#53
post #50

Snapshots and diffs are just a storage implementation detail, no? Can you not calculate one from the other?

Well snapshots and lists of all the diffs to apply in order (so long as there are no conflicts) are equivalent, but there are important ways that git is fundamentally based on snapshots rather than diffs. A simple example is that rebasing changes the revision id and snapshot even if the diff doesn’t change, or that rerere exists. If snapshots were equivalent to diffs then this wouldn’t need to be the case: just do set union in the world of diffs.

Re: Commits are shapshots, not diffs

#54
post #49

Earlier quoted context omitted.

Ok I see. I actually misunderstood what rebase actually did. So I guess it's a good thing then that I've never used it. Thanks for your persistence.

That didn't stop you from arguing that it was trivial upthread...

I was attempting to answer a question. It wasn't my intent to pose an argument.

Re: Commits are shapshots, not diffs

#55
post #4

Earlier quoted context omitted.

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 oppo…

I kind of intuitively get it, but that doesn't really seem well defined. I'm always a little bit spooked that `cherry-pick` will cleanly apply when it really shouldn't have. It's not clear to me under which circumstances it automatically resolves.

You're right to be spooked about that, but you're wrong if you think only cherry-pick has this problem. In fact, all git commands can and sometimes will cleanly apply and subtly mess your files (git merge, git pull, git rebase, git apply, git stash apply etc).

The definition of how changes are applied actually has nothing to do with git itself, and everything to do with the diff algorithm you choose (of course, you normally use a built-in one, but I believe you can customize it if you really want).

In general, the default Git diff algorithm, like all text-based diff algorithms, can have problems with structured data, such as removing closed parens or significant white-space. Naturally, it can also be problematic if you have declarations that must be a unique in a file, but that can occur in different places. The Java or Go `package` statements are safe, since they must occur at the beginning of a file, so if they are different between the 2 files they are likely to be caught. But if two people have added a top-level function called `foo` , but they added it in different places in the file with different params, it's pretty likely that the diff algorithm will not see any conflict and will duplicate both lines.

Cherry pick is in fact one of the places I would normally worry least about this, since it is usually done for limited sized commits. However, when merging a feature branch into master, the potential for errors goes up, and so does the work required to catch such errors during the review.

Re: Commits are shapshots, not diffs

#56

Earlier quoted context omitted.

I kind of intuitively get it, but that doesn't really seem well defined. I'm always a little bit spooked that `cherry-pick` will cleanly apply when it really shouldn't have. It's not clear to me under which circumstances it automatically resolves.

You're right to be spooked about that, but you're wrong if you think only cherry-pick has this problem. In fact, all git commands can and sometimes will cleanly apply and subtly mess your files (git merge, git pull, git rebase, git apply, git stash apply etc). The definition of how changes are applied actually has nothing to do with git itself, and everything to do with the diff algorithm you choose (of course, you n…

Thank you.

In all my (extensive) commentary in this topic, I feel this is the first response that addresses the root of my confusion in a way I can understand. Sincerely, this is helpful.

Re: Commits are shapshots, not diffs

#57

Earlier quoted context omitted.

> The result of subtraction is defined to be a number. A diff shows the difference between two commits (i.e. snapshots). Perhaps a better math analogy: one point can be subtracted from another to give a vector. > It's not clearly (to me) defined which parts of the files are considered to part of the diff and which parts are to be excluded. You're right that it's not precisely defined in that way, but there's a good r…

I'm glad that real-life diff tools work in ways that they deem to be useful. But they don't always produce the most sensible result. In fact different algorithms produce different diff visualizations for the same input. I'm just a little uncomfortable with a feature that uses diffs for purposes other than display for humans, since they don't seem to be consistently defined.

> I'm just a little uncomfortable with a feature that uses diffs for purposes other than display for humans

Git is based on the idea that it is generally safe to do that. You can't do any kind of work with git other than commits on your own local repo without relying on diffs and merges based on diffs.

Re: Commits are shapshots, not diffs

#58
post #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 G…

Git internal delta compression has nothing to do with why Git commits are most usefully thought of as diffs. All git operations start by computing diffs between commits, and then trying to apply those diffs before conceptually taking a snapshot. It is quite likely that the textual diff used in the operation and the internal diff produced by the delta compression are entirely different.

Re: Commits are shapshots, not diffs

#59
post #44

Earlier quoted context omitted.

> I'd argue that diffs in the presence of renames aren't natural That is true, at least for the text-based diff(1) formats, though obviously nothing precludes extending the format, or even using something else entirely (aside from the risk of not being compatible with diff(1), but then you could always present diff(1) compatible diffs externally and use something richer internally, for instance). > git handles them b…

That could be all be true, but IMO git's handling is still better than the alternatives I've used (Perforce, mercurial, subversion, CVS). (Although honestly I never really have problems with it messing up. If you approximately separate renaming from editing, it seems to work very reliably for me.) There's also nothing stopping anyone from writing a git history browser that caches the calculation. The point is that it…

Git rename tracking is better than P4 rename tracking with colleagues that don't use Rename. But if people are disciplined and DO use Rename/Move (and Copy), then P4 is much nicer to use. In particular, since many languages require file contents to be change depending on dir structure, Git often forces you to commit invalid files just to try to ensure that it will pick up the changes.

With P4, you can move the files around, adjust everything until it compiles, and only then start telling P4 about what you actually did (you can even start from Reconcile Offline Work, which will try to use exactly Git's logic to identify moved/renamed/copied files based on content - but only one time, on your own machine, not every time someone looks at the history).

Re: Commits are shapshots, not diffs

#60

Earlier quoted context omitted.

You're right to be spooked about that, but you're wrong if you think only cherry-pick has this problem. In fact, all git commands can and sometimes will cleanly apply and subtly mess your files (git merge, git pull, git rebase, git apply, git stash apply etc). The definition of how changes are applied actually has nothing to do with git itself, and everything to do with the diff algorithm you choose (of course, you n…

Thank you. In all my (extensive) commentary in this topic, I feel this is the first response that addresses the root of my confusion in a way I can understand. Sincerely, this is helpful.

Glad to hear that! Rarely have I actually felt that a comment I wrote actually made a difference.
Post reply on HN