Anyway, I've been working at a client site for a few weeks now as we define and document a project. One of the subjects that needed to be addressed is one of source control. They were previously hosting somewhere off-site, and they're looking to us for recommendations on what kind of setup they'll want as they move forward. Not a problem for us, of course. We specialize in helping clients. So, for the purpose of this client, it's pretty cut and dry.
But the experience as a whole got me thinking a lot more about source control. Sure, we all have our favorite products that we know inside and out (for the most part, anyway) and it often just boils down to Yet Another Religious War among geeks who all think their preferred product is better. That's our culture, it's how we think. But, thinking about it, there's a key aspect of source control that I feel is all too often overlooked. The component of developer motivation.
Let me explain...
"Source control" is more than just a repository for code. It's more than just a repository which tracks in minute detail any changes made to code. The name itself implies a greater purpose. "Control." For it to be successful or useful by any measure, it needs to be a controlled point of access to code changes. Not just track them, but insist on tracking them. To this end, source control needs to motivate developers to use it. It's something we've all touched upon before. A source control system should facilitate what we're doing, not get in our way. It should never create a barrier to what we're doing. It should never motivate us not to use it.
Consider an example...
- System 1 has a source control repository which holds the code. There isn't really anything closely resembling continuous integration, nor is there even an automated deployment process. Deployment to any environment, be it test or production, is done by a developer. He compiles the code locally, sets up the configs locally, and copies the output to the server.
- System 2 has a source control repository which holds the code. Upon check-in (at least to the main repository), the continuous integration system compiles the code and runs its automated tests. Once everything passes, it automatically deploys to a target environment. Maybe not the official QA environment, maybe it's just an internal shared Dev environment. But it's deployed somewhere and is immediately live.
In System 1, the shortest path is to make the change, compile it, and copy it to the server. In System 2, the shortest path is to make the change and check it in to source control. The difference is clear. System 2 motivates the developer to use the source control system. System 1 inverts the motivation. Such a setup actually provides incentive for the developer not to use source control.
Sure, the developer knows the importance of source control. He wants to use it. But you know how it goes... He's just going to skip it this one time because he just needs to quickly see the result of this change in the test environment. He'll update the source control later. Really, he will. You would, right?
Both of these systems host the source code in a central repository controlled by the business. Both of them provide tracking to any code changes made in the source control system. But only one of them controls the source. Only one of them acts as a gatekeeper. Yes, in System 2 a developer can still circumvent the source control. But it's a hassle. And his changes will be over-written on the next check-in. So why would he? System 1 sits outside the path of development. It's an extra step. System 2 is the path of development.
And it happens more often than we think. Ask yourself... How do you track changes to your database schema/procedures/views/etc.? That's source code too, after all. Those are a major part of the overall system and their changes absolutely must be tracked. But even in System 2 above, how are database changes tracked?
I've seen plenty of System 2's out there which treat database changes exactly like System 1. (Hell, I've even helped design and painstakingly maintained such a setup. So I know about the motivation.) It's a question I ask when I encounter a new setup at a new job or a new client site:
- Me: "How do you track your database changes?"
- Them: "Oh, just like our code. We keep it in the source control repository."
- Me: "How are the deployments handled?"
- Them: "Simple, we run the scripts against the database."
- Me: "Manually?"
- Them: "Ya, why not? Developers check in their change scripts and then run them at deployment time."
- Me: "Doesn't that invert the motivation?"
- Them: "Doesn't that do who with the what now?"
- Me: "Well, the physical act of recording the change in source control is itself the extra step. There's no motivation to actually do it. The target database doesn't know the difference. It's source, but it's not controlled."