|« LINQ in Python||Memcached set invalidation »|
Divmod has a development methodology which they call UQDS. It's billed as lightweight, but I've been using it for 6 months now and find it burdensome. The basic flow of UQDS is: make a ticket, do all work in a branch, get a full review, merge to trunk. In theory, this brings the benefits of peer review and fewer conflicts between developers. In practice, however, I've found the following problems:
So, here's my answer:
The goals of XQDS:
The strategy of XQDS:
The flow of XQDS is:
svn upon at least a daily basis, and definitely before committing. Conflicts are resolved as needed with each local copy.
Don't you lose the benefit of branching? What if Jethro checks in broken code and goes to lunch?
Don't you lose the benefit of review? Review helps avoid conflict and also teaches the reviewee.
svn upoften, and help resolve conflicts.
What if I need to share unfinished code with another developer? Or switch developers mid-feature? Or switch platforms mid-feature? Or switch features mid-developer?
svn switchand a simple folder rename when you want to put aside some work for a while.
Isn't trunk broken more often?
UQDS says it improves information flow to managers. Don't you lose that with XQDS?
Doesn't XQDS require more conflict resolution?
svn switchto a new branch and commit your (now broken) changes. You're going to have to resolve the conflict either way; but XQDS allows you to skip making a branch unless you need it.
"XQDS" is what pretty much most of us in opensource-land are doing anyway. Must it have a name ? I'm just going to forget it and then be accused of being non-XQDS compliant. Maybe call it "TOV": Timeline Oriented Development. Since a lot of the advantages you name above have to do with the path of code sticking mostly to a singular, nicely documented chronology which is easily viewable as a timeline.
Like all things, giving it a name makes referring to it easier. I'd be just as happy with "TOV". You're right about the timeline; it seems to be one of the bigger distinctions: UQDS tries to pretty up revision logs, XQDS tries to pretty up the Trac timeline. The other big difference is when/whether to branch, so maybe we should call it "TTOV" for "Trunk/Timeline Oriented Development". :P
You should check out something more modern than SVN. Using Mercurial (or git, or bzr) at the very least solves the problem of merges being one big changeset all squashed together.
XQDS is pretty much what we did at my last job. It worked fine with a team of about a half-dozen developers. We only made branches for maintenance and for substantial changes that we knew would take a long time to be ready.
To be fair, I didn't think that UQDS claimed that conflicts would be fewer. Rather just that they would happen when one is in a 'checkin' or 'conflict-resolution' type mindset, rather than in the midst of solving a problem.
On the other hand I also agree that UQDS has been burdensome for small tickets and recently many of us (ssshhh! don't tell the boss) haven't been using it as much for those types of tickets. When we get large tickets where we'd like to be able to share (potentially broken) code between developers we make branches.
I still find Combinator useful for maintaining branches and pathing between branches, it saves me having to remember and chain together multiple svn commands with revision arguments.
So in summary, I'm all for adopting a "branch only when you need it" methodology, but I won't be giving up combinator yet. :P
I've apparently been using XQDS at work for the last several years. I've been looking forward to maybe one day switching to Bazaar or GIT (from Subversion) and requiring branch reviews before merging to trunk. Your post made me think whether that would really be such a good idea.
I realize it's been quite a while since you wrote this post, but I'm just noticing it now; I hope you don't mind if I correct some misconceptions about UQDS here.
I'll respond to each of your seven points:
1.: UQDS doesn't have much to say about how the determination is made who to assign a review branch to. On the Twisted project, we assign it to nobody, and the first available reviewer picks it up. On Divmod projects, the author selects someone based on their preferences for that branch. If you are finding that reviews are not assigned to appropriate people, then determine an algorithm that selects an appropriate person!
2.: Conflict reduction isn't really a goal of using branches. The only reference to reducing conflicts in the UQDS writeup is the part that says "branch lifetimes should be short".
3.: Keeping developers on-task is a delicate art, but UQDS specifies that the branch for a ticket should be as small as possible to satisfy that ticket. I don't know why you were having this problem, but it certainly doesn't have anything to do with the process itself: the process says not to do it. If anything, UQDS gives you a specific way to say "if you go off task, put other stuff somewhere else, don't pollute this changeset."
4.: This is an issue with subversion (if it's an issue at all), not UQDS. You can do UQDS with bzr, and then you get a much richer commit history. At any rate, there's hardly any point in reading the commit logs at /, you should be reading /trunk; then you only see merges.
5.: I suppose whether the review overhead is worth the benefits is ultimately a matter of taste, but developers should not be inventing bikeshed problems. To be fair, the summary / introduction on the UQDS page is really vague about what the reviewer is supposed to be doing, but later it is much more specific: "The reviewer verifies that the code makes sense, has unit tests, has documentation, updates any existing documentation that is affected, and actually resolves the issue in question." The reviewer needs to avoid involving personal judgments of taste as required review criteria. Training people to do good code reviews is not easy, but the answer is not (as you posit in XQDS) getting them to do fewer reviews.
6.: Let me make something very clear. PARTIAL REVERTS ARE NEVER, EVER, EVER, EVER, EVER, EVER, EVER allowed in UQDS. Not EVER. This is possibly the worst thing you can do. The idea is, trunk is a queue of changes which are made. If one change is bad (i.e. causes unit tests to fail), it gets reversed; automatically, completely, and without prejudice or ego getting involved. If you start involving random cherry-picking on trunk, then you've created an entirely new unverified change. If you know that part of the change is good, then create a new branch, shepherd the thought-to-be-good part of the change through the review process, and make sure that it fully satisfies some requirement.
Point 6 is absolutely the worst thing about this post, since it suggests that what you're actually criticizing here is actually the opposite of UQDS.
For emphasis: partial reverts are not part of UQDS. They are never allowed.
7.: This is actually a pretty good point. Given that the purpose of the branch should be decided upon ahead of time, the commit message should also be written ahead of time. The reviewer should review the commit message along with everything else. We've been talking a lot lately about improving the UQDS spec to deal with this in a way similar to the way that the Bazaar developers do code reviews.
Anyway, thanks for your feedback and I'm sorry I didn't get to it sooner!
|<< <||> >>|