Live data from Hacker News

Git Branches: Intuition and Reality

jvns.ca

81–90 of 281 posts

Re: Git Branches: Intuition and Reality

#82
post #8

A lot of things in git are just pointers to commits, and then the git implementation handles them under the covers in some way that usually makes sense but not always. One example that also bites people: moving files isn't stored in git - if you move files (even with `git mv`) and create a new commit, the moves aren't stored, but this is reconstructed later by the client based on similarity, which comes from the diff…

[deleted]

Re: Git Branches: Intuition and Reality

#83
The article goes in the right direction, but from a weird starting point. Saying things like "a branch contains the entire history" just adds to the general confusion about Git. Git does not have branches. Sure, Git emulates branches to appear familiar and intuitive, but it is actually counterproductive to use that as a starting point to explain how Git works. Git manages a graph of commits and some of those commits need human readable labels. That's it. The only thing that contains the entire history is the commit graph itself.

Re: Git Branches: Intuition and Reality

#85
post #30

Earlier quoted context omitted.

I'm still missing what part of the intuition is incorrect? It seems like the only "incorrectness" is that there's no explicit hierarchy of branches. Except that's wrong the HEAD ref points to the default branch. Any other branches are of equal significance, though.

No, the HEAD ref points to whatever branch is "active", that's how the active branch is defined. Indeed `git checkout branchname` does nothing except make HEAD point to the commit that `refs/heads/branchname` points to. The intuition jvns meant is the idea that a branch only constitutes the commits since the point of divergence, but every branch actually contains the full history up to the root of its tree, and `git…

> `git checkout branchname` does nothing except make HEAD point to the commit

You probably know this, but since we are being pedantic we might as well get it right: That describes "git reset". "git checkout" does that and record that we are tracking branchname. So any commits will move both HEAD and the branchname reference.

Re: Git Branches: Intuition and Reality

#86

That's an excellent explanation. > “Wrong” models can be super useful. This is used in usability and UX design a lot. Affording mental models that don't reflect the actual code, happens all the time.

This is used in usability and UX design a lot.

It's the fundamental thing that makes UI work. I've always liked the title of Brenda Laurel's book - Computers as Theatre

Re: Git Branches: Intuition and Reality

#87
post #83

The article goes in the right direction, but from a weird starting point. Saying things like "a branch contains the entire history" just adds to the general confusion about Git. Git does not have branches. Sure, Git emulates branches to appear familiar and intuitive, but it is actually counterproductive to use that as a starting point to explain how Git works. Git manages a graph of commits and some of those commits…

[deleted]

Re: Git Branches: Intuition and Reality

#88
post #3

I cannot be the only one that gets away with only knowing: git pull git merge x git checkout [-b] foo git commit git push

Really?? I would have a very hard time without: git log git show git status git blame git diff git add git reset

My "minimalist" list of git commands:

    git add
    git blame
    git branch
    git checkout
    git cherry-pick
    git clone
    git commit
    git diff
    git fetch
    git log
    git merge
    git pull
    git push
    git reset
    git rm
    git stash
    git status
17 commands in total. I don't think it is possible to be a professional software engineer without being familiar with them. Granted, some of these you may need more frequently than others.

My guess is, the OC relies on their IDE/editor for the functionality provided by some of these commands. But then, why not just go all the way. Just use all VC features provided by your IDE, and claim that you need zero git commands.

Re: Git Branches: Intuition and Reality

#89
post #59

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 conve…

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…

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

Re: Git Branches: Intuition and Reality

#90
post #71

While the explanation is right in some sense, it misses a few points. Branches are pointers to a commit and that pointer is refreshed when a new commit is created. One could say they are a wandering tag (without explaining a tag for now). The actual chain of commits that represent what we see as branch comes from the commits themselves. Those commits point back to their parent commit. And then one can see why no bran…

This was the most useful piece of information that I have ever read about Git. But what happens if you merge branch A into beanch B? A and B will both contain the commits of A, but in B there may be commits of B between the commits that were merged. Do the same commits of A then have different parents depending on which branch they are on?

> Do the same commits of A then have different parents depending on which branch they are on?

Absolutely not. Commits are immutable (representing whole repo state, not a diff), and branches are just (mutable) pointers to them.

As the sibling already noted, a merge commit is just a regular commit. It simply points to multiple parents, "merging" them. Aside of the whole machinery to resolve conflicts etc. that's pretty much all there is to it.

When your graph topology allows it, you can also merge branches without generating a new commit (so called "fast forward" merges) - such a merge does nothing but rewrites the branch pointer. You can also create merge commits that point to more parents than two ("octopus" merges). Reconciling the commits' content can get quite complicated in such cases, but from the repo graph perspective it's nothing special.

Post reply on HN