My development team is considering alternatives to our current version control system (SVN). Over the weekend I decided to take the opportunity to read up on Git. I've had my eye on Git for quite a while because it is so popular in the open-source community. Many open-source projects are hosted on Github which is arguably the most popular Git hosting site. After reading the first third of Pro Git(free to read online) by Scott Chacon I started to see why Git was so popular and eventually made the decision to completely switch over and use Git with all my personal projects. I then went to my team and proposed that we switch to using Git for our work projects as well.
At work our development pattern with SVN looked like this:
Every release we would run a build script that would check out a copy of the code from the trunk branch in our SVN repository and publish that code to our staging server. This script would also create a "release" branch at the same time. This would ensure that the release branch had code that matched the code that was updated to live. We would then continue development within the trunk branch before our next release. The problems occurred when something slipped through the cracks and we had to patch something on live with a "hotfix". The developer would have to map and pull down the entirety of the release branch from SVN. He would then make the fix and check it into that branch. We would then release to live from our release branch. Well now trunk is out of sync so we have to then duplicate the change in trunk. One would think you could simply merge the change into trunk but something about our build process prevents that from ever happening smoothly. It's always easier for us to just make the change twice than it is to fuss with SVN.
Git makes branching and merging so easy because when you clone a repository you bring all of its branches with it. You don't even have to map different branches to different directories like you do with SVN. When you switch a branch in Git the working directory for your project actually changes to match the branch you're on. All the files and the directory structure change instantly when you switch branches. You read right, instantly. Because everything is stored locally it is able to pull out entirely different versions of the source code and swap them. This is the beautiful part of git. Branching is so simple and merging branches together is also extremely simple. Because Git encourages lots of branching I re-designed our development workflow to take better advantage of this.
The diagram seems a little more complicated on first glance but it's really not. We essentially turn the master branch into a base-line as it always reflects what is currently on the live server. There is only ever a minute or two between when you merge code into master and when the code is pushed live. Git allows us to branch away from our live master branch and work on our tasks for our development sprint off to the side. Also because branching is so easy it makes sense for each of the developers to then branch off of that development branch and perform their tasks in their own branches. This is to mitigate the issue we sometimes have where one developer will commit unfinished code and break the build for everyone else. With our own branches we can break our own builds all we want and it only affects us.
Once a developer finishes a task they simply merge their branch down to the development branch so the other developers can pull the change up during development. This provides the same continuous integration that we get when we all work in the same repository without the accidental commits of incomplete code that breaks the build. Since we know the master branch reflects live code this also presents us with the opportunity to easily implement hot-fixes. All we need to do is create a temporary branch off of master, make our fix and test it, then merge back into master and release it. After that we can then merge the fix up from master into the development branch and then each developer can then bring the change up into their own branches with their regular merges just like they do when they bring up other developer's changes.
I'm pretty excited about this new workflow and the opportunities it will afford us as a team. This, combined with some other changes we are making to our release process will help us to maintain a stable environment on the live server and an agile development process where we can perform structured work as well as react quickly when we need to.