仕事で使ってる巨大SVNレポジトリをGithubに移管するためにやったことまとめ
動機
Subversionで困ってない
ぶっちゃけSubversionで全然困っていませんでした。コードレビューはちゃんとやっていたし、マージ・ブランチングも自作シェルスクリプトのおかげてスムーズにやれていました。
よく「Gitはマージが賢い、ブランチ作成が一瞬でできる」とかいわれますが、Subversionだってちゃんと使えばコンフリクトなんかめったに起きないし、ブランチ管理・マージだって全然めんどくさくない。
特にver1.7からはサーバもクライアントも大幅に高速化されたし、.svnディレクトリが.gitみたいに1個になったし、rebaseみたいなことだってできる。(sync merge & reintegrate)
ただ、世の中が一斉にGitにシフトしている中でいつまでもSubversionを使っててよいのかという不安がありました。
また、月から金までSubversionにどっぷり使っているとなかなかGitスキルが身につかず、Github上のオープンソースプロジェクトに参加する敷居が高いという問題がありました。
Subversionが腐ったテクノロジーだって??
きっかけはこれ。会社の腐ったテクノロジーに縛られ続け、VSSやらSubversionやらいまだに使って、レガシーコードに携わっていても、外に出たらそれは評価されるのだろうか?
長時間労働・サービス残業は自分の価値を下げ企業存続を危うくする | Act as Professional - hiroki.jp by HIROCASTER
最初これをみたときは正直腹がたちました。
Subversionが腐ったテクノロジーとは言い過ぎじゃないか、
GreeだってモバゲーだってSubversionで育ったんじゃないか、
Ruby言語は今もSubversionで開発されてるじゃないか、
Subversion1.7からはすごい改善されたのにそれを知らないだけじゃないか、
カッとなって反論記事を書こうとしました。
しかしふと思いとどまって、そんな反論にエネルギーを使うくらいならGit移管をがんばってやってみよう、前に進もう、そう決意しました。
結果的に@HIROCASTERさんに感謝です。
業務でGithubを使うとヤバイらしい
Gihubに移管しよう思ったのは、YAPC::Asia2012でペパポの人がGithubでの開発を楽しそうに語っていたのを聞いたのが決め手でした。あといつもお世話になっている@sotarokさんの講演動画も。
- GitHubを使った開発とデプロイ
- PHPカンファレンス2012 で Git と Pull Request をつかったチーム開発の話をしてきました #phpcon2012 - 肉とご飯と甘いもの @ sotarok
遭遇した問題点
- SVNレポジトリ内に不要ファイルが大量に蓄積されており、サイズが肥大化していた
- SVNでのbranches構成が不規則すぎてgit svn cloneが何度もこけた
- チームメンバーがGitに不慣れだった
やったこと
- Subversionレポジトリの整理(不要ファイル削除とか)
- git svn fetchを使ってSVN→Gitへのレポジトリ変換
- git-svnで平行運用しつつ、メンバーを教育
Subversionレポジトリの整理(不要ファイル削除とか)
当初レポジトリサイズが6GBもありました。容量のほとんどは不要な画像とかドキュメント類が占めていました。
svndumpfilterを駆使して不要ファイルをパスベースで除去しました。
svn cp やsvn mvで履歴が複雑に絡み合っている場合、svndumpfilterがエラーを吐くので一筋縄ではいきませんでした。
何段階かに工程を分けて、(まず画像を削除、次にドキュメントを削除、・・みたいな感じで)少しずつ少しずつレポジトリをダイエットさせました。
svndumpfilterを1回通すだけで数時間かかるので作業はかなり大変でした。途中でエラーが出て何度も泣かされました。
svndumpfilterを通算10回ほどかませた結果、レポジトリサイズを6GB→1GBにまで減らすことができました。
差分の5GBはバイナリファイルです。バイナリファイル恐るべし!
参考記事
- [Subversion]過去の分岐の歴史を修正する方法
- [Subversion]直近のコミットをなかったことにする方法(レポジトリデータを削除)
- [Subversion]巨大なリポジトリから多数の不要ファイルを恒久的に削除する方法
- [Subversion]svndumpfilterで、肥大化したレポジトリをダイエットさせる方法
- [Subversion]レポジトリ内で容量をくってるリビジョンを突き止める方法
git svn fetchを使ってSVN→Gitへのレポジトリ変換
最初git svn clone -s でレポジトリ変換しようとしたら、branches構成が不規則すぎてエラーが出まくりました。git svn clone --trunk でtrunkのみを引っ張ってくるようにしたらうまく行ったのですが、これだとブランチのコミットが全て失われてしまうという問題がありました。
ブランチのコミットを捨てるという選択肢もあるですが、その場合4万コミットのうち3万コミットほど捨てることになってしまい、いろいろ苦労した思い出が消えるのかーと思うとせつなくなってきて、やっぱりできるだけ過去のブランチもGitに移管しようと決めて戦略をねりなおしました。
試行錯誤してみてわかったことは、
- git svn cloneは使わない。git svn init してからgit svn fetchすれば同じことができるしエラーが出ても途中から再開できる
- git svn init で--branchesオプションを複数指定できる
この2つのテクニックのおかげで、結果的にほとんどのコミット履歴を維持したままGitに移管することができました。
具体的には、
- authors変換用のテストファイルを作る
- git svn init
- .git/configを手動で編集
- git svn fetch
authors.txt
tanaka = tanaka <tanaka@example.com>
yamada = yamadai <yamada@example.com>
git svn cloneは使わない方がよい。
実は、git svn clone = git svn init + git svn fetch
なので、initとfetchを別々に行いました。
init後に.git/configに小細工を加えることで、ブランチ認識ロジックを調整することができます。
.git/configを手動で編集
SVN側で、branches/dqneo/br1
branches/dqneo/old/br2
のような不規則なブランチ名を使っていたので、これをGitブランチで正しく認識させるのに苦労しました。下記のようにブランチパスをごにょごにょ書きかえることで、うまくいけました。
先に書いた方が優先的に解釈されるみたいです。
$ cat .git/config
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[svn-remote "svn"]
url = file:///home/dqneo/tmp/repo
fetch = trunk:refs/remotes/svn/trunk
branches = branches/dqneo/old/*:refs/remotes/svn/dqneo_old/*
branches = branches/yamada/old/*:refs/remotes/svn/yamada_old/*
branches = branches/dqneo/*:refs/remotes/svn/dqneo/*
branches = branches/yamada/*:refs/remotes/svn/yamada/*
[svn]
authorsfile = /home/dqneo/authors
なお、下記のような記述は文法エラーになりました。ワイルドカードがちゃんと使えるわけではないみたいです。
branches = branches/ver*:refs/remotes/svn/ver/*
参考記事
- SubversionのリポジトリをGitリポジトリに移行する - どっかのBlogの前身のような
- git svn cloneで、標準構成じゃないときのbranches指定方法
- git svn cloneをやるときは--prefix svn/をつけるべき
git-svnで平行運用しながらGitに習熟する
スキル高めのメンバーからgit-svnを覚えてもらって、SVNとGitをしばらく平行運用しました。メンバー全員がGitに習熟するのを待っていると長くなりそうだったので、メンバーのうち半分くらいがgit-svnを覚えた段階で、(なかば強引に)一気にSVNを廃止してGithubに切替えました。
ちなみにGitはこの本で勉強しました。
大変分かりやすかったです。
移管してみてわかったこと
- Gitはブランチが気軽に作成できるので、コードレビューの粒度が小さくなってよい。
(SVN時代は1チケット1ブランチだったのでレビューの粒度が大きくて大変だった) - SVNに習熟してる人ならGitはすぐ馴れる。
- Githubはプルリク時にレビューコメントが書き込めるので便利。
(従来はRedmineにレビューコメントを書いていたのでやりとりが面倒だった) - オープンソースプロジェクトへの心理的敷居が下がった。
(SVN時代にもちゃんとコードレビューする文化があったからかも)
大きいのは、仕事も趣味もGithubに一本化されたので精神的に楽になったことです。
今後使い込んでいくにつれて「ソーシャルコーディング革命」を実感できる日が来るかもしれません。
それを楽しみに日々精進していきたいと思います。