卜部昌平のあまりreblogしないtumblr RSS

Archive

Aug
23rd
Mon
permalink

超俺専用メモ「rubyのsvn->git gateway再構築方法」

一般化すれば他者にも有益な話題と思われるがとりあえずめどい。

方針

  • ありものをつかう
  • 回線に優しく
  • てっとりばやく
  • データロスしない

setup OpenSSH multiple connection sharing

以下の方式ではsvnサーバにつなぎに行っては「あ、やっぱ手元にあったわ」でコネクション切るというのを繰り返す感じなる。git-svn(1)頭悪いな。で、普通にそのままやるとSSHのセッションハンドシェイクが全体の時間に対して支配的になる上に、どう考えても回線の無駄なので、一旦作ったコネクションを使いまわすことで対応する。これはOpenSSHには普通に備わっている機能だ。~/.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

んで

% screen ssh -vAN ci.ruby-lang.org

この窓は開きっぱなしになるので: screen zshとでもして新しい窓を開いてそっちで作業を続ける。

initial retrieval

ではレポジトリを作るところから。

% 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

ここでconfigに以下のように一行加えることで無駄な通信を大幅に減らすことができる。

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

次にすでにgithubにpushしてあるobjectを引っ張ってくる

% git --bare remote update svn

これでもうこのremoteは用済み。以下のようにconfigを直接弄ってremoteを消す。git remote rmはするな。refも消えるからな。

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

以上の下準備をしたら、ようやく普通にgit-svnしてよし。

% git --bare svn init --stdlayout --prefix=svn/ svn+ssh://svn@ci.ruby-lang.org/ruby
% git --bare svn fetch --minimize-connections --quiet

しばらく(数十時間程度)かかるので根性で耐える。NaCl社内からだと2~4時間程度。

setup remote

では今度はpushする側のremoteを作る。

% git --bare remote add github git@github.com:ruby/ruby.git
% git --bare remote update github

これは超一瞬で終わるはず。いちおうpushできるか試してもいい。

% 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

ここでnon-fast-forwardとか言われてエラーになるようだったらぶっ壊れてる。リモートかローカルかは不明だが。

setup crontab

これはgatewayなので全自動で同期されるべきなので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

まずもうsshのコネクションは不要なのでそのscreenはいらない。

あと手でconfigを弄る等かなりきわどいことをしているので、ねんのためfsckとかやっといたほうがいいはず。

% git --bare fsck --lost-found --unreachable
% git --bare gc --aggressive --prune
% git --bare svn gc
% git --bare repack -fAd

repackは趣味で。

  1. ftnk reblogged this from shyouhei
  2. eban reblogged this from shyouhei
  3. conceal-rs reblogged this from shyouhei
  4. mrkn20 reblogged this from shyouhei
  5. atm09td reblogged this from shyouhei
  6. gtokio reblogged this from shyouhei
  7. shyouhei posted this