Note from the author : After 3 years, I translate this into English. I have to emphasize this is a "svn → git gateway", not svn←git. I have never tried opposite way, and can hardly believe that works without modifications. At your own risk please.
Too fussy to generalize… Smells like groovy to others though…
Lines:
- Reuse what's usable
- Bandwidth friendly
- As quick as it can
- No data loss
The reason Y U R so slow, is that git-svn(1)
is so brain-challenged that it cuts the connection every time it receives something. So in fact all you're to wait is TCP handshakes. Thanks to OpenSSH this totall mess can be avoided. You can force OpenSSH to persist its connection even when git-svn requests to cut it. In order to do so you have to write following to ~/.ssh/config
Host ci.ruby-lang.org
User svn
Hostname ci.ruby-lang.org
IdentityFile ~/.ssh/id_rsa
PreferredAuthentications publickey
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p
And
% screen ssh -vAN ci.ruby-lang.org
This session lasts forever so open a new window by : screen zsh
and move into it.
Start creating repository.
% repo=tmp.git
% git init --bare $repo && cd $repo
% git --bare remote add svn git@github.com:ruby/ruby.git
% cp config config.bak
% /usr/bin/editor config
Now, you can grately reduce needless transmissions bu adding only one line to config, like this.
diff -up config{.bak,}
--- config.bak 2010-08-20 12:42:54.851200417 +0900
+++ config 2010-08-20 12:44:05.561200494 +0900
@@ -5,3 +5,4 @@
[remote "svn"]
url = git@github.com:ruby/ruby.git
fetch = +refs/heads/*:refs/remotes/svn/*
+ fetch = +refs/tags/*:refs/remotes/svn/tags/*
Next, fetch git objects from github.
% git --bare remote update svn
Those remotes are no longer necessary. Remove them by directly editing config. Don't git remote rm
. That'll also delete refs.
--- config.bak 2010-08-20 12:42:54.851200417 +0900
+++ config 2010-08-20 16:31:22.341199938 +0900
@@ -2,7 +2,4 @@
repositoryformatversion = 0
filemode = true
bare = true
-[remote "svn"]
- url = git@github.com:ruby/ruby.git
- fetch = +refs/heads/*:refs/remotes/svn/*
After doing everything above, now git-svn
.
% git --bare svn init --stdlayout --prefix=svn/ svn+ssh://svn@ci.ruby-lang.org/ruby
% git --bare svn fetch --minimize-connections --quiet
Depending on your physical location this command takes several hundreds of thousands of seconds to run (NEVER PRESS ^C once you stared this! That should let svn and git out-of-sync) so be patient. If you could directly connect to the local segment of ruby-lang.org, it only takes 2 to 3 hours though.
Next create remotes to push to.
% git --bare remote add github git@github.com:ruby/ruby.git
% git --bare remote update github
This should end in 0.5 sec. You can test the setup if you need.
% git --bare push --dry-run -- github \
` git --bare for-each-ref --format='%(refname:short)' refs/remotes/svn \
| fgrep -v tags | sed 's|svn/\(.\+\)|svn/\1:\1|' \
`
Everything up-to-date
Something's broken if you're said to be non-fast-forward
or something. Not sure if that's remote or local though.
It's a gateway. Should sync auto. Put it into crontab
0 * * * * cd tmp.git; git --bare svn fetch && git --bare push --dry-run -- github ` git --bare for-each-ref --format='%(refname:short)' refs/remotes/svn | fgrep -v tags | sed 's|svn/\(.\+\)|svn/\1:\1|'`
That ssh connection have no use any longer so kill the screen.
You modified your config file, is of course not a good thing, so you want to fsck.
% git --bare fsck --lost-found --unreachable
% git --bare gc --aggressive --prune
% git --bare svn gc
% git --bare repack -fAd
That repack is optional.