The Baseless Critique Of Living Branchlessly

this branching thing.

the idea behind branching is that it provides advantages in situations where a code change is large. the idea behind non-branching is not to enter those situations. these two views seem very difficult to reconcile.

i am a non-brancher. i push to head, i pull from head, i test on head, i ship from head.

let’s take a second to consider the arguments against living like this.

first, a whole team that lives like this is constantly merging out and merging in, and that feels expensive. my counter is to point out that, as we learned with continuous integration, higher frequency of merges means far less pain.

second, ongoing large-scale changes are always partially in the code long before they are ready for prime time, i.e. release. there is a technique price for this, to be sure. but there is also a substantial gain from using those techniques.

the price is that you have to learn and use the various ways to prevent parts of head from being exposed to the user. these include things from feature-toggling to code re-organization, with many small patterns mixed in, like strategy and abstract factory. it’s a lot of technique to learn, and hence the price. (i know of orgs who try to solve all this with one technique, but it doesn’t work.)

but the gain comes in two parts. overall skill, and longer periods of GAK and other alpha testing.

what i mean by overall skill: these techniques i mentioned are not special cases only for this end, they’re the meat & potatoes of coding. abstract factory, say, or strategy, these are techniques that have myriad applications in programming aside from hiding code from users. so my geeks will use exactly the same proficiencies they should already have, and if they don’t know them, they should be learning them.

the longer periods of GAK and other testing is the second gain. (GAK = “Geek At Keyboard”, a geepawism.) the longer the code is in the base, the more likely we *all* are to discover infelicities before we get to release. this is of great value.

a third critique of living branchlessly is that it doesn’t let us hierarchicalize — org-chart-ify — testing & development & auditing. here we meet the ol’ geepaw at his most annoying: “that’s not a critique.” the separation of responsibilities idea was always classic idols of the schema. looks good on powerpoint, does not work well at all.

the fourth critique of non-branching is a kind of protean thing, whose rough gist is the fear of shipping defects. you’ve already seen one counter, the idea that the longer code is in place the more defects we can find in it.  but the real counter has to match the protean nature of the fear. it’s amorphous, attitudinal, and involves a huge variety of cases.

in one sentence: you get fewer defects by writing code in a defect-revealing way, not by trapping them after the fact.

when we ship a defect in the non-branching world, we respond to it in steps designed to disable that *kind* of defect forevermore. we don’t fix the defect and keep moving. that’s about attitude and technique both, a typical sociotechnical response.

i understand that’s a vague answer. it was a vague question. the truth of the matter is that that fear is based on a false abstraction. you can’t divide the world into bugs & non-bugs, or more correctly, you can, but it’s too abstract. real bugs have great variety.

the actual branchless response to discovering a bug depends on the nature of that particular bug & its family. if you want specific answers to how do i prevent bugs of family X, we need more info about that family. to pretend otherwise is bogus. in fact, pretending that all bugs are alike is precisely what creates that amorphous fear in the first place.

i’ve gone on too long already. let’s wrap this…

branchless living is suspect on four grounds: merge inefficiency, partial implementations, org-chart-lessness, and defect fear.

merge inefficiency doesn’t match our experience. partial implementation is just part of programming, org-chart-lessness is a good correction. defect fear is based on a weak abstraction.

i live without branches. i recommend strongly that everyone do so. key insight: don’t make large code changes, and you won’t need branches.

Drive, Sustenance, Collaboration, Stepping, And Narrative

take for granted for a minute that professional software development is a _complex_ problem, in the sense of complexity theory. i have in recent months been fretting, then, at how to *optimize* for s/d given that fundamental complexity.

problems that are merely intricate have the property that when you strike them sharply they break into smaller pieces. you get problem-shards, smaller ones, and hence more soluble, less intricate. rinse, lather, repeat, and they eventually get “‘easy”.

complex problems don’t have that property.

when you strike a complex problem sharply, it still breaks into pieces, but most of them are still complex problems. i use the metaphor of color separation. photos are printed by first dividing them into color separation layers. the usual is cyan, magenta, yellow, and black, tho others are possible. one photo turns in to four separations, one for each ink.

notice that the separations aren’t themselves *simpler* than their combination. they are all as complex as the photo itself. so we strike a complex photo sharply, and we get four equally complex separation layers from it.

i am in the process of striking professional software development this way. and i have (so far) produced what i think are five separations. i caution the reader with the three P’s: this work is partial, preliminary, premature. partial cuz i don’t think i’ve got it all yet. preliminary cuz i don’t think i’ve got all of even what i’ve got. premature cuz go easy.

optimizing for professional software development means optimizing for drive, sustenance, collaboration, stepping, and narrative.

we optimize for drive, juice, energy, because wrestling with complex problems is much harder than wrestling with intricate ones. it demands a level of individual energy and focus and a kind of perpetual improvised preparedness that is simply exhausting.

we optimize for sustenance — the continuous reaping of partial value, a kind of “winning on the way” instead of “winning at the end”. we do this because complexity means we don’t actually know where we’re going OR when we’ll get there.

we optimize for collaboration, the direct interaction of humans, because dealing w/complexity is almost entirely about the flow of ideas. ideas are the scarce resource, and collaboration is a never-ending fountain of them.

we optimize for stepping — working in small doable/undoable “not definitely wrong” units — because “definitely right” is out of reach. stepping is the only answer to the knee of predictability, which is the binding constraint of complex systems.

we optimize for narrative — shared framing stories that explain & suggest local action to ourselves and others — cuz it’s how humans deal. humans are adept at complexity, we handle it using narrative-rational decision-making, and we handle it better when we’re intending to.

so. that’s my current take. drive, sustenance, stepping, collaboration, and narrative. five “color separations” for complexity in pro s/d. the separations aren’t “easier” problems, they’re just re-framing of the existing problem towards the end of actually getting it done.