In my last blog post I was mentioning 6 arguments why you shouldn’t use Git. While 5 arguments were obviously meant to be sarcastic (who can really think that slow operations like searching the history in SVN can be an advantage) there was doubt about one argument that can be tricky:
Git destroys the idea of continuous integration
In Git you are using branching heavily. Let’s assume everybody’s working on feature branches. Then somebody is renaming a widely used interface or class and checks the code into the mainline. If you don’t integrate your feature branch early this can result in lot’s of conflicts.
Some people favor solutions with an integration branch. People integrate the changes from their feature branch on an integration branch. If the CI-Server has build the software successfully and all tests passed, the changes get automatically pushed to the mainline. That way the mainline stays always deployable and green. I don’t like this solution: The integration branch is basically the mainline. But if a build fails, it is not so important to fix it. Not my understanding of continuous integration.
I stil prefer the SVN statement: “Commit early, commit ofter” what should be translated for DVCS into “Push early, push often”.
Solution 1: Making the mainline the communication point again
Switch from SVN to Git and work as you have before. Don’t branch, just push your changes to the mainline on your central repository. You still benefit from fast history searching, offline capabilities and much more. Just beware that if you once started with Git, you’ll probably come to use also the awesome branch features, that drags you into a different workflow.
Solution 2: Promiscuous Integration
Martin Fowler has written a great and much more detailed blog post about Promiscuous Integration. Basically people talk about changes and integrate the changes from feature or personal branch to another. The way changes got also continuously integrated in each others feature branches. When it comes down to pushing changes back to the mainline, you won’t experience lot of merging pain: Changes have already be integrated. Martin is pointing out, that this requires communication between developers and this can go wrong. There is no clear rule which changes you should integrate into your personal feature branch.
My favorite solution: Feature Toggle + Task Branch + Automatic Push!
With Feature Toggles you design your software that you can turn your feature on when it’s ready. When currently developing the feature is usually off so you can deploy the software immediately. A feature can consists of many tasks. I like the idea to have a branch for each task and push changes to the mainline when your task is done. I assume a Task Branch doesn’t live longer than 2 days. That way you still continuously integrate your changes and work focused on your branch.
You could combine this with a feature Atlassian has build in their Continuous Integration Server Bamboo: Automatic Pushing. If the mainline changes and the build went good, Bamboo is trying to push the changes automatically to your task branch. That way you have always the latest changes in your branch. I guess there is also a plugin for Jenkins available, I just couldn’t find it 😉
In my opinion this is the best of all solutions: The mainline is your communication point, you recognize conflicts very early, merging is not to hard and you have done some things to keep your mainline up-to-date and your builds green.
Another thing that your CI-Server can help you with is running a build of a potential merge. Before merging for real you can see if your build will succeed or not without pushing your changes already. Jenkins with Gerrit or Bamboo with Stash can be set up for such a workflow.
These are just my thoughts. I would like to know what your experience are with CI and Git. What works for you in your organization?
2 thoughts on “Git & Continuous Integration – Does that work?”
OK, I have to say I am brand new to Git and I’m dying for some answers here. I have traditionally used Team Foundation Services Repositories, and I guess I still have not seen the value of a DVCS. And I’d really like to if it is in fact superior to CVS systems, including Team Foundation Services.
I understand TFS is not free and Git is, or the DVCS tools out there are mostly free, I’d like to understand this from a feature vs feature level, not from a cost perspective.
Also, what is the learning curve for Git? I feel like there is a level of potential data loss when users are not checking their work directly into a centrally managed server with disaster recovery systems in place. And how do you run a build with your local branch without pushing it to the centralized repository where your build needs to run?
I’m not a Microsoft TFS expert. Bt I heard that TFS is supporting Git or will be in some weeks. Team Foundation Server is more than the repository.
So here are some resources that might help you get started:
Why DVCS: http://www.atlassian.com/dvcs/overview
Get started with Git: http://www.atlassian.com/git/
There are some free visual tools out there that helps you get started once you learned the basics about Git like http://www.sourcetreeapp.com/
There are also 3 awesome blog post how we moved to Git at Atlassian: http://blogs.atlassian.com/tag/svn_git_jira/
Hope that helps 😉