This article on Making Small Commits lead me to think about when to commit and when to branch a code base.
Branching is the black art of version control, and anyone who has tried it at least once has probably had the nightmare that arises from having to merge code back in.
It’s an art worth learning, however. Sometimes you’re working on a feature, or a refactor, that’s significant enough that you can’t risk partial checkins.
Now, for context, I’m a big believer in frequent checkins. Beyond the advice in the linked article, I tend to check in almost any change. Add a method? Check it in. Add a single unit test? Check it in. Version Control is my brain and my undo. I’d rather revert a version or 10, but be confident, than realize I need to go back about halfway through my current rewrite.
Given I like, and in fact need, to check in often, I feel I probably need to use branching more often, as well. An recent example was work we started for a client. Right after integrating the first elements of the new features, the client changed the current request. Entirely. However we were stuck deep enough in a combination of new elements not yet finished and concurrent refactoring that it became easier to comment out large sections of code than refactor. If we’d just branched the new feature set, and continued maintenance on the trunk version, we would have saved ourselves frustration - and the risk that comes from half-finished features that probably won’t ever make it to the top of the backlog again!
What is your philosophy on branching your code base?
April 23rd, 2008 at 6:19 pm
My experience over the past 10+ years is with the CVS/SVN set. I’ve settled on basically not branching unless necessary with them. For most “move fast, get it done” projects, that means you might have a dev+qa+staging branch and a live branch.
For projects that need more control, you’d have one branch per change request (2d-3w of work), but merge behavior gets murky after dev. QA folks would probably use the change request branch, then it’s merged into a UAT branch for UAT, and then merged into staging to allow eventual launch. This is more pain than the basic branching, but also falls apart if the client changes their minds and wants to launch something different than what was dev’d or uat’d … or if there are significant changes in UAT.
I’m playing around with git as a different approach. In git, individual commits can be merged separately between branches, so you can easily “rebase” (i.e. bring arbitrary changes from trunk back into a branch) at will, and merge back to trunk, without causing undue conflicts. It could have the effect of having us branch once per change or once per ticket … we’ll see.