3 ms·
I think we're running into a naming issue here. It's usefult to think of a single commit in itself as a diff. The DAG is a useful model for an accumulation of c
by maweki 6y ago
I think we're running into a naming issue here. It's usefult to think of a single commit in itself as a diff. The DAG is a useful model for an accumulation of changes. The question is, what changes and operations make up a node in the DAG (i.e. what code is in this branch, compared to that? What code do they have in common)?
To answer this: take the node and follow along the predecessor until you get one (or more) roots. All commits along the root are contained in the commit at hand. That's the history.
Adding changes is, I think, the most useful mental model, even if it is not the implementation.
Now what the author is saying is: A commit is not only the diff, but also the whole tree/history that the diff is based on. And that is also true and then the commit (the adding plus the past) is a snapshot.
Do we have a good naming convention for the single node in the tree with its changes, compared to the single node in the tree with its changes AND the references to the parents with all their changes etc.?
- derriz 6y ago> It's usefult to think of a single commit in itself as a diff. Except if it has multiple parents like a merge commit. Actually I don’t agree even in general. It took me an unreasonably long time to become unafraid of git because I clung to the common VCS mental where commits were actually diffs.
- maweki 6y agoBut the snapshot-model also doesn't really make a lot of sense for merges. It's a snapshot of what then? A merge of all parent trees? What's a merge of two files then? Defining this merge-operation on trees is at least as mentally taxing as the alternative. Accumulating all the diffs from two (or more) ends (until they are common again) is at least as useful.
- derriz 6y agoFor me, a merge commit in git is just a snapshot like any other except that its metadata contains links to more than one parent. The parent child relationship acts as nothing more than remark that the child was derived from both parents in some way. Of course, commonly the child is derived by finding the most recent common parent, using heuristics to guess file identities after any renaming and then performing a 3-way line-based diff between what it thinks are corresponding files. But actually git doesn't really care - it's just another snapshot you've created and added to the DAG. I haven't found it helpful to think of what's going on in git in terms of an "accumulated file diffs" abstraction because git has no notion of file identity (across commits).
- cesarb 6y ago> But the snapshot-model also doesn't really make a lot of sense for merges. It's a snapshot of what then? It's a snapshot of the final result. That's the beauty of the "commit as snapshot" model: each commit always contains the final result of the commit. It doesn't matter if the commit is a normal commit with a single parent, a merge commit with multiple parents, or even an initial commit with zero parents. It doesn't matter if the parent commits are unavailable (shallow repositories). It doesn't matter if the parent commits have been changed (grafts).
- viraptor 6y agoYou can have a diff to multiple parents - you get multiple status columns then. Similar to what you see in the diff in merge issues.