Live data from Hacker News

Git Branches: Intuition and Reality

jvns.ca

231–240 of 281 posts

Re: Git Branches: Intuition and Reality

#231

Earlier quoted context omitted.

Merging branch A into branch B does two things: 1. Create a new merge commit with two parents: the commit pointed to by A and the commit pointed to by B. 2. Set branch B to point at the new merge commit. This is a non-linear history; when comparing some commits there isn't a "before" or "after."

If I checkout the merge commit and then do a ‘git log -n 5’, which parent pointer is followed to show the previous commit logs? A or B or Both / all if it is more than a 2-way merge?

By default it's by commit date.

Other ordering is possible, e.g. --topo-order

Re: Git Branches: Intuition and Reality

#232

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…

aka Git is the simplest crappiest implementation that can work. Then they tacked a terrible UX onto it and shipped it. Chaos ensued and we as devs have spent the last almost 20 years fighting over trying to understand the chaos, we would have been way better off staying with SVN or Mercurial or Fossil(or pretty much any other VCS), but that ship has sailed and now we are stuck in the chaos.

Now nobody understands their VCS and nobody will ever understand it, as the explanations are either too detailed and miss the forest for the trees or too high level and skip over all the trees that kill you when you accidentally run into them.

I hope someone somewhere manages to convince us all to move to something sane.

Re: Git Branches: Intuition and Reality

#233
post #232

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…

aka Git is the simplest crappiest implementation that can work. Then they tacked a terrible UX onto it and shipped it. Chaos ensued and we as devs have spent the last almost 20 years fighting over trying to understand the chaos, we would have been way better off staying with SVN or Mercurial or Fossil(or pretty much any other VCS), but that ship has sailed and now we are stuck in the chaos. Now nobody understands the…

With all due respect, what a load of crap!

SVN, branching that takes forever instead of a simple file with a commit hash in it? Are you serious?

Mercurial, when I had to use it for almost 2 years? The single thing I missed the most is the fact that "everything is just a label" (or pointer if you will).

Fossil I can't comment on with certainty, as I never really used it.

This is probably gonna get voted into oblivion, but most devs just don't get VCS, period (yes I'm a dev, so this is an inside perspective). Git or not. They didn't get it in CVS days, they didn't get it in SVN days and they didn't get various commercial ones either. Somehow most devs just don't grok version control trees.

But so far git is the single best VCS I have got to use. Everything that I actually need day to day follows from grokking the one simple rule: All those branches and tags are just labels/pointers/sticky notes and you can move them around at will and it's fast.

I do get that there are tricky situations with octopus merges and all that jazz and the Linux kernel and a few other open source projects are probably some of the trickier use cases to understand. For your run of the mill corporate situation? Keep `master`/`main`/`whateveryoucallit` history straight with one commit per feature/change by doing rebases and squashing and you will never have a single minute of misunderstanding what is going on. IFF you grok that "everything is just a label" and you've actually "created a branch" by just creating a file in `.git/refs/heads/` yourself!

And the second rule is: before you try anything, just: commit! And never close that terminal window. You might need that commit hash to reattach a label to it after you "destroyed" your branch (but git has not garbage collected yet and it's all actually still there). Or someone else still has your commits and you just get them from there and reattach a label. It's really so simple.

Re: Git Branches: Intuition and Reality

#234
post #71

Earlier quoted context omitted.

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?

Merging branch A into branch B does two things: 1. Create a new merge commit with two parents: the commit pointed to by A and the commit pointed to by B. 2. Set branch B to point at the new merge commit. This is a non-linear history; when comparing some commits there isn't a "before" or "after."

To complete the answer, the only difference if you merge branch B into branch A is that A is advanced to the new commit instead.

Re: Git Branches: Intuition and Reality

#235

Earlier quoted context omitted.

I have to serious ask. Of the people who have issues with using or understanding git, how many of them have actually read the docs? Git is by no means perfect but the development community is great and there is a massive focus on improving the project and making things more approachable and intuitive. And because of that, git actually has really solid, coherent documentation with easily digestible tutorials and guide…

Git makes version control roughly 10x more complicated than it needs to be. I can teach an artist or designer who has never heard of version control how to use Perforce in roughly 5 minutes. They will never blow off their leg and will likely never lose work. It will probably be a few months before they hit some edge case where they need help. Git requires building a non-trivial mental model. Then it requires memorizi…

> Git makes version control roughly 10x more complicated than it needs to be.

A significant part of this is that git explicitly supports more workflows than centralised VCS like subversion, perforce, or clearcase. Other than a few fairly small differences, mercurial and fossil (two other distributed VCS projects) have the same UX issues. You can't really reduce the complexity without just lopping off support. You can make that complexity more approachable/digestible (which the git devs are trying to do) but this fundamentally requires a certain willingness from the user to learn the tool.

For a lot of people git ends up being a sort of cargo cult where they get through the day with a set of magical incantations that make it work and solve their problems but without any real ability to troubleshoot when they do something wrong. Which is exactly the thing that prevents them from "gitting it".

And worth noting: I don't think I've ever worked with someone who has really gotten irreparably stuck with git after reading through the important parts of the user manual (not the references/man pages but the dedicated user manual [1]) and/or the git book [2]. There are some overly technical parts but they are towards the end of each. But if someone actually reads the entry-level user oriented parts of each/either document, odds are they'll understand enough to be able to actually solve their problems.

1. https://git-scm.com/docs/user-manual

2. https://git-scm.com/book/en/v2

Re: Git Branches: Intuition and Reality

#236
post #206
post #200

Earlier quoted context omitted.

> 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). A good name for these "wandering tags" would be "heads", since it's what git calls them internally (for instance, when not packed, they're stored at the "refs/heads/" path in the repository). This also exposes a distinction between a "branch" and it…

Just to make this explicit: a branch in the chain of commits. The start of the chain is pointed to by a head. When you create a new commit on a branch, the head (of that branch) changes to point to the new commit.

Arrggh. A branch IS a chain of commits.

Re: Git Branches: Intuition and Reality

#237
post #177

Earlier quoted context omitted.

The right mental model is to realise the 'main' branch is only special by convention - git doesn't actually treat it differently from any other branch. All of the confusion expressed in the article stems from a misunderstanding that main should work in some special way. Of course every branch's history goes all the way back to root and not to some arbitrary common commit of another branch like 'main'. Of course rebas…

"All of the confusion expressed in the article stems from a misunderstanding that main should work in some special way." I didn't have that impression when reading that article. To me it seems that the confusion comes from thinking in actual branches, and not from thinking anything special about main.

They're only thought of as actual branches (off of main) if you're also thinking of main as a trunk that is in some way special or different.

Re: Git Branches: Intuition and Reality

#238

Earlier quoted context omitted.

Git makes version control roughly 10x more complicated than it needs to be. I can teach an artist or designer who has never heard of version control how to use Perforce in roughly 5 minutes. They will never blow off their leg and will likely never lose work. It will probably be a few months before they hit some edge case where they need help. Git requires building a non-trivial mental model. Then it requires memorizi…

> Git makes version control roughly 10x more complicated than it needs to be. A significant part of this is that git explicitly supports more workflows than centralised VCS like subversion, perforce, or clearcase. Other than a few fairly small differences, mercurial and fossil (two other distributed VCS projects) have the same UX issues. You can't really reduce the complexity without just lopping off support. You can…

> A significant part of this is that git explicitly supports more workflows than centralised VCS like subversion, perforce, or clearcase.

I don't think this is quite correct. Mercurial is just as capable but has a much more accessible CLI.

Git pushes edge-cases to front and center. Almost all Git users use Git as a defacto centralized tool. There's a remote on GitHub, the end. Almost all users never need any feature that has to do with decentralization.

Git has somehow tricked people into thinking that version control is complicated. It's tragic.

Re: Git Branches: Intuition and Reality

#239
post #177

Earlier quoted context omitted.

"All of the confusion expressed in the article stems from a misunderstanding that main should work in some special way." I didn't have that impression when reading that article. To me it seems that the confusion comes from thinking in actual branches, and not from thinking anything special about main.

They're only thought of as actual branches (off of main) if you're also thinking of main as a trunk that is in some way special or different.

[deleted]

Re: Git Branches: Intuition and Reality

#240

Earlier quoted context omitted.

A key point with git is that every clone is effectively its own set of branches; even if they have the same name. The mechanisms you use for synchronizing your local branches with some remote branches are exactly the same as the mechanisms you use between to your local named branches. Git was actually designed initially for email based workflows where there was no central remote at all. Basically, that works by expor…

> A git patch is just a textualized form of the list of commits you created locally. You can apply them to any branch you like. Not even branch. You can combine two unrelated repositories, and in theory you could cherry-pick commits from one of the original repositories to the other. Of course, in practice this rarely works because the files mentioned in the commit don't exist in the other repository. But there's not…

Git commits always have a parent. Applying git patches to a repository without the parent is not going to work. The repository must have the parent commit. You might force it to work without that but it's going to create conflicts, complicate merging, etc.

The reason is that a git patch is not merely a diff but an export of the actual commit objects and referred content (trees, blob diffs, hashes, etc.). Applying the patch recreates the exact commit objects on the other side. The end state is exactly the same as if you would have merged the commits from some branch. There is no difference.

Git diff, shows you a normal diff. It's not the same thing. You can indeed apply such diffs to your local work copy. But that's not the same thing as a git patch.

The commands you need are git format-patch (exports the patch) and git apply (applies it).

Post reply on HN