This site will look much better in a browser that supports web standards, but is accessible to any browser or Internet device.

Anomaly ~ G. Wade Johnson Anomaly Home G. Wade Home

February 28, 2015

BPGB: The Witch Hunt

For the next entry in the Best Practices Gone Bad series of posts, I have a topic I wish I had thought of.

In issue 125 of Overload magazine (Feb 2015), Sergey Ignatchenko wrote an article entitled Best Practices vs Witch Hunts. Sergey covers a somewhat different approach to how best practices go bad. He walks through a series of steps leading from identifying a practice that a few teams find useful, through declaration as a best practice, to an end point of applying the practice religiously without regard for whether it is appropriate.

One thing I don't think I have described well in my posts is the point that best practices are trade-offs, just like everything else we do in development. Since any best practice is really a rule of thumb that works in many, but not all circumstances, you can't enforce a best practice without thought. Sergey does a good job of getting this concept across in his article.

Many of the best practices gone bad that I've described (and more that I intend to) only become a problem when someone uses the practice in a place where it is not the best trade-off. Sergey covers how people can become zealots enforcing a best practice to the point that it becomes a BPGB. He also touches on the social aspects of this kind of failure. I definitely recommend the article.

Posted by GWade at 10:25 PM. Email comments

February 14, 2015

BPGB: Feature Branch Fail

The past few generations of version control systems have really good support for branching. This feature allows someone to create a new line of development that is separate from the official main/master/trunk line of development. Changes made on a branch do not affect the main development until they are merged to the main branch.

Shortly after people become comfortable with branches, they notice that branches can solve the problem of big changes breaking the master branch.

Feature Branches, In Theory

One workflow used to keep the master branch clean is Feature Branches. The idea is to create a new branch for each bug fix, change, or new feature that you want to work on. As long as the change is not complete, you continue making changes on your feature branch. When everything is working satisfactorily, you merge the feature branch back into the master branch.

For small changes, this works incredibly well. Different people can work on their own tasks independently of each other until they are ready to merge. Nobody else's changes affect your work until you are ready to merge. Everything seems wonderful and bright.

The First Cracks

The first problems in this perfect workflow occur when two people make overlapping or conflicting changes. The second person to merge gets a merge conflict and/or failing tests. This is actually not that much different than the problem with doing all of the changes on the master branch. Modern DVCSs usually handle the textual conflict pretty well. A good test suite will usually uncover semantic conflicts pretty quickly.

This means that no one tends to see this as much of a problem.

Long-running Feature Branches

Feature branches work pretty well for the short term, but what happens as the branches live for longer?

The longer the feature branch stays disconnected from the master branch, the more potential conflicts build up. The advantage of having changes to the master branch not affect your feature branch comes at a cost of merge pain later. Doing regular merges from the master branch into the feature branch can mitigate this problem at the cost of more frequent, smaller potential pain points.

Just as importantly, the longer the feature branch runs, the more changes it collects relative to the master branch. This means that when the feature branch is finally merged, it will probably cause disruption to anyone else working on master or their own feature branches.

Positive Feedback

Probably the worst part of this problem is an annoying feedback loop caused by merging. As long as merges go well, people are willing to do them regularly. When a merge is conflicted, however, the developer may find they have an aversion to doing frequent merges. After all, if any merge could be painful, we probably want to reduce the number of opportunities for pain.

Unfortunately, the longer you go between merges, the more likely you are to have merge conflicts (all else being equal). This reinforces your idea that merges are painful and makes you more likely to put them off. This positive feedback loop can pretty rapidly create worst case feature branch merges.

Dependency on a Feature Branch

Another fun failure mode for feature branches is when someone creates a feature branch that depends on an unfinished feature branch. This shouldn't happen often, but it becomes more likely the longer a feature branch lives.

As an example, let's say that Bob is working on a long-running feature branch that replaces the logging system used by our server. Sue starts a new feature to add fail over capabilities to the server allowing us to have more than one server at a time. In working through the problem, Sue realizes that Bob's new logging would make some of her work simpler. She merges Bob's changes into her feature branch after talking with Bob to learn how the feature can help.

The problem occurs when Sue finishes before Bob. She merges her code into the master branch and suddenly Bob's unfinished code is part of the system. This partial code now ripples into every feature that is keeping up with master. If things go well, Bob can finish his feature soon and merge it in. If his code really isn't ready for general use, then everyone is at least partially broken for a while.

Conclusion

Short-lived feature branches are a good idea. The longer a feature branch lives, the more effort is needed to keep potential problems in check. People who are new to this workflow often get stuck on the idea of the independence of the branches and don't realize the problems lying under the surface.

Posted by GWade at 12:27 PM. Email comments

February 02, 2015

Git for the Solo Programmer

Despite the press in recent years asserting the software development is always a team activity, there are still individual programmers building software without help from others. I've recently had a question from one such individual asking if version control makes sense for a developer working alone.

Despite working in teams for years, I also work on quite a few solo projects. In the past, I always added projects to version control (whichever system I was using) once it reached a certain size or level of complexity. Any time I started to worry a little about a change that I might not be able to back out, I would stick the code into version control.

And so it begins...

A few years ago, I started using git. While I am still not a complete believer in the git way, there's one feature of git that has caused me to convert all of my current home projects: it is extremely easy to set up a git repository. It's so easy, in fact, that there's no reason not to.

But, Why?

For those that have never used version control on a small project (or at all), I can almost hear your question. Why bother? What does version control in general and git in specific do for you?

Ad hoc version control

If you haven't used a VCS before, you've probably dealt with changes to your software in one of a very few ways:

  • There's always one version of the code in one directory.
  • There may be one (or more) extra copies on your system that you are experimenting with or trying to keep pristine.
  • Every now and then, you zip (or tar) all of the code and store it somewhere so you can recover if something goes wrong.

These approached can work on very small projects that don't change much. But, if you hand a copy of the project to someone else or need to make extensive changes at some point, these approaches are much harder.

Since git is going to add steps to your workflow, it really needs to provide some benefit to offset the cost.

Didn't it used to do that?

The first thing that it gives you is the ability to look at earlier versions of the project. All of us have had the problem where a tool we use all the time used to work and now it doesn't. It's sometimes hard to tell what change caused the problem. Using git, we can look back to see when something changed. If you write good commit messages when you make changes, you'll know why it changed.

Which version did I give to Fred?

The second thing you get is the ability to name particular points in development. Any time you have a specific version of the code that you want to be able to retrieve at some point, you can add a tag with git. For example, I'm using the program on my main system and I want to copy a version to my other computer. Setting a tag at that point is probably a good idea. Another point would be when I give a copy of the project to someone else for some reason. A really good reason for a tag is right before I make a big change. I'm going to change the program from using a text file to using SQLite. I'm upgrading the script to work on a new version of the OS I use. Any of these changes might break the project and I want to be able to get back easily.

I've got a cool new approach

The third thing you get is a freedom to experiment. It took me a few years to really grok the wonderful feature that this is. Let's say you think you can make your project much faster by changing some fundamental part of the design: different libraries, new algorithm, an all-nighter doing micro-optimizations. Before you make any changes, create a branch with git. Now you can make all of the changes you want over as much time as you want and the original is still safe on the master branch. If you decide this was a bad idea and you don't want to continue, throw the branch away. If you need to fix a bug on the real code even though you aren't finished with the experiment, change branch to master, commit, and come back. When you eventually get everything the way you want, merge the branches and life is good.

It's Part Mental

It's really hard to convince people how much version control does to reduce mental stress. If the project is something you rely on, every change brings a small worry that you might break something, or you might lose something that you wanted. This worry adds some mental stress the whole time you are making changes. Depending on the change, the worry may continue after you finish. There's that did I really test everything feeling.

Also, if you have multiple copies of the project you'll always be wondering which copies are up to date and which are not.

Using version control can relieve this stress. Amusingly, many of the people I have talked to that made this transition really didn't think of it in these terms. They were just happier with their work.

The ability to do experiments cannot be over-emphasized, though. It's amazingly liberating to be able to try hare-brained ideas without messing up your normal code, and have an easy way to go forward or back depending on how things turned out.

Posted by GWade at 08:20 AM. Email comments