svnmerge, a tool to manage SVN merges

We use SVN on a project with a lot of small branches, i.e. a branch for almost every non-trivial feature. This is not a particularly pleasant want to use SVN, but it meets another important need for our project: code review on the way in to the trunk (as a “gate”), rather than code review for code already in trunk (“drive-by” code review).

Today on the XPSTL mailing list, Mike Jorgensen pointed me to svnmerge:

“svnmerge.py is a tool for automatic branch management. It allows branch maintainers to merge changes from and to their branch very easily, and automatically records which changes were already merged. This allows displaying an always updated list of changes yet to be merged, and totally prevents merge mistakes (such as merging the same change twice).”

svnmerge looks rough, but should still be a big improvement of SVN alone. It’s a ways short of what’s in the box with git, bzr, etc., but is also a much smaller step for a team using SVN.

Speaking of merging, Mark Shuttlework recently argued merging is the key to software developer collaboration. To me, this is obviously true, and not only for open-source projects, but for closed-source projects also.  If it sounds untrue to you, then you and I are probably thinking of different meanings of “merge”.

How Not To Shoot Yourself in the Foot with Change Control

As anyone with experience in a large firm knows, change control procedures (and “change control boards”) are a common fixture. Change control mechanisms (such as requiring extensive documentation, signatures, meetings, checklists, approvals, etc.) have obvious benefits, but they also add inertia, increasing the cost of change. This refers to both dollar costs (meetings aren’t free), and to inaction by employees who find it not worth the effort to a desirable change approved. The net result can be that bad procedures, features, documents, etc. stay in place, to the detriment of the organization.

Thus, I will frame Kyle’s Guideline on Change Control:

The “weight” of your change control system should be, at most, proportional to how good your product / processes are. If things are really bad, fix them *first*, while it’s easy, and then *after* that add in the obstacles to change.

Unfortunately, this ubiquitous alternative procedure:

  1. Notice things are bad.
  2. Add change control mechanisms that make it hard to fix them.
  3. Avoid changing the things that are bad.

is actively stupid. (Of course, maybe your problem is that things change too much… in that case, the first thing to change, is to make it harder to change.)

Keep Your Development Focus Sharp

Brian Button recently suggested, for XPSTL, “a series of presentations where we discuss the biggest challenges we, as team members and developers for the most part, face in our day-to-day jobs with respect to being agile. The challenges can be in technical areas, organizational change issues, or whatever else people think is hard.”

I’ll bite.

First, some background: the context here is an agile but not XP project, with a widely distributed team. The software is sold in an “application service provider” model; we usually deploy updated software weekly, though our planning is not particularly crisp around iteration boundaries. We use source control, a build server, an issue tracking system (paper cards aren’t of much use in a distributed team), unit tests, a few acceptance tests, a mailing list, Campfire, Java, and Eclipse. We build and sell an “enterprise” software product, so our product management is driven both by meeting current customer-specific needs and general target market needs.

We have listed a great number of desired features (and tasks, and bug fixes), and grouped them in to a few large buckets, which are roughly “releases” in the XP sense of the word. A small subset of those work items are considered “To Do” items, i.e. items that should be worked on now, to be deployed it the next week or two.

The ongoing challenge we face is in disciplining our own desires – in limiting the list of what we will do next, to what we can reasonably expect to accomplish soon, and then to work vigorously on getting those things out the door. Thus our goal is to, at all times, keep the team focused on a relative handful (at most a couple dozen) of key things to work on now, to bring those items to end-to-end closure.

Our challenge is in the perpetual tendency to derail the process, in any number of ways:

  • As new issues come up, there is a tendency to throw these in the “do now” list, without regard to their importance in the backlog.
  • Items get stuck waiting for requirements feedback. Either get the feedback quickly, or kick the items off your “to do” list in to the backlog, and go work on something you can finish.
  • Items get stuck waiting for integration in to core code.Items get stuck waiting for a production / deployment task, because your team is hesitant to touch a production system. The solution is to test, test, and test again, then deploy (using whatever the local process is, for your team / project / organization).
  • Items grow in scope, as they are discussed and implemented. The fix for this is to split off the additional scope in to another item (XP card) and put it in the backlog to be prioritized; trim the work item in front of you to a reasonable size and get it shipped.

All of these cause an overall derailment not because they add “bad” items, but because they reduce the focus, and thus reduce the tendency to get items finished and out the door. My advice is to keep your (team’s) focus sharp.

Conference / User Group Member Photographs

Here is an idea I picked up at AYE and again at ETech; I mentioned it at the Ruby UG last month, and am writing it up here to encourage its use.

A common problem at growing and changing groups of people (such as user group members, conference attendees who see each other rarely, etc.), is remembering names and faces. To make it easier for everyone to remember everyone else, it’s very helpful to have a photograph of each person on the group’s web site. Sorting and labelling such photos can be a lot of work, so here is an approach to get it done with very little work.

Ingredients:

  • Digital camera
  • Blank paper
  • Wide-line markers

At a meeting, during a break or at the start/end, all of the willing attendees write their name on a blank sheet of paper, in letters at least 1 inch high. Then they hold up the paper and have a photo taken with the digital camera. A low-res, head-and-shoulders shot works best.

Afterwards, transfer the images to a page on the group’s web site. By taking them low-res, no scaling will be needed. Because each person is holding a sheet of paper with their name, noone needs to sift through a pile of images, associating photos with names. Simply post them as-is, unsorted. This works amply well enough for at least several dozen people, and probably well enough for up to 100.

Refactoring to Patterns? No, learn the primitives.

Last night at XPSTL, John Sextro gave a talk on the “Move Embellishment to Decorator” refactoring as described in Joshua Kerievsky’s Refactoring to Patterns book. I greatly enjoyed and benefitted from the original Design Patterns book (from the Gang of Four) which was already old (published 1994) when I heard about it and bought it in 1998. (By the way, when I looked it up on Amazon to put in the link above, Amazon reminded me that: “You purchased this item on February 18, 1998”.)

I enjoyed John’s talk, and I hope he does more of them.  He hit a few rough spots along the way (the usually excellent IntelliJ IDEA IDE failed mysteriously, for example), but worked through it and reached the target of composable decorators. The rough spots led to some interesting diversions also.
I’m not sold on the “refactoring to patterns” idea though; it seems like a distraction from a more important goal: to gain deep experience and understanding of how to use the underlying “primitives” (encapsulation, abstraction, polymorpism, low coupling, high cohesion, etc.). Once you grasp the primitives, the design patterns are useful mainly as a tool for talking about how something works – in other words, write good code, then perhaps notice that it follows one of the “patterns”, if you find that helpful in explaining how the code works.

Several times at XPSTL, we’ve had lengthy conversations about how to choose whether to use “Strategy” or “Command” or “Decorator” or …. I’m not convinced that these conversations are helpful. My answer is that it is silly to look for a list of rules in choosing which pattern to use. Read the patterns, use them to learn good ways to use and combine the primitives. Then do that in your code:

  • Notice that you can benefit from polymorphism, and use it.
  • Notice that you can split a class in to two separately cohesive parts, and do so.
  • Notice that you could get composability by replacing inheritance with aggregation, and so so.

You’ll end up with the right “Pattern” – and you probably won’t care.

Michael Feathers at XPSTL

This evening at XPSTL, Michael Feathers (blog) (book) was in from out of town (and from around the world) and gave a talk on API design. He’s been thinking a lot about API design recently, driven by issues that come up with working with legacy code, which talks to lots of APIs, to cajole it in to a more testable state. I think there is a lot to say (maybe a book’s worth?), and a lot of what has been said elsewhere turns out to yield APIs that are unduly difficult to build testable code with.

What we end up doing here, and a thing that Michael says is not at all unusual, is to “wrap” most APIs with some application code, to enable:

  • a simplified way to call the external component / API, more suited to our needs
  • easy testing, as we can design our wrapper to make it trivial to substitute a test/mock implementation
  • a buffer from future changes in the external component / API
  • easier migration to alternate implementation of the same underlying services

Our wrappers tend to be “flatter” and simpler than the underlying APIs we wrap. For example, most of our use of Hibernate is behind a class we call DataSession, which represents the connection/session, transactions (it encodes our policies on how to use transactions) and many named methods for query operations (thus we avoid scattering HQL or SQL around the project).

Also, we had a big crowd at XPSTL – the room was packed.