You administer a subversion repository that is a hub of collaboration for developers, and you fancy git. You dream of a better tomorrow.
You administer a subversion repository that automatically pushes all commits to, and therefore holds a subset of, a git-svn repository and, from there, to gitolite. Developers collaborate via either repository, and changes made through git are pushed to subversion using git-svn. Your dreams are well on their way to coming true.
You have shell access to your code server, where git, git-svn, and gitolite are already installed. You have a fair bit of storage space available to hold all the git-svn reference maps.
Create and initialize a git repository that is going to receive changes directly from subversion:
$ cd GITSVN_PATH $ git init $ git svn init --stdlayout --rewrite-root=SVN_URI SVN_PATH
Create a new text file at
GITSVN_PATH/.git/authors.txt containing one line per user, similar to this:
svn_user_name = Full Name <email@address> joshua = Joshua Tacoma <email@example.com>
Make sure the authors file will always be used by adding this setting to
[svn] authorsfile = .git/authors.txt
Finally, you are ready to give the computer some heavy work! Unfortunately (in my experience) this can’t all be done with one simple git svn fetch:
$ git svn fetch --revision 1:1000 && > git svn fetch --revision 1000:2000 && > git svn fetch --revision 2000:3000
You may notice this repository is pretty darned big, so now is a good time to mention:
Beware the git-gc command’s
--aggressive option! (Don’t use it!)
Configure a new gitolite repository and make sure that a subversion post-commit hook will be able to push changes into it. Your gitolite.conf file should include lines like this:
@subversion = the accounts that process svn commit hooks @devs = yourself and all the other developers repo GITOLITE_NAME RW = @subversion RW+ develop/ = @devs RW+ feature/ = @devs RW+ release/ = @devs RW+ hotfix/ = @devs RW+ support/ = @devs R = @all</code></pre>
GITOLITE_URI as a remote in the git-svn repository:
$ git remote add origin GITOLITE_URI
GITSVN_PATH/.git/config so that the
[remote "origin"] section looks exactly as follows, replacing
[remote "origin"] url = GITOLITE_URI fetch = +refs/remotes/*:refs/remotes/origin/* push = refs/remotes/*:refs/heads/*</code></pre>
The following commands, executed within
GITSVN_PATH will fetch the latest commits from subversion and then push everything to gitolite:
$ git svn fetch && > git push origin
SVN_PATH/hooks/post-commit. Here is a perfectly functional example:
#!/bin/bash cd GITSVN_PATH && git svn fetch --quiet && git push --quiet origin</code></pre>
If the post-commit command produces any output whatsoever, subversion clients will be confused about whether the commit succeeded, resulting in false conflicts!
You now administer a subversion repository that automatically pushes all commits to, and therefore holds a subset of, a git-svn repository and, from there, to gitolite. Developers may collaborate via either repository, but changes made through git must be pushed to subversion manually using git-svn. Your dreams are well on their way to coming true!
Some of the work here, especially the
GITSVN_PATH/.git/config section, is based on Thomas Ferris Nicolaisen’s excellent Git-SVN Mirror for multiple branches.