views:

199

answers:

11

Hi,

I'm looking for advice/experience/best-practices on how to get a team of developers engaged in a commit early commit often work paradigm while still benefitting from a thorough code review process. We currently use review board and it is policy that no code be committed to SCM w/o a peer review. While I completely embrace code reviews it appears to slow the overall process and presents a huge speed bump to the commit early commit often idea. So I'm asking for other's experience in what works and what doesn't. Do you commit early and often? Do you also use code reviews? Is there an obvious way (that I'm missing) where the two ideas can blend?

+1  A: 

I would suggest maybe switching to distributed SCM. You could do so that every member on the team commits to it's own repository. When a feature is ready for review, the reviewer is notified. If the reviewer accepts the changes, he pushes/merges them in the stable repository (which is quite painless).

Git and Mercurial (hg) are good examples of distributed SCM's

Peter Smit
+1  A: 

First of all, what revision control software are you using?

Depending on your RCS software, you can achieve both goals at the same time. For example, if you are using Subversion, each developer can commit early and often to their own private development branch. Peer reviews can be required before any development branches are merged into the trunk. Other RCS systems can most likely do something similar.

Edit: I forgot to mention that if you are indeed using a "commit early and often" strategy with Subversion (with or without development branches), developers need to make sure that they update their working copy with the changes committed to the trunk equally as often. This was a problem my team had for a while after we migrated from VSS to Subversion. We were not accustomed to being able to do 3-way merges, and developers would update their working copy infrequently (sometimes less than twice a day) which would usually require a significant amount of manual merging. Eventually, everyone got accustomed to running a svn update whenever a commit is made (we have a post-commit hook that updates an RSS feed with new commits) or, at a minimum, every hour or so. As a result, most of the merging is handled automatically and the amount of manual work required to merge a development branch's changes back into the trunk is typically trivial. This also keeps the diff between the trunk and the development branch as small as possible, which makes code review easier (since we typically focus on the diff between branch and trunk when reviewing code).

bta
I think SCM is a more common abbreviation than RCS. Also, subversion is not really known for it's easy merging. This kind of private/public repository setup is therefore doomed to fail. Distributed SCM's are made for this approach.
Peter Smit
Branches are also made for this approach.
steve_d
@Peter Smit- Just because it's not easy doesn't mean it's doomed to fail. My team has been doing it successfully for some time now. I avoided recommending a distributed system because that sounded like too big of a change to make in one step given the OP's current situation (and you know how much management likes big changes). You can start with SVN, then developers start using git-svn for the productivity boost, etc etc. One step at a time.
bta
I appreciate all the feedback! Our project originated with my suggesting separate branch work with daily merges for team-wide continuous integration. That felt overall slower and more error prone to the team so we moved to using review board based approach. We use svn for SCM. Please keep the comments coming.
Cliff
@Cliff- Private branches felt slower than running code through a review board? I would think that using a piece of software would be much faster than having to run the code past several slow humans. Also, I would not recommend daily merges. Merge the code in logical chunks (e.g., one merge contains all of the fixes for a specific bug or all of the code for a new feature, etc) no matter how (in-)frequent that turns out to be. If it's the end of the day and your bugfix is only half complete, leave it in your development branch until you can finish it tomorrow.
bta
@bta I personally don't feel that private branches are slower. The general consensus across our team was to avoid them if possible because of the overhead associated with potential merges/conflicts and the perceived slow-down. I don't want to go into detail too much about early project decisions that may no longer be relevant. I'm really more interested in how to best integrate code review w/ commit early commit often. If branches are the best answer then so be it.
Cliff
+1  A: 

Use a distributed version control system. One of the biggest drawbacks to centralized version control is that it hinders "commit early, commit often". Distributed systems encourage it.

William Pursell
I don't want to debate whether centralized version control "hinders" this technique, but it certainly doesn't prevent this technique. I have been committing early and often in a range of version control tools for over 2 decades of centralized version control systems (with the exception of the dark years where I had to use Visual SourceSafe.)
Oddthinking
A: 

Apply this method to all text-based files: break up your SO paragraph into small groups of sentences.

mcandre
Please, if you need to say this, put it in a comment. Also, you have enough reputation to correct/edit this if it bothers you.
Peter Smit
+6  A: 

All of the existing answers propose distributed SCM. This is sufficient, but not necessary. Before the existence of Distributed SCM, it was still possible to do this.

Each developer should work in their own branch (or, you may prefer to lower levels of branch-granularity such as per bug or task (especially with pair programming, or developers who work on many tasks at once). This decision can probably be left to the developer, if you have a mature team rather than foisted upon them.

Developers should commit early and often into their own branch - it is like a back-up system, which backs up at important points, and tracks what you were thinking about when you made the change.

Only merge code-reviewed branches back into the main branch.

Distributed SCM systems have many benefits, and I don't want to sound like I am against them, but if you aren't using one, that's no excuse not to use branches per developer.

Oddthinking
I believe one of the obstacles to early commits in this paradigm is psychological/ego. With a centralized VCS, even if committing to a private branch, commits are permanently available in history. A developer is unwilling to commit stupid ideas and dead ends. With DVCS, there is no such problem; you can commit as often as you want and then clean it up before publishing. The patch sequence makes you look like a genius.
William Pursell
@William: You mean with git. Other DSCMs believe in keeping history around. :)
Paul Nathan
@William, I understand your theory. My experience with, for example, ClearCase (amongst others) is that this isn't a problem in practice. Private branches don't attract much interest from other people; I cannot recall any examples of a developer commenting on code in another person's private branch. Similarly, in a corporate environment, you could probably walk over to someone else's machine and log on, but in practice people (at least in the cultures I have worked) just don't do that.
Oddthinking
Amen! And big +1. Most people are missing the point here: the tool is not the key.
Pascal Thivent
A: 

Use branching.

Example:

Devs work on their own branch on a feature branch. Review in the changes when merged against the mainline development branch. Merge in the dev branches against release branch when releases are made.

Paul Nathan
A: 

You should take a look at this Google TechTalks by Linus Torvalds: http://www.youtube.com/watch?v=4XpnKHJAok8

Linus is explaigning why Distributed SCM (like Git or Hg) lower the psychological barrier to commit, thus allow devs to "commit early, commit often" (using branches, thanks to merging being so simple in git).

Then, the peer review is done by others dev pulling in your branch into theirs, checking whatever they want to check, and running tests suites.

Finally, when everyone is happy, you can push to a "live" or "pre-live" branch which should be maintained by a thrusted team/person.

Just say something like "It's not me, it's Linus telling it!", it should help a lot :)

bPizzi
Branching is simple in most SCMs. It's the RCS, CVS, and SVN that have issues with branching. Git is not unique at all in having working branching.
Paul Nathan
Branching is always easy.It's merging and dealing with conflicts that is difficult in centralized SCM.Some thoughts : http://whygitisbetterthanx.com/#cheap-local-branching
bPizzi
"can be", not "is" - yes similar but distinctly not the same thing.
Murph
+5  A: 

We use the strategy described in Version Control for Multiple Agile Teams - works also for a single team - and it works great for us.

Below, an illustration for a whole iteration:

alt text

And a very short explanation:

  • The trunk contains DONE DONE stories, it has a releasable policy (can be released at any time).
  • Development is done in work branches (one per team), they have a softer policy (unit tested).
  • when a story is DONE, it is pushed from the work branch to the trunk.
  • Merges from trunk to work branches are done every day.

We include "code reviewed" in our "Definition of Done" so a story can't be published from a work branch to the trunk if the code hasn't been reviewed. However, people CAN commit early and often in the work branch of their team (as long as the code is unit tested).

I've used this approach on several projects, multiple size (small project with a single team to huge project with multiple teams), with different VCS including Subversion with success. And I recommend reading the whole paper.

Pascal Thivent
I appreciate your thorough explanation and graph. This sounds like a policy that I could be comfortable with though it implies a certain amount of overhead associated with each merge/conflict resolution. It actually inverts the main issue that drove me to ask this question. We have constant conflicts and lots of rework due to changes sitting too long without an official "ship it".
Cliff
@Cliff My experience with this strategy is that you don't get that much conflicts (because people are focusing on specific parts). Sometimes, you get some but most of time, you don't, and its much easier to solve them early anyway. Now, you clearly have to change something somewhere to solve your problem (since your current policy prevents a commit w/o code review) and in my opinion, having separate branches for ongoing work and releasable code is the natural solution.
Pascal Thivent
Consider adding additional (ad hoc?) branches per developer/pair for situations where you want non-unit-tested code to be committed (e.g. in the middle of a large refactor.)
Oddthinking
+1  A: 

Can't comment so - the strategy with different levels of branches (Pascal's answer) is great. However, I think one thing you would want to clear up is whether "commit" equals "release". It shouldn't.

What we have been doing with a single team per project was that developers commit when ready, however the commit must not break unit tests harness (similar to "unit tested" policy in the workflow from Pascal's excellent answer). We have a test server running straight from the repository and updating after each commit (we do web apps - this is equal to having a build of your software every commit or every day). Everyone can access that server, including the POs and stakeholders - in fact anyone who wants can play with it and provide feedback.

Now, code reviews are assigned as explicit work on the sprint backlog to each item. Items that have not been through code reviews are not considered completed and are not part of the shippable increment that is released at the sprint's end.

In this scenario "committing" means sending your code to the repo. Your code will be visible to others, it will be also visible working on the test server (if it won't break something). The psychological barrier is much lower than if committing meant sending something that is considered releasable. Still, each developer knows their code won't be really released before a code review and they will have to wear a funny-looking hat for the rest of the day if they send a commit that will break unit tests.

As for code reviews taking time - well, this is time well spent, time invested towards higher quality of the product. Well worth it.

Andy
+1  A: 

If you're looking for a blend, may I suggest adopting a new policy: that code produced in pairs doesn't require a code review.

Pair programming provides the same value as a code review, allows excellent knowledge transfer, and helps novice programmers (and sometimes experienced programmers!) learn quickly. Of course, it brings its own challenges... none of them insurmountable.

Lunivore
A: 

The team I am on has adopted a similar policy that no code is committed without a review, but the way we address that is to do almost exclusive pair programming. Some might argue that that does not constitute a "review", but it does ensure that at least two developers went over the code, design, test. On check-in, both reviewers enter their initials for tracability.

Not sure if that will work with your review board, but something you might want to consider.

mdenomy