1. 14
  1.  

  2. 14

    The problem with branching is really merging. So what’s merging? It’s the worst.

    Any discussion of merging trouble soon turns to merge conflicts. Because merge conflicts are death. But there are fates worse than death. There are successful merges.

    As a heavy user of branches, I don’t really understand this post but in particular this point seems to misunderstand what a merge conflict is. The problem with branching is not merges or merge conflicts, merge conflicts have just made it clear that two people are working on the same bit of code at the same time and now one of them has to do something about this. In what way is this wrong?

    The point that merging doesn’t mean everything works is completely true, but that is why people write long blog posts about testing and all that jazz. I don’t see how being branchless stop someone from committing code that also breaks things.

    In general, I’m not sure what the difference is between branchless development and branched developement other than branched developement makes what is going on explicit. In branchless development people are developing in parallel just as much as branched, the branched model just makes it explicit what is going on where. (Assuming you aren’t using a version control system with file locks).

    1. 1

      merge conflicts have just made it clear that two people are working on the same bit of code at the same time and now one of them has to do something about this. In what way is this wrong?

      I seem to have omitted the paragraph about the crudeness of line by line, choose left or right, merge tools. :) But the point was that while most people grumble about resolving merge conflicts, some of the very worst merge errors I’ve dealt with resulted from smooth, successful merges. git pull, no conflicts? Ship it!

      Add:

      that is why people write long blog posts about testing and all that jazz.

      I certainly understand what you mean, though I find “that’s why you have tests” to be something of a cop out. You can make that reply to any methodology (except the ones without tests). “Use tests” seemingly makes all development styles equivalent, and that’s clearly not the case.

      1. 1

        I seem to have omitted the paragraph about the crudeness of line by line, choose left or right, merge tools. :)

        Yeah definitely, the way we handle code is pretty sad. I realize you have a smiley face there, but do you mean that merge conflicts are bad because of this or vice versa? If we had semantic diffs we’d still have merge conflicts, but would that be ok, in your opinion?

        But the point was that while most people grumble about resolving merge conflicts, some of the very worst merge errors I’ve dealt with resulted from smooth, successful merges. git pull, no conflicts? Ship it!

        In what way does being branchless fix this? I agree with you that a successful merge is no indication that the change is ready to ship, but I’m not sure how being branchless makes the state of affairs better.

        I certainly understand what you mean, though I find “that’s why you have tests” to be something of a cop out.

        Well tests just happen to be where the industry has stopped in trying to ensure quality. You could have a very expressive type system where compiling a successful merge is a strong indication of correctness. But as far as I can tell, unless I’m missing something really revolutionary, when it comes to code quality all roads lead to testing. At some point in time you have your changes and master has changed, you’ve got to verify your changes work inside master somehow.

        Branches are a way to help manage changes rather than a tool for correctness.

        1. 3

          I think tools reflect our mentality, but then the tools reinforce that mentality. Merge tools subconsciously suggest that the final product should be some linear combination/interleaving of lines.

          This wasn’t really meant to be a branchless advocacy piece, I was just thinking about it the other day, but I can certainly make some points clearer. (It was really “why openbsd doesn’t use github” but I got lazy and didn’t write much about that.) Thanks for asking, though, good questions.

          Mostly I need to refine the parts about risk assessment. I think we measure the risk of a feature/branch by its divergence from baseline. Imagine a triangle, where you have a straight line going left to right. Baseline. And a line trending up, that’s the feature. Your risk is the height of the line. Now, if somebody is working on a second branch, that’s like a second line trending down. Your true risk is now the difference between the top and bottom line. But in my experience, nobody calculates that, and instead makes all decisions based on distance to a projected baseline. Is that clear at all?

          Working on the same branch just means everybody is always close to the baseline. Your risk estimates remain accurate, and you learn about potential interference between features must sooner. I don’t think many organizations have the project management knowhow to really predict such interference.

    2. 3

      As a fellow “development heresy” kind of guy, I identify with this, although I’m glad to see it doesn’t attempt to make any sweeping claims.

      I’ve worked with mostly branchless to lots of branches and I can’t say one is significantly better than the other. Testing is needed with both approaches (until we find something less annoying, if ever) as is discipline to make it work. The complexity of dealing with multiple edits to the same section of code remains. How it’s handled is different, but it doesn’t go away.

      Branchless certainly has a more methodical feel to it, which is something I tend to like. Frankly, I’ve found the branchless approach more social because I end up having conversations about the code before I start to change it, rather than after.

      Alternatively, encouraging branches tends to lead to speedier commits. I think there’s something gratifying about that, a bit like junk food, that keeps you coming back for more.

      This falls into the “there’s more than one way to do it” camp. That’s appreciated.

      1. 3

        We practice this kind of development in the central repository of illumos. There is only master; every change we integrate must be reviewed and tested, and of a quality sufficient to be used in release versions of illumos distributions. Software is hard, so sometimes we make mistakes – but we strive not to be negligent.

        In SmartOS, we have a downstream fork of illumos, where we also use and ship the master branch in SmartOS and SDC. We generally merge in any upstream illumos changes once per working day. This keeps us as close as possible to upstream, and reduces the merge conflict hell described in the article. Even so, it can still be a pain in areas where we diverge from upstream.

        We seek to ensure that as many engineering and operations resources as possible are testing what we ship to the community and to paying customers. Having engineers living in long-term development branches would reduce the amount of testing the operating system receives before being shipped. Less testing means master is more likely to be broken, which is self re-enforcing: it becomes the quality death spiral.

        1. 3

          The problem with branching is really merging. So what’s merging? It’s the worst.

          The problem for me with the above is that branchless, trunk development still creates merge conflicts.

          1. 2

            Maybe I’m too old (and had to deal with the horrors of moving a file on CVS), but I never had any problems with merging on Git (I tend to avoid them because rebases are so much cleaner, but rebasing would use branchs anyway, so…). Perhaps I’m missing something?

            Also, if your problem is really with merge conflicts, you will get them just the same if everyone is commiting to master/trunk, no?

            Finally, lots of assumptions there (“this is faster”, “that is slower”) and the only references seem to point to articles defending branched approaches (trunk-based, which I particularly dislike + condemning feature toggles)

            1. 1

              I come close to agreement, because I do think branches should be short-lived. I tend to follow agile: one branch per feature, and each feature should be small enough to be completed in two weeks, so no branch should live longer than two weeks.

              But inside those two weeks the branches let my coding be more social, not less. While a feature is in progress it may well not even compile (with an ideal type system, one would decide that a particular feature should exist, declare as much to the type system, then start fixing compile errors - and when you’ve fixed all the compile errors, you’re done! E.g. with a suitable type system that dialogue confirmation problem simply couldn’t happen, because adding a confirmation to a dialogue that already has a confirmation is a type error). And while I’m working on a feature I want to experiment with approaches that may or may not work - branches allow me to try one approach and go back if it’s not working. I push a lot, probably every five minutes.

              If I didn’t have (public) branches, I’d have to spend those two weeks working offline and then push to master at the end. That would also make merging or integration problems more likely - if other developers can see exactly what I’m working on then we can head off any potential conflicts before they happen.

              Feature toggles are indeed the worst kind of technical debt.

              1. 1

                Google has been doing branchless dev at enormous scale for many years.