Source Control Workflow
At the heart of many software projects (if not all), no matter which language you use (framework, IDE, etc) you have source code.
There is lots of tools out there (git, mercurial, SVN, CVS, TFS, etc) that help us to version the code and keep it safe so valuable changes are never lost.
However when working with a team choosing a tool is not enough and a workflow has to be agreed to ensure that the same practices are applied by all the members of the team, changes are merged properly, tests run, etc.
Why? If you work with a central repository as soon as you copy the repository code to your local computer it may become out of date, thus you may need to bring someone else’s changes to have the latest version, and ensure that your changes will work when you actually push (submit) them to production.
How to do so? Well, you have to decide as a team on a series of steps (workflow) to follow in your day to day coding to agree how the changes are merged, resolving conflicts, etc. Usually branching is part of the recipe.
Branching will save your bacon
Branching is what we do naturally to write changes, new features, spiking solutions, etc.
It’s as easy as copying the source to your local hard drive, that’s a branch right there.
The better your tool is at branching, the easiest it is to make them, switch between branchs, compare branches, etc.
Why this is a good idea? To handle (with little pain as possible) scenarios like these:
- Feature XXX has to be added but while coding it a super urgent bug that has to be fix appears.
- Five new features are being reviewed in user acceptance test, only two get accepted to go to production.
- We need to modify production code for a client that has special requests, and keep maintaining both the modification and the main code.
And that’s cool, however we still have one enemy to defeat: merging.
The dreaded merge
Branches are a huge benefit once we have a merging workflow that is as painless as possible and avoids overwriting other’s developers code (who cares? It’s c!$&*^p anyways! Just kidding, just kidding….) or features.
What should we do? Let’s review some options:
One branch shared for the length of the iteration (may be weeks)
The race is on! Whoever finishes last has to deal with all the changes and do the merge, or just wait until the sprint/iteration it’s over and then someone has to merge all the code changes (I hope it’s not you). The result: we gain nothing.
Have a centralized merge guru
When is time to deploy this guru will take what he needs from each branch and solve conflicts, etc. This process is long, tedius and buggy. How does this guru know what your code supposed to do? Who better than the dev who wrote it? The result: we gain nothing.
A combination of both?
Yeah, like that would work!
To control the fear and minimize screw ups you can use a policy like the following:
- Use tests to ensure no feature gets broken.
- Branch to start a new feature or fix.
- Bring changes and merge them often (once a day? twice? as often as you need!).
- Keep the branches lifespan short if possible, no more than one or two days (or even shorter!).
- When you are done and quite positive your branch is up to date and no test are broken, merge back.
Bringing changes often will produce small “local merges” easy to handle instead of waiting to finish the feature and then try to merge with a collection of changes that may break your code and perhaps force you to rewrite a big chunk of your feature.
Every developer is responsible to bring changes and do merge before “pushing” any code to the repository making sure that all the tests are green before and after!
The longer you wait to merge, the hardest is going to be.
What about Feature Toggles ?
Some time ago at a conference I heard about Feature Toggles as an alternative solution to “I have too many merging issues and branching is a pain in the neck”.
Curious I asked what is that, and what I understood is the following:
Instead of worrying about code that doesn't work, you toggle the feature "off" and keep adding code (that may not work properly) until the feature is ready and then you release it and turn it "on" for the user.
That’s cool I thought, but what does it have to do with source control workflow, branching and merging?
How does it help? Don’t you have the same issues? Wouldn’t developers still have to merge the code of others developers? What about database changes?
You mean the code is there but not working? Why would I like to put code that doesn’t work into the app?
Do you have to turn it on in order to test it? No? You don’t test it? So how do you know is compatible with your current app? What? Am I rambling like an old crazy architect? Get off my lawn!
Having features that can be turned off is part of the application design and architecture. A choice that should be made because adds value to the final product. It’s not a solution nor an alternative for poor source control tools or weak workflows.
I can’t just start a new project, no code written, and as part of discussing source control workflow say “I know, let’s use Feature Toggles!”. You have to write code for that to happen, you have to setup the basic architecture, storage, etc. So in the meantime, until that’s ready, what do you do with the code and the merge conflicts?
Perhaps you know of a case where feature toggles is a good fit due to the environment requirements, limitations of the tools, particularities of the team, etc. And I agree, maybe in that case it is a good solution.
However is not a general source control tool nor a general merging and branching solution.
Especial case, especial solution, no more, no less.
The best tool for the job
It’s been a few years since I started to use git and I really like it. A lot. You can read online the benefits, features, etc.
When I hear about source control woes, sometimes I suggest to try git out, to alleviate branching and merging pains.
However, I have noticed some reluctance to adopt it because git is harder to learn, or more complex to use compared to the source control tool the team is currently using.
And I agree! It may seem harder than others but like any other tool, it takes a bit of time to get used to it. And the benefits are huge! After all, what do we do with best practices, design patterns, etc? Just put them aside because they are hard to learn or implement? Why source control tools should be different?
I worked with teams that some of the devs had a hard time at first using git, understanding branching, merging, rebasing, etc… what did I do? Work with them and help them out… work on a personal repository first, do the workflow together several times until they are comfortable to do it on their own.
Another reason is that git it can be used as a distributed repository, not only because you can work locally completly disconnected from others, but you can decide from which repository you are going to deploy, meaning that is that one that has the latest version.
Does that mean that you have to do the same? Not at all! Nothing to worry about!. You can still have a central repository and even use only one repo with one branch, your choice.
The git police won’t show up at you cubicle and ask you to surrender your dev badge and your GOF design patterns book!
What puzzles me most is this: If the team is smart enough to write high quality code how come they aren’t bright enough to learn git?