Live data from Hacker News

Commits are shapshots, not diffs

github.blog

61–70 of 154 posts

Re: Commits are shapshots, not diffs

#61
post #44

Earlier quoted context omitted.

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…

You could have the commit command do rename-detection and store the result.

Re: Commits are shapshots, not diffs

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

> Diffs are a "natural" object for version control

Diffs are natural objects for evaluating commits--answering questions like "does this new version of the code make sense?"--but they are not the natural objects for storing commits.

Re: Commits are shapshots, not diffs

#63
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…

> One problem with the name-based systems is that developers don't actually use the VCS rename operation.

That’s a matter of tooling. In languages and environments where using an IDE is the norm, use of VCS operations happens automatically, simply by virtue of performing all source file operations through the IDE.

Re: Commits are shapshots, not diffs

#64
post #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

This is my go-to video for anyone looking to learn git. It won't teach you the various commands on the command line but it shows you what is actually happening inside git when you perform various actions. It made me transition from "I know how to run these commands to operate git" to "I know what git is doing, so I can reason about the system and adapt to unusual circumstances". Now when someone makes a mistake in my company's git, I am the person people go to for help.

Re: Commits are shapshots, not diffs

#65
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 don't think diffs are the "natural" object - if you talk to someone who isn't using an automated version control system but still doing revision control, what they have is "Resume 12-1-2020.doc," "Resume 12-2-2020.doc," "Resume reviewed by Joe.doc," "Resume for Contoso final.doc," "Resume for Contoso final final USE THIS VERSION.doc," etc.

Those are snapshots of individual versions of the files, not diffs.

Or think about your favorite wiki (Wikipedia or your corporate wiki) - if you hit the "History" page, what you see is a list of the versions of the page, and then some UI to compare any two given versions. While there's a button for computing a diff between any version and the previous, that's not what it appears to treat as the natural object.

Diffs are an emergent object when you have some mechanism to automatically create them and apply them. (This is generally a programmatic mechanism, but there have long been cases where the mechanism is manual effort - think laws that amend other laws by saying "After section 3 insert... and remove section 5".) But the ultimate goal is to produce a version of the file.

If you want a diff management system, play around with quilt, which treats diffs (patch files) as the first-class object. Just about everyone I know who's tried using quilt for more than the tiniest amount of work vastly prefers just importing the applied patches into git and working with them in git. This is largely because quilt is empirically much more leaky - it's very sensitive to the current state of your directory, because a diff is a second-class object which requires something to be applied to in order to make sense, and it's too easy for the contents of your directory to not quite line up.

(Put another way - there's a reason we call it "version control" / "revision control". The thing it tracks is versions/revisions, which are concrete instances of the file in time. Quilt is a patch management system, and very few people are interested in those.)

Re: Commits are shapshots, not diffs

#66
Great article.

The first thing that I was told about git was that commits are snapshots. It is enough to understand the simple workflow: pull, commit -a, push.

What confused me was everything that involves applying diffs (git stash apply, git rebase, git cherry-pick).

The secret is that you need to think both in terms of snapshots, or diffs, depending on the context.

Some git tutorials show you a few "magic" commands to get you started but it's best to really understand the git model as soon as possible. It's not that hard, and it's here to stay. We may still be using git in 30 years, just like we're still using bash and vim.

Re: Commits are shapshots, not diffs

#67
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'm not sure I understand what you mean. Snapshots and diffs are different views of the same thing. You need both. It doesn't really matter which one is more natural or primitive in the implementation.

When I git push, I upload my commits (i.e. snapshots). And when I git cherry-pick, I apply a diff. Both views are needed, I don't see why it's a leak.

Re: Commits are shapshots, not diffs

#68
post #20

This is why I'm really excited about the potential of Pijul. In pijul, commits are diffs, and you avoid all of the rebase/cherry-picking craziness of Git. Still alpha software, so tons of roughs edges, but the potential is incredible. I think it'll be similar to the centralized -> distributed revolution that git ushered in.

There's nothing intrinsically superior about storing commits as diffs - subversion stores its commits as diffs (or at least, it did a decade or so ago,) and I haven't heard anyone enthusing about svn in a long time.

Re: Commits are shapshots, not diffs

#69
post #68
post #20

This is why I'm really excited about the potential of Pijul. In pijul, commits are diffs, and you avoid all of the rebase/cherry-picking craziness of Git. Still alpha software, so tons of roughs edges, but the potential is incredible. I think it'll be similar to the centralized -> distributed revolution that git ushered in.

There's nothing intrinsically superior about storing commits as diffs - subversion stores its commits as diffs (or at least, it did a decade or so ago,) and I haven't heard anyone enthusing about svn in a long time.

Are you sure about that? See "Why a new version control system?" at

https://pijul.org/faq/

and the linked "badmerge" example:

https://tahoe-lafs.org/~zooko/badmerge/simple.html

Re: Commits are shapshots, not diffs

#70
A fascinating bit of history is that the reason for this data structure was to explicitly distance git from BitKeeper.

BitKeeper was used by many kernel developers, until one of them (the co-inventor of rsync, unsurprisingly) reverse-engineered its protocol, leading its proprietary owner to end its offer of a free license to Linus Torvalds and other developers.

While searching for a replacement, the Linux community sparked two projects: Mercurial (which uses changesets, similar to BitKeeper) and Git (which uses Merkle trees). Git was created by Linus in the unexpected free time that this event created; and he mentioned being weary of Mercurial and having adopted this design for Git to remove any ambiguity that they were creating a BitKeeper clone.

Incidentally, BitKeeper did demand that its customers not work on Mercurial[1].

[1]: https://web.archive.org/web/20070929115009/http://article.gm...

Post reply on HN