The following content was taken from Atlassian.com
This is the third blog post of a three part series where we focus on migrating the Jira code base from Subversion to Git. We wanted to share Atlassian’s migrating experience to those of you who are contemplating moving a large project to Git – without sacrificing active development. In our first post we discussed why we decided to make the switch to Git. In our second post we dove in the technical details of switching from Subversion to Git.
Migration – The Human Side
So you might know that you can run a pretty slick migration from the technical side, minimize commit downtime and ensure high availability of your supporting infrastructure. But are your developers ready for the change?
The opinions of Jira developers on the migrations varied from, “Git is the most wonderful thing to ever happen to Jira,” to, “I know Git’s better than SVN but I need training,” to, “Just show me how to do what I currently do in SVN in Git”. It’s critical to address the needs of developers across this spectrum.
The VCS you use (along with some other core things like programming language, IDE, frameworks and libraries) is one of your core tools and one of the key areas where you develop skills. Your VCS is the vehicle for technical communication and collaboration. You need to ensure that all developers are fully on board to maximize their own potential. If a developer has any uncertainty or hangups about the tools they use – particularly their VCS - their work can be severely impeded. Atlassian prides itself on openness – people are encouraged to speak up and risk falling flat on their face rather than not speak up at all – but there are all types of companies where we can envisage people hiding, not speaking up about issues if they’re not comfortable.
Also, developers worth their salt feel a connection to the code they write and their infrastructure. The most productive developers feel an ownership of their environment. If you are going to change that environment, like their VCS tool, it needs to be a change that they own and embrace.
1. Your team will need training
Assuming that everyone in your organization can learn Git on-the-fly after the migration is finished is a recipe for failure. Git is fundamentally different to SVN. Being aware of this, making your developers aware of this, and preparing them for Git is critical in making the migration a success.
The first thing we did to get our developers ready was to run a couple of Git training sessions. For example, we started out with, “How to do what you do in SVN, in Git.” This included Git commands for things like committing and demonstrating what tools are available (developers at Atlassian use their IDE, SourceTree, gitg, and the command line to work with Git). More importantly, it focused on explaining the key differences between SVN and Git. What does it mean to have a local repository that’s a clone of the remote repository? What is a working copy? What is the staging area? Finally, a step-by-step guide to cloning the Git repository and getting started fast was introduced and published on our extranet.
Further, Charles Miller (our Confluence Architect) ran a seminar that was a real deep dive into how Git works internally – what data structures it uses internally, and how actual operations like committing work get done. This was optional for all developers, but some people learn by deep investigation which helps onboarding. Also, the more you delve, the more you discover that Git is a wonderfully elegant architecture internally which is valuable for any computer scientist to learn.
We developed these training sessions internally, however there are a number of external companies that run Git training if that is your preference.
2. Your team wants to know how the migration is proceeding
While we were running the migration, we kept the team up-to-date on the migration status via email and HipChat, our real-time group chat offering. Every time we reached a milestone, we let the team know. Every time we changed infrastructure, we let the team know – partly as a warning in case things break, but also to keep them updated on how things were progressing. It’s a satisfying feeling when you say to a team member, “Hey, you know that code review you just created, you actually created it off the Git repository,” especially if you can pull it off without anything failing during the change. This regular communication, from within the team, was huge in making each developer feel like they were up to date and owning the change. The worst outcome is if the team feels like this change is forced from outside, or if the tools they use every day are changing under their feet without them knowing.
3. Your team will need “Git champions”
Let me say this once again: Git is different to SVN and it can take a while for people to adapt. No matter how much you prepare, how much you educate – developers will run into issues when they start actually using it. Left unattended, these issues will reduce productivity and can spiral into hostility to change.
We marked a couple of developers who had Git experience as ‘Git champions’ after the move. Any time people had issues, or didn’t understand things, or just wanted to know, “What did I just do?” or “How did it work?”, they could pull in a Git champion to help them. This was critical to making the change as seamless as possible.
In practice, we found the major difficulty people encountered was not the differences between commands, but the differences in the conceptual model of working copy, local repository and remote repository. Developers had internalized the SVN model. I would say it took 2-6 weeks for each developer to reach the same familiarity with Git.
4. Don’t change your workflows too much too quickly
There are a number of really advanced Git workflows out there that allow you to put the “D” in DVCS. Branches, feature branches, forks and pull requests are just the start. If you switch to these advanced workflows at the same time as you migrate, you are either Albert Einstein leading a team of Nobel laureates, or you are setting yourself up for a fall. We took the principle of “success through stability” into our workflows as well. We started off with exactly the same workflow we used in SVN:
- one or two stable branches for bug fixes; and
- a master branch for new development work
As I mentioned above, our SVN workflow for getting bug fixes from stable to trunk was to manually patch each commit. We kept this workflow when first migrating to Git – each bugfix commit is manually cherry-picked into master. Why would we do this? Git is designed for merging – wasn’t it part of the reason we migrated? To maintain stability, we felt that the change to Git itself was big enough for developers to take on and that changing workflow would only complicate things.
5. Make small, iterative workflow changes
We made our first workflow change about two months after the migration – no more cherry picking. Stable branch merged to master with each commit.
Again, we invested in communicating this change to the team – the motivation why, and a series of steps for how to do it. We re-awoke the Git champions to assist people anytime they had a difficulty. It proved to be a smooth, easy transition. Making small, understandable, iterative changes is what made each change a success.
The Current State of Play – Distributed VCS, Decentralized Development
Once we had settled into a merging workflow, we started embracing the distributed workflows that Git enables.
I mentioned at the start of the article that one of our major products, Jira, now releases to our hosted platform every two weeks. We tend to run with separate teams in separate branches; this enables frequent releases by decoupling separate teams’ work from each other:
- On the day-to-day level, one team’s changes do not affect other teams. Did Team A break the build? That’s not a problem. Their changes are isolated to their own team – they only broke their own build and no other team’s development speed is affected.
- On the two-weekly release level, one team not making the cut does not affect the release. If Team B did not get all their stories over the line, they do not merge back at the end of their iteration. The release can go ahead with everyone except Team B’s stories.
This does introduce challenges of its own. Merging multiple sets of changes at the end of an iteration runs the risk of integration conflicts that can cause bugs. In practice, this is mitigated by the fact that individual teams tend to be working on separate areas of the code base. However, if a team or teams are working on areas that are likely to conflict with other teams, they tend to work directly on the master branch. The teams that are running on individual branches pull regularly from master to get these changes regularly and catch the conflicts before they become critical. Thus far, keeping the lines of communication open has prevented these sorts of conflicts from becoming problematic.
Another complicating factor is geography. Jira’s main development is done in Sydney and Gdansk; but on any one day we might get commits from Atlassian teams in San Francisco, Boulder, or Amsterdam. Teams in different cities tend to run on different branches allowing us to get over the communication gap. To facilitate communicating the kind of potential conflicts I mentioned above, we use HipChat (our group chat product) for 1-1 and group announcements and communication; this works extremely well with our distributed team members. The real-time chat rooms kept conversations persistent so when someone logged on from a different time zone, they could check the status of the conversation and get quickly up to speed. Developers were pinged when they were mentioned in a room so they could respond to someone’s query without having to read through the whole conversation.
A quick note on branch strategies: some people advocate a ‘branch-per-feature’ workflow, where each individual story is developed on a feature branch. This is a great workflow if it fits your project. Some products at Atlassian use this. In Jira, our CI overhead is very high. Running what we would consider ‘adequate’ CI on every story that gets developed is not within the bounds of reality for us. Branch per team, however, is working out well.
The migration turned out to be a great success. No developers’ time was lost in limbo where they could not commit. CI ran continually, and we maintained the ability to do a 5.0 release throughout the entire migration. Post migration, we hit each change successfully and today, developers are embracing the power that DVCS gives them. The proof of this is in the complete change in our release cadence. There is no way we could have shifted from a 90-day to 14-day release cycle without DVCS.
This is probably the fifth time I have mentioned this but I cannot stress enough the importance of communication to the rest of your development team. During the migration, do not be afraid of giving it a higher importance than the actual technical migration tasks. It gets the developers to own the change. For those reticent to change, communication decreases worry and helps developers love Git.