top | item 38393718

(no title)

mtnygard | 2 years ago

I have found that git makes a lot more sense if you reverse the mental model of lineage. People think about a lineage going forward. But a more useful way to think is in terms of backward pointers.

A commit points to it's parent(s). Since a branch is just a commit ID, you can follow the parent links backwards to find the whole history of that branch.

So a "branch point" is just where two chains of parent links converge.

The special part are merge commits. Those have multiple parents, indicating that two histories fused into one.

discuss

order

layer8|2 years ago

The issue is that if you consider a branch to be what is really the history of the branch tip, then a branch is not just the part starting from the last join with another branch. Instead it is some directed path through the commit DAG, a path that in general can’t be reconstructed from the information Git keeps.

If, for example, you have a structure like

        |
        o
       / \
      o   o
   A  |   |  B
      o   o
       \ /        
        o
       / \
      o   o
   C  |   |  D
      o   o
       \ /
        o
        |
then conceptually the path CA might be one branch and DB the other branch (or alternatively, CB and DA). But this is not something that is represented in Git’s model.

ajross|2 years ago

> a path that in general can’t be reconstructed from the information Git keeps.

Uh... yes it can. Commits have a list of 0 or more parents. That creates a DAG. There are literal hordes of tools out there that reliably interpret this, from visualizer tools to practical mutators like git bisect.

Maybe you're trying to say that no single commit order exists that traverses the whole tree. That's true, because branches can merge together. But it remains a completely interpretable graph nonetheless.

vifon|2 years ago

This missing piece of information would be essentially `git reflog`, except it's not something Git sends between the clones.

Izkata|2 years ago

You can reconstruct it manually with a combination of the parent commit order and the automatic merge commit message, if you didn't change the commit message. But yeah, that second part isn't recorded in the structure itself.

lifeisstillgood|2 years ago

Just to go off on a tangent - that's a pretty neat diagram for a throw away comment. was that just careful spacing in the HN textbox or did you use a tool - which one ? :-)

mountainboy|2 years ago

Interesting, so then which path(s) does git display when running git-log on this?

trealira|2 years ago

That's how I learned it, not having known anything about git or version control beforehand. I used this site:

learngitbranching.js.org/

Which represents commits as circles with arrows pointing to their parents.