We recently migrated our team's repositories (103 of them) to Bitbucket. For the past few years we had been hosting them on a Gitolite (v1) instance that we had set up at
git.designhammer.net and were maintaining on a Rackspace slice. This setup served us very well but moving to Bitbucket was an easy choice, given that we didn't want to spend our time maintaining the Gitolite instance, and the cost of Bitbucket would be about the same.
After we decided to make the switch, migrating to Bitbucket was really easy. Here's a quick guide to how we went about the process as well as some gotchas to look out for.
Bitbucket setupFirst we created a DesignHammer team in Bitbucket, invited our colleagues, and then added them to the team. Bitbucket offers the same granularity that Gitolite supports in assigning permissions and roles on a per-repository basis, as well as defining roles for different people on your team, but of course the administration is a lot simpler since its through the Bitbucket UI, instead of Gitolite's configuration file.
As part of this process, make sure your colleagues upload their SSH keys to their Bitbucket account so they are not locked out of pushing/pulling to repos.
Next, we grabbed a list of all our existing repositories. With Gitolite, you can run the command
ssh firstname.lastname@example.org info and get back a list of all the repositories you have access to. (Of course, make sure you do this as a user who has access to all the repos so you don't leave anything behind.) The output you get back is something like:
R W some-repo R W another-repo
I'm sure there is a better way to do this, but the quickest way for me was to fire up Sublime Text and use the multiple carets feature to select every line, then deleting the "R W " from the beginning of each line, so the result was:
Ok, now it's time to point our migration script at the
repos.txt file and push them up to Bitbucket. One thing to note: run this script in a temporary directory from a server you control, not from your laptop; the network speeds will be much better if this is run in the cloud.
#!/bin/bash # Usage: ./bitbucket-migrate.sh repos.txt # # repos.txt should have one repository per line. echo "Reading $1" while read line do repo=$line echo "###" echo "Processing $repo" git clone --bare email@example.com:$repo cd $repo.git echo "Creating repo in Bitbucket" curl --user USER:PASSWORD https://api.bitbucket.org/1.0/repositories/ --data name=$repo --data is_private=true --data owner=designhammer echo "Pushing mirror to bitbucket" git push --mirror firstname.lastname@example.org:designhammer/$repo.git cd .. echo "Removing $repo.git" rm -rf "$repo.git" echo "Waiting 5 seconds" echo "###" sleep 5; done < $1 exit
As you can see this is a very simple script built around
git clone --bare and
git push --mirror. These commands are important as they ensure that all tags and branches are migrated over to Bitbucket. You can also see in the API call to Bitbucket that we're setting the owner to
designhammer and that the visibility of the repos should be private. Finally, the local copy of the repo is removed so we don't fill up the server with repos it doesn't need.
After that all of our repos were mirrored over at Bitbucket, we used Bitbucket's custom domain feature to add a CNAME for
git.designhammer.net to map to
bitbucket.org. Since this takes about 20 minutes to take effect, it was a good time for our developers to do the three manual steps in the process:
- Each developer had to remove the entry in their
git.designhammer.net(since the IP address had changed to Bitbucket's).
- In each repo that had been cloned from
git.designhammer.net, each developer had to edit
.git/configto modify the clone URL. So what used to be
email@example.com:some-repohad to be changed to
firstname.lastname@example.org:designhammer/some-repo(note the addition of designhammer/). This makes sense, as the repo is now under the
designhammeraccount on Bitbucket.
- Don't forget to also use Bitbucket's deploy keys if you are checking out the repo on a server for pushing code to an environment.
And that's it! The whole process — from decision to implementation — took just a few hours, and it was well worth the effort. I hope this guide will be useful to you if you decide to migrate as well. Let us know in the comments if you have any suggestions or tips to improve this guide.
For some reason rm command not working for me.