Live data from Hacker News

Commits are shapshots, not diffs

github.blog

41–50 of 154 posts

Re: Commits are shapshots, not diffs

#41
post #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.

I can't agree, because I don't work on diffs, I work on whatever the current state of the file hierarchy is. When I make changes to a file, it's not enough to know just the few lines before, I need to know what versions of code are operating dozens of lines away and in different files.

Further, diffs only make sense if you have the full version of the files, pre-diff. Without that full file state, diffs could operate in all sorts of incorrect ways.

I think this is one thing that git actually does correctly: save full checkpoints of a directory structure. I want the same thing when I'm dealing with, say, edits of an essay or book. I want the saved full state, and may produce a diff for convenience, but I wouldn't want to save the diff as the fundamental object of interest.

Re: Commits are shapshots, not diffs

#42
post #19

Earlier quoted context omitted.

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.

> It's analogous to how the difference between 5 and 15 is equal to the difference between 105 and 115. Patches are torsors? :o

I don't know what it means, but I recall seeing that word once before. That was in the context of explaining git also, so there's probably something to it.

https://news.ycombinator.com/item?id=25122863

Re: Commits are shapshots, not diffs

#43
post #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...

How about "Git For Ages 4 And Up" [1]?

[1] https://www.youtube.com/watch?v=1ffBJ4sVUb4

Re: Commits are shapshots, not diffs

#44
post #15

Earlier quoted context omitted.

I'd argue that diffs in the presence of renames aren't natural, and git handles them better than other version control systems. That is, git is content-based and not named-based. Name-based systems explicitly track renames with metadata; git does not. git calculates renames dynamically based on content.

> 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's ephemeral / derived state, not authoritative state.

One problem with the name-based systems is that developers don't actually use the VCS rename operation. They just delete and add, and then you've lost the diff under every system I know of. Another problem is importing from other VCSes -- the metadata is often messed up subtlely.

Git keeps it simple. And they can and have improved the algorithm over time without making your repo data obsolete / incompatible.

Re: Commits are shapshots, not diffs

#45
post #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.

I can't agree, because I don't work on diffs, I work on whatever the current state of the file hierarchy is. When I make changes to a file, it's not enough to know just the few lines before, I need to know what versions of code are operating dozens of lines away and in different files. Further, diffs only make sense if you have the full version of the files, pre-diff. Without that full file state, diffs could operate…

Your output, however, should be a patch. That's all I care about when it's time to review and integrate.

Re: Commits are shapshots, not diffs

#46
post #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.

Snapshots and diffs are dual. Most version control systems operate on snapshots, but there is at least one that doesn't: Darcs. Written in Haskell, it bases it's operation on an algebra of patches. Unfortunately, while usable (and neat!) for smaller projects, Darcs has serious performance problems (due to inherent algorithmic complexity) and gets slower with certain operations. Still, one can hope it will inspire a next generation of version control systems.

Re: Commits are shapshots, not diffs

#47

Earlier quoted context omitted.

> A snapshot is the aggregate of all previous changes. I don't see what could be broken by copying the snapshot. If you copy the snapshot, you lose all the intermediate commits you're rebasing onto, because they're not in the snapshot you're rebasing. > The snapshot before the rebase is exactly the same as the snapshot after the rebase. Which is exactly what you do not want. > The contents of the predecessor doesn't…

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.

Rebase is useful for artificially straightening out simultaneous work.

It's less clear in the above example, where d is just a single commit. But if there's a d1--d2--d3--d4, it can be confusing to merge chronologically (d1--d2--e--d3--f--d4).

If there aren't any conflicts, it's conceptually simpler in the long run to rebase it as e--f--d1--d2--d3--d4. You artificially serialize the work, which isn't what actually happened, but it could have happened that way. When you go back and look at it, pretending that it did is simpler. For example, if you have to go back and debug something that happened while working on d1...d4.

It's not absolutely mandatory to learn about it. But it the simple cases are common enough, and useful enough, that it's worth learning.

Re: Commits are shapshots, not diffs

#48

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, since they don't seem to be consistently defined.

Sure, I see your point as it applies to cherry-picks/rebasing. Yes, there's no formal guarantee it will do as you expect. The user should always check it manually. Occasionally it doesn't do what you want.

I'm of the opinion git cherry-pick should default to behaving like git cherry-pick --no-commit for that reason.

edit:

> they don't always produce the most sensible result

I don't know how much work has been done on language-aware diff/merge algorithms, but I can't see an obvious reason for it to be a dead-end.

Re: Commits are shapshots, not diffs

#49

Earlier quoted context omitted.

> A snapshot is the aggregate of all previous changes. I don't see what could be broken by copying the snapshot. If you copy the snapshot, you lose all the intermediate commits you're rebasing onto, because they're not in the snapshot you're rebasing. > The snapshot before the rebase is exactly the same as the snapshot after the rebase. Which is exactly what you do not want. > The contents of the predecessor doesn't…

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...
Post reply on HN