- Pick a ticket N from our bug tracker (it's TRAC, with some customized statistics modules I wrote and a handful of third-party TRAC-hacks for planning purposes),
- Update my git repo from SVN with
- Start a git branch for my work on the ticket with
git checkout -b ticket-N,
- Do my thing, with as many commits and experimental branches as needed, and then clean up (remove debug-commits, maybe merge some small steps), with
git rebase -i,
- Rebase onto the updated upstream SVN with
git svn rebase,
- Push the whole thing into SVN with
git svn dcommit,
- Drop the branch, since it's in SVN now; the detached commits will get garbage collected eventually.
- Figure out what part of the repository is interesting; for me, that was the development/ branch in SVN, from revision 28754 onwards.
- Figure out who is committing to the repository. SVN has the usernames, while git needs to have a name and email address. This requires a map of SVN authors to git authors. It's also pretty much essential that the author in the mapping file matches the author and SVN username you configure in client-side git clones, or you'll get a multitude of branches, all twisty and all very much alike. After some history examination (in SVN) and discussion on useful git author names with the other developers that might use git, we ended up with a file like this:
adriaan = Adriaan
bassie = Bassie
I ended up committing this file into SVN so that it would be available -- and could be updated -- for general use. It lives in
development/.git-authors, ie. in the root of what I'm going to follow with git.
- Do the initial clone of the repository. Unlike the recipe here, I have an authors file (a copy exported from SVN, because it's got to be there before the clone runs), and I don't use the standard layout. I did this on the server, so that the SVN repository is local. The repository lives at
/home/svn/project, and the fetching repo will be git-project-fetch
git svn clone -A author-map -r 28754:HEAD file:///home/svn/project/development git-project-fetch
- Set up the bare repo, which will be git-project:
git init --bare git-project
- Configure the fetching repo to push changes:
git remote add origin ../git-project
- Then modify .git/config so it reads as follows (again, this is all according to TF Nicolaisen's recipe, only with a restricted SVN tree, a starting revision, and an author map):
url = ../websites.git/
fetch = +refs/remotes/*:refs/remotes/origin/*
push = refs/remotes/*:refs/heads/*
Because there's only one branch here (namely development), there's no need to configure which branch needs to be checked out by default.
- Add a post-commit hook to update the git repositories:
if /usr/bin/lockfile -2 -r1 /tmp/project-gitsvn ; then
( cd /home/svn/project-fetch && /usr/bin/git svn fetch && /usr/bin/git push origin )
rm -f /tmp/project-gitsvn
- Use an ssh URL for access to both the SVN and the git repositories
git clone -o mirror ssh://project.example.com/home/svn/git-project
git checkout -t mirror/git-svn
git svn init --prefix=mirror/ ssh://project.example.com/home/svn/project
git svn dcommit
That last dcommit -- since the repo has just been cloned -- just updates all the revision numbers. It's not really necessary, since it will happen with the first real SVN commit from git anyway.
- Client side, we also need to set up the git author and the SVN authors files, so that they match with what happens on the server side. Failing to configure these consistently will cause lots of extra commits to show up in your local clone. Note I'm configuring this in the repo-local configuration, not globally, so it doesn't interfere with the recommended KDE git setup. It uses the authors file I previously checked into SVN at the root of the development branch -- now in the root of the git repo:
git config user.name "Adriaan"
git config user.email "firstname.lastname@example.org"
git config svn.authorsfile .git-authors