4 ms·
> Suppose I have a directory that is 100MB in size. If I take a snapshot of it, my snapshot would be 100MB in size. Not with `btrfs subvolume snapshot`, it won
by LukeShu 6y ago
> Suppose I have a directory that is 100MB in size. If I take a snapshot of it, my snapshot would be 100MB in size.
Not with `btrfs subvolume snapshot`, it won't. If that's not a snapshot, I don't know what is.
From a storage perspective, no dammit, Git commits are snapshots, look at the bits on disk if you don't believe it. This isn't something that people who like to write blog posts about Git made up for pedagogical purposes, it's how Git actually works.
As you point out, it's wonky for pedagogical purposes; what does it mean to "cherry-pick" a snapshot? When thinking about cherry-picking, yeah, a diff makes more sense than a snapshot. But saying a diff is better pedagogically doesn't change the fact that a commit actually is a snapshot (and when cherry-picking, it diffs to snapshots to create a patch, then applies that patch).
- jgraham 6y ago> 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.
- nyanpasu64 6y ago> 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)
- LukeShu 6y ago> 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.
- LukeShu 6y ago> 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.