Moving a Subversion Repository to Git
Introduction
Many of our projects are now using Git for source control. oss.oracle.com supports this. But what about projects that are still in Subversion? This document describes the steps to change a Subversion-hosted repository to a Git-hosted one. It assumes this will be a shared Git repository here on oss.oracle.com backing an already existing Sourcebo hosted project.
Creating the Git Repository
Here's how you create a Git repository on your local machine that contains the entire history of the Subversion repository. The result is a bare repository (no working tree) that is ready to be uploaded to oss.oracle.com.
- Create an authors file. This matches Subversion commit users with Git author emails. Each line specifies someone who committed to the Subversion repository. You need to get everyone or the clone will fail. The format is simple:
# user = First Last <email@address.com> jlbec = Joel Becker <joels.email@oracle.com>
- Make sure you have git-svn installed on your local machine. On most distros it's packaged as "git-svn".
- Clone the svn repository to your local machine.
git svn clone --stdlayout -Aauthors http://oss.oracle.com/projects/myprojects/src/ myproject-git
The --stdlayout option is supposed to get the branches and tags right. It doesn't. It does, however, make sure that the branches and tags are stored as remote branches. Now you need to fix them up.
# For every remotes/tags/tagname # git tag -m "Message about this tag" tagname remotes/tags/tagname git tag -m "Tagged 1.0.0" myproject-1.0.0 remotes/tags/myproject-1.0.0 # For every actual remotes/branchname # git branch branchname remotes/branchname git branch myproject-1.0 remotes/myproject-1.0
- Turn the svn:ignore properties into .gitignore files
git svn create-ignore git commit -s -a -m "Add .gitignore files"
- You now have a Git repository with your project's history. The next step is to create a bare repository. This is a repository that has no working tree. It's how a repository looks up on oss.oracle.com.
cd .. git clone --bare myproject-git myproject-bare cd myproject-bare
Edit the description file. Probably should just use the same description as you have on the Sourcebo project page.
Edit the config file. You need to set up a few things. The repository needs to be shared via SetGID directories. Ref updates can be turned off; they waste space and are for working trees. The mailing lists need to be specified. You want a config file like this:
[core] repositoryformatversion = 0 filemode = true bare = true logallrefupdates = false sharedrepository = group [receive] denynonfastforwards = true unpacklimit = 5 [hooks] mailinglist = myproject-commits@oss.oracle.com announcelist = myproject-announce@oss.oracle.com
We have two standard hooks. The first is the post-update hook. It is required so that people can pull via HTTP. Create the file hooks/post-update with the following contents and make it executable:
#!/bin/sh # # An example hook script to prepare a packed repository for use over # dumb transports. # # To enable this hook, make this file executable by "chmod a+x post-update". exec git-update-server-info
The second hook is the post-receive hook. It fires off commit emails when the repository is changed. Create hooks/post-receive with the following contents and make it executable:
#!/bin/sh # # An example hook script for the post-receive event # # This script is run after receive-pack has accepted a pack and the # repository has been updated. It is passed arguments in through stdin # in the form # <oldrev> <newrev> <refname> # For example: # aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master # # see contrib/hooks/ for an sample, or uncomment the next line (on debian) # . /usr/local/bin/post-receive-email
- Repack the repository so it takes up as little space as possible.
git repack -a -d -f -l
Tada! You have your Git repository. Now it's time to upload it.
Uploading Your Repository
Odds are you don't have administrator rights. So just rsync(1) the repository to your home directory on oss.oracle.com.
cd .. rsync -aHv myproject-bare/ oss.oracle.com:/home/me/myproject-bare/
Then grab the oss.oracle.com admin to help you complete the migration.
Installing the Git Repository
This is a task for an administrator on oss.oracle.com. This section moves the repository into place and configures it for public view.
Note: Instead of the actual path to Git repositories on oss.oracle.com, I'm going to pretend they live at /git. This is just for a modicrum of privacy.
- We share access to Git repositories by the unix group system. Each shared repository has its own group. Users permitted to access the repository are members of this group. The first step, of course, is to create the group.
groupadd myproject
Edit /etc/group to add users with write access to the group. Only users needing write access. Read access is open to the world in the configuration we're creating.
Copy the repository out of the user's directory into /git.
rsync -aHv /home/user/myproject-bare/ /git/myproject.git
- Change to the repository directory.
cd /git/myproject.git
We need to set up the ownership and permissions of the repository. The repository starts out owned by repo-owner and the myproject group. When users commit changes, the new files they upload will have their own ownership but be part of the myproject group thanks to setgid sharing. We don't want the configuration changeable by everyone though. Do it in this order so that none of the fun hidden group change behaviors mess it up.
chown -fHR repo-owner.myproject . chmod -fR g+w . chmod g-w config find . -type d | xargs chmod g+s
Make sure, just for completeness, that hooks/post-update and hooks/post-receive are executable by everyone. They're owned by repo-owner.myproject but need to be executed by Apache.
The Git repository is now live. It should be visible at http://oss.oracle.com/git. People should be able to clone it via git://oss.oracle.com/git/myproject.git. Users with write access should be able to commit as outlined in GitRepositories/ForMaintainers.
Turning Off the Subversion Repository
Now that your source code is hosted in Git, the Subversion repository needs to be made read-only. Otherwise, people may accidentally commit changes there and forget to put them in Git. Note that we are only turning off the source repository. Web content for the project is still stored in the Subversion content repository.
This is also a step for the oss.oracle.com administrator.
Create an empty password file for the source repository. In the configuration directory for the project, create an empty file named passwd.turned-off. It sits next to the existing passwd for the project. We keep the existing passwd to provide access to the content repository.
Also in the configuration directory for the project is the apache file. This file contains the Apache configuration snipped for this project. We need to change the AuthUserFile for the source repository to our disabled passwd.turned-off. Again, I'm editing the paths for publication, specifying /config for the real project configuration location.
... AuthType Basic AuthName "Subversion Repository for myproject Source" AuthUserFile /config/myproject/passwd.turned-off ...
- Finally, reload Apache to pick up the new configuration.
The old Subversion source repository for the project is now read-only.
Pointing to the Git Repository
This is for the project maintainer again. The administrator is no longer required.
The project still points to the Subversion repository when visitors follow the "Source Control" link. We need to fix that and let them know about the new Git repository. We're going to do that by updating the web content of the project.
- Check out the content repository for the project if you have not already.
svn co http://oss.oracle.com/projects/myproject/content/trunk myproject-content cd myproject-content/home
Sourcebo normally generates an automatic web page describing the project's source control. This default page describes the Subversion repository. Since you have changed this to a Git repository, you need to override the default page. You do this by creating an HTML file called source.html in the content repository's home directory. This HTML file, like others in Sourcebo, is a snippet. It will get placed inside the standard Sourcebo templates when it is uploaded. Here's a good source.html snippet to start with:
<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="2" WIDTH="100%" STYLE="font-size:smaller;"> <TD COLSPAN="2" CLASS="PlainText" VALIGN="top"> Active development for my has moved to <a href="http://git.or.cz/">Git</a> for source control. <p> Instructions on how to use git, as well as general information on Git repositories hosted on oss.oracle.com, can be found <a href="http://oss.oracle.com/osswiki/GitRepositories.html">in the wiki</a>. <p> You can <a href="http://oss.oracle.com/git/?p=myproject.git;a=summary">browse</a> the myproject Git repository, or you can check out changes at: <blockquote> git://oss.oracle.com/git/myproject.git </blockquote> To clone the repository, you can use: <blockquote> git clone git://oss.oracle.com/git/myproject.git myproject </blockquote> This will create a clone of the tree in the directory ./myproject. <hr> <UL> <P> <LI> <A HREF="http://oss.oracle.com/git/?p=myproject.git;a=summary">Browse</A> source code on-line to view this project's directory structure and files. </LI> <BR><BR> <li> <a href="http://oss.oracle.com/projects/myproject/files/">Download</a> source code archives, if any are available, to copy read-only source files for this project on to your local system. <br><br> </li> <LI> <A HREF="/projects/myproject/mailman">Subscribe</A> to any of the project mailing lists. </LI> <br><br> <li> <a href="http://oss.oracle.com/osswiki/GitRepositories.html">Read</a> documentation about Git and how we use it. </li> </UL> <br><br> </TD> </TR> </TABLE>
- Add this file to Subversion and commit it.
svn add source.html svn commit -m "Update source.html for the new Git repository"
- You can also add a news article to the content repository announcing the change. You'll probably also want to email your announce list and your devel list.
Ten minutes later the new content will be live on oss.oracle.com. You have successfully migrated the source control to Git.