Check In Early, Check In Often

@T.E.D. :

If you use something like SVN, you should have a branch for your code in progress. Commits to that will not break the main build, which is in the trunk. That way you’re able to do lots of little incremental commits without affecting anyone else. It’s great to be able to revert back to your last checkpoint, if you ever do something to screw things up in a major way (global searchreplace, etc.). When you’re code is finally finished, you then merge your branch into a local copy of the trunk. If it compiles,runs,passes tests, etc. then you commit the new trunk (and create a new branch for your next project).

Perhaps what we need is a model of software accretion. Start with a tiny fragment of code that does almost nothing. Look on the bright side – code that does nothing can’t have many bugs! Test it, and check it in. Add one more small feature. Test that feature, and check it in. Add another small feature. Test that, and check it in. Daily. Hourly, even. You always have functional software.

Test Driven Development

Where have we heard this story before? Yeah, I remember, test-driven development and eXtreme Programming. Good to see those ideas spreading amongst .NET practitioners too.

sounds like Test Driven Development
http://en.wikipedia.org/wiki/Test-driven_development

or maybe the test-first concept of Extreme Programming
http://en.wikipedia.org/wiki/Extreme_Programming

I agree that painless merging is absolutely a strength of DVCS
but this is also possible via branching and merging in centralized systems

Yeah, people talk about how that is a big feature of distributed systems, when it is actually just a nessecary component of them. There’s nothing about distributing a revision control system that magically makes them merge better. But if they didn’t, then they’d be a real PITA to use.

What’s really different about distributed systems is that you have much better control over who sees what changes and when. That makes it much more difficult for a single sloppy developer to break everyone’s build. It also means you can set up complex repository relationships that better match your internal working relationships.

Also (with Git at least) its much easier to work from remote locations with slow or bad network connections. That’s because it only needs to communicate when doing merges.

Perhaps what we need is a model of software accretion. Start with a tiny fragment of code that does almost nothing…Add one more small feature…Add another small feature…

In Ye Olde Days we called that UNIX.

… small pieces, loosely joined …

What you are really talking about, is continuous integration.

The problem with checking in too often is that your development team end up consuming a fair amount of resources on these auxiliary things. While a necessary aspect, we still want to focus our attention on the problem at hand.

Branching in current state-of-the-art centralized SCM is cumbersome and impractical so not really an option, distributed SCM solves this problem as many pointed out.

As long as you have mechanism in place to enable cumulative code reviews (i.e., a feature spanning many check-ins), then I think there’s nothing wrong with lots of little commits. But problems arise if you have lots of uncontrolled check-ins and no way to see the big picture for review once things are done.

We’re using Crucible for this right now, which is working out great.

If you use something like SVN, you should have a branch for your code in progress. Commits to that will not break the main build,

Yes, I know the theory. However, that’s not the way one needs to work, its jut one way to do it.

Let’s take a step back here. The chief purposes of revision control are:

  1. Coordinate changes between multiple developers.
  2. Keep track of old working versions of the program so we can rebuild them or fix bugs in them if need be.

Two auxillary things people often end up using revision control for are:

o Keeping track of old non-working versions of source files, just in case you need to start over from that point for some reason.
o A file backup system (assuming your repository is backed up, and easy to recover when corrupted).

If you want to use your revision control system that way, that’s fine. It creates a lot of junk branches and revisions, but that’s not really a huge problem for most people.

However, there are other ways to do those things. A good editor (eg: emacs) will keep old versions of files around for you. I have mine set up to keep the last 10 versions. VMS used to do that for you too.

Working out of a directory that is periodicly backed-up is all you really need to do for backups. If you can’t do that, then you’ll have to periodically copy your work into a place that is backed up just to be safe. Leveraging the revision control system for this does seem sensible. However, if your dev machine is being backed up, you really don’t need to use your revision control system for backups.

Sounds a lot like the Open Source Mantra - Release Early, Release Often. As always, great article (i’m always looking forward to the next coding horror post in my google reader).

http://www.samalamadingdong.com

I pretty much check in whenever I’m at a solid state… not nessassarily done, but not breaking things either. I like having a point I can go back to if I really mess my code up, and I get a warm and fuzzy feeling know that even if my computer goes toes up, my code will still be there. Don’t check in code that is going to break any functionality of the app.

Also, somewhat related, I try to check in as often as I can because the merge tool in Visual Studio 2005 seriously sucks. There are times when I need to merge things and it won’t allow me to choose the code from which file to take, and other times it lumps a block of code together when I really just want to keep one line out of it, but I’m forced to take either the whole block from one file or the whole block from another. Checking in often, you avoid most of these headaches. And if it doesn’t merge right, you don’t have that much to do to fix things.

I became convinced of the value of short check-in cycles over a decade ago after watching Jim McCarthy’s presentation How to ship great software on time. But I’ve worked with a number of people who just don’t think that way and no amount of persuasion or policy will change their minds.

You know it’s funny that you and Damon point out that developers don’t check in because they are afraid of breaking the build. I had an experience quite the opposite. We had a developer at my work who wasn’t checking his code in, even though he made sure it would never break a build, yet was releasing it to the Dev and Integration servers. When I got the go-ahead to release my code I got latest and pushed out all files (which is standard practice where I’m at), which subsequently broke the build since he hadn’t checked in anything he was working on. Thankfully he still had it locally and was able to integrate. He was of the mind that someone might find bugs and he would still have to work on it. We had a nice chat on why he needs to check-in code before he releases to any server.

Not being able to check something in makes me feel unsafe :stuck_out_tongue:

Whenever it compiles and is filled with // TODO: … comments inside stubs to describe what I’m going to place there, it’s checked in. Makes you go home with a good feeling that it’s being backupped, and visible in case you suddenly fall sick

@T.E.D: Working out of a directory that is periodicly backed-up is all you really need to do for backups.

Wow! What a great idea!

I think I can even improve on that, though. You could use a batch file (or shell script) to compress the files and copy them into that directory!

Oh, wait… I’ve done that before. Back in the '80s.

This blog really needs a section called Bleeding obvious

this is also possible via branching and merging in centralized systems

It would if merging wasn’t such an ugly pain, an history loser (at least under SVN) and so badly supported.

In other words, it isn’t.

I go on the approach of Always check in the code, even if it doesn’t work or isn’t finished, you’ll still be able to change it later!.

Code that isn’t finished is ok, but code that doesn’t work is only ok for small enough values of doesn’t work: if your changes make it impossible for others to work (because you broke compilation, or features, or…) then you don’t under any circumstance commit it to the central/team repository.

Yeah, people talk about how that is a big feature of distributed systems, when it is actually just a nessecary component of them.

Erm… it’s both? Just because it’s necessary for DVCS to work correctly doesn’t mean it’s not a feature.

yet was releasing it to the Dev and Integration servers

How come he was able/allowed to release code that hadn’t been committed in an SCM?

Oh, wait… I’ve done that before. Back in the '80s.

Actually, Linux development worked that way until they started using Bitkeeper, and in his Git presentation (@google) Linus stated that timestamped tarballs were – in his opinion – vastly superior to CVS (or SVN)

software accretion is how I’ve always done all my development, that’s how it always used to be done back in the day. Checking in at least a couple times a day and making sure my changes are stable (nothing to do with complete) at that time.

A great reason to turn off check-in policies in TFS. It’s an automated roadblock on the last mile of your journey. Why should I care if your Code Analysis rules don’t pass? Let me check in!

Hmmm…

  • Mandatory Code Review
  • Check In Often

Choose one.

I would be curious if someone knows a ways of doing both without crippling team productivity. Thanks.