We've all heard the DevOps transformation matra of "People, Process, Tools" where you start by getting People on board the DevOps movement, which in turns leads to Processes being overhauled to support the DevOps mindset, and finally Tools being brought in to support the processes.
That's nice. But I often find that people will not change until a new tool is introduced that devalues or is outright incompatible with current processes, which in turn challenges their worldview and opens them to transformation.
The most notable example I can think of is Git. As a longtime Subversion user, Git challenges my Continuous Integration beliefs, most of which have been shaped by the model and limitations of Subversion:
- Merging is a pain and should be avoided if possible
- Every developer has full commit access to the repository
- Change history is completely linear--"branches" are basically an illusion whereby you replicate the entire codebase
These realities, in turn, have led to the following processes:
- Giving every developer full commit access to the mainline (trunk) to distribute the risk of merge pain among all developers.
- Having every developer integrate individually to the mainline. Don't create feature or experiment branches because that just means you'll have to merge them into trunk at some point.
- Commit ("push" for you Git folks out there) early and often, as it reduces the size of potential merges.
Merging in SVN is a pain, so when using SVN typically every developer has full commit access to trunk and everyone’s just self-integrating into trunk directly from their working copy. If they try to check in changes with an out-of-date working copy, they have to svn update, fix all of the conflicts, and try to check in again. That can be a pain when you have a lot of developers making substantial changes to the code. You try to avoid that pain by committing early and often, even if the changes you’re committing are not cohesive—a little here, a little there.
Meanwhile, there’s this mantra about not breaking the build. For SVN users, it just means that they’ve got to remember to run the local build and unit tests before they attempt to check in their changes to trunk. If you’re trying to check in frequently and having to build all the time, this can slow you down—and you don’t want to be slowed down because you don’t want to be the developer who’s got to svn update and merge a bunch of other developers’ commits into your working copy. So there’s tension there. Yeah, I don’t want to break the build, but I also don’t want to merge. Maybe I can commit, break the build and then followup by fixing the build.
Secondly, since version control systems also serve as a code preservation mechanism in addition to a integration mechanism, developers are encouraged to commit at least once a day. Personally, I always liked to commit as soon as I had a reasonably working changeset completed because the sooner you commit the less likely you’d have merge conflicts on your working copy. BUT, the pressure for committing as soon works against the pressure to preserve the integrity of the build. And if I knew some of my fellow developers were making particularly large changes, then I’d be stuck having to merge them all into my working copy just so I could check in my relatively miniscule changes.