Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> From a storage perspective, no dammit, Git commits are snapshots, look at the bits on disk if you don't believe it

Except they're not. They're (often) packfiles, which are a delta encoding i.e. a diff. It's not necessarily the same as a specific commit, but appealing to "the bits on disk" is wrong.

It is certainly true that the git object model each commit object refers to a tree that represents the complete state of the repository at that commit.

It is also true that many git commands implictly treat a commit as being the diff between the state of the tree in that commit and the state in the parent. For example git show, git rebase and git cherry-pick.

It is simultaneously true that the on-disk storage system is optimised for performance and so doesn't map onto the object model in a trivial way.



> They're (often) packfiles, which are a delta encoding i.e. a diff. …appealing to "the bits on disk" is wrong.

That's fair. The diffs in a packfile have no relation to the "diff" that a commit would be if the commit were a diff; so it's wrong to use "but packfiles" when arguing that commits are diffs and not snapshots; but you're right, packfiles make my "bits on disk" argument not quite right.

The way I look at it is that packfiles are a compression mechanism; and they don't alter the fact that fundamentally it's snapshots that are being compressed. But that's not the only way of looking at it.


> It is also true that many git commands implictly treat a commit as being the diff between the state of the tree in that commit and the state in the parent. For example git show, git rebase and git cherry-pick.

A commit is a snapshot, and you can compute the diff between a commit and any of its parents. If a commit has multiple parents, git cherry-pick bails out unless you pick a parent (usually -m 1), and git rebase, I think implicitly assumes the first parent.

(EDIT: a commit's tree, its parents' trees)


> If a commit has multiple parents, … git rebase, I think implicitly assumes the first parent.

`git rebase`'s behavior regarding merge commits is shockingly complicated, but much of the time: Because by default it linearizes the history, it actually just skips merge commits because it assumes that the merge has already happened implicitly by applying one of the merge's parents on top of the other parent.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: