Subversionからgitに引越してみた
前書き
残念なお話
Subversionの複数のリポジトリを一気に移行する手段はありません。
一個ずつ地道にやるしかありません。
前提条件
- Subversionのサーバーにアクセス可能、またはダンプが取得可能なこと。
- 作業用PCにgitがインストールされていること
- 作業用PCにSubversionがインストールされていること
動作確認環境
- Subversionサーバー CentOS 5 Subversion 1.8
- 作業用PC macOS Sierra Subversion 1.9.4 git 2.11.0
Subversionサーバー上での作業
svnadmin dump を使ってダンプを取得する。
svnadmin dump /opt/svn/reponame/ > svndump.dump
このダンプファイルは後で使いますので、作業するPCに持ってくる必要があります。
サーバー上でやるならそのままでOKです。
作業PC上での作業
Subversionリポジトリの準備
gitに変換する対象だけが含まれたSubversionリポジトリを作業用PC上に準備します。
履歴のクリーニング
ゴミファイルがコミットされた履歴があったので、削除します。
※最新版からは消されていても、履歴に含まれているとgit clone に時間がかかる原因になります。
ここの手順はオプションです。の時点ではまだSubversionのダンプファイルに対しての作業です。
gitは一切関係ありません。
svndumpfilter exclude /document/ /sql/ /trunk/ruby/vendor/bundle/ /trunk/ruby/tmp/ < svndump.dump > svndump-clean.dump
excludeの後には、履歴からも削除するファイル (or ディレクトリ名)を列挙します。数に制限はありません。
ダンプファイルのロード
作業用PC内に、Subversionのリポジトリを作り、ダンプファイルをロードします。
※ 履歴のクリーニングを行ったのであれば、クリーニング済みのダンプファイルを使用します。
# subversionリポジトリ作成
svnadmin create svnruby
# ダンプファイルのロード
svnadmin load svnruby/ < svndump-clean.dump
ローカルにSubversionサーバーを立てる
svn => git 変換時に file:// は使用できないので、サーバーをローカルに立ち上げる。
svnserve -d -R --foreground --root svnruby/
# ターミナルが占拠されるので、以降の作業は別ウィンドウで行う
gitリポジトリへの変換
いよいよ、変換していきます。
Subversionアカウント名->gitメールアドレスの読み替えファイルを作る
Subversionのコミット者は、アカウント名が記録されますが、gitでは、 名前 <メールアドレス> なので
対応表が必要です。ここでは、 svnauthors という名前で以下のような内容のファイルを作りました。
※私の場合は redmineと連携していたので、redmineのユーザー一覧から簡単に作る事ができました。
このファイルは履歴に対する変換表なので、現在いないユーザーでも履歴に含まれるのであれば設定が
必要です。(適当な人に振っても良いと思いますが)
svnuser1 = Subversion user 1 <svnuser1@example.jp>
svnuser2 = Subversion user 2 <svnuser2@example.jp>
gitリポジトリ生成
とりあえず、gitリポジトリの生成だけします。
git svn init -s --prefix=svn/ svn://localhost/ gitruby/
Subversion -> git
Subversionリポジトリ内容をgitに変換(取込)します。
cd gitruby
git svn fetch -A ../svnauthors
変換というか取込はSubversionのリポジトリから1コミットずつ取得して、その内容をそのままgitにコミットしていくイメージです。
コミット数・規模に応じて時間がかかります。
gitのupstreamにpush
サーバーにpushというと怒られそうなのですが、まぁサーバーに送ります。
実行前に、git branches でブランチを確認したり、中身がまともかどうかを確認したりした方が良いでしょう。
よさそうであれば、以下で push できます。よさそうでなかった場合は蛇足を読んで頂ければ。
git remote add origin http://gitserver.example.jp/gitlab/TEST/test.git
git push
完了後の確認
githubなりなんなりで確認して下さい。
お疲れ様でした。
参考にしたページ
git-svnでSVN→Gitへの移行をやってみたログ
http://qiita.com/hidekuro/items/4727715fbda8f10b6b11
SubversionからGitへ移行してみた
http://qiita.com/EichiSanden/items/326bdac596485baa6086
仕事で使ってる巨大SVNレポジトリをGithubに移管するためにやったことまとめ DQNEO起業日記 http://dqn.sakusakutto.jp/2012/10/svn-git-github-migration.html
蛇足
普通ならこれでOKですが、変換したSVNリポジトリは /trunk/ が空で、/branches/ruby に最新ソースが入るという
ちょっと意味不明な構成になっていました。本来であれば、 git svn init 直後に、 .git/config ファイルを修正
することで、適切に取込ができるのですが、幸い branches は git のブランチとして取り込まれるのでそのまま取込を
実行して、後で直すという作業をしています。以下はその作業ログです。
さらに言うと、この取込をpushする作業も何度もやっており、今までの履歴を全部消し飛ばしてやり直しというシチュエーションです。
※ gitサーバー側はgitlabを使っており、 master ブランチを unprotect 済み、
※ 使用するgitアカウントはプロジェクト管理者権限をもっています。
$ git branches
remotes/svn/ruby
$ git checkout remotes/svn/ruby
Note: checking out 'remotes/svn/ruby'.
You are in 'detached HEAD' state.(略)
$ git checkout -b master
Switched to a new branch 'master'
$ ls -l
(ファイルが存在するか確認)
$ git remote add origin http://gitserver.example.jp/gitlab/TEST/test.git
$ git push -f
$ git push -f origin master
(ユーザー名パスワード聞かれる)
(中略)
+ adff8c3...eafd1ace master -> master (forced update)
作業終了後は、gitlab上で・・・
- developブランチを作る
- protect branch (master & develop)
- デフォルトブランチを develop にする
作業完了です。(この辺、開発ルールによるのでご参考程度)