Skip to content

Instantly share code, notes, and snippets.

@shyouhei
Last active December 31, 2015 00:09
Show Gist options
  • Save shyouhei/7905704 to your computer and use it in GitHub Desktop.
Save shyouhei/7905704 to your computer and use it in GitHub Desktop.
"svn→git gateway reconstruction" super personal note

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.


"svn→git gateway reconstruction" super personal note

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

Setup OpenSSH multiple connection sharing

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.

Initial retrieval

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/*

Kick git-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.

Setup remote

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.

Setup crontab

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|'`

Cleanup

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment