最終更新日: 2009 年 6 月 11 日
CVS と Subversion は開発現場で広く使われている ソフトウェア構成管理システム (または バージョン管理システム) です。筆者もこれまで CVS と Subversion には大変お世話になっており、Piece Framework のソースコードも SourceForge.net の Subversion サービスを使わせていただいております。
しかし、SourceForge.net のサービスは速度面で快適とは言い難く、以前から他のサービスへの移行を検討していました。現在は GitHub に移行することを決定し、少しずつ移行作業を進めている最中です。この記事では、Piece Framework のプロダクトのひとつ Stagehand_TestRunner を例として、Subversion から git への移行について実際に行った作業を記録しておきたいと思います。
ノート: SourceForge.net から GitHub への移行は無事完了しています。piece's Profile - GitHub (2009/6/11)
ゴール
今回のゴールは Stagehand_TestRunner の Subversion リポジトリを git の共用リポジトリに移行することです。まず、移行元のリポジトリレイアウトを示します。
+--branches | | | +--branch-1.0 | +--releases | | | +--release-0.3.0 | | ... | +--release-2.6.2 | +--tags | +--trunk
上記の要素のうち branches 以下のディレクトリと trunk を git の ブランチ に、releases 以下のディレクトリを git の タグ にマッピングします。tags は空なので無視することにします。まとめると下記のようになります。
| Subversionリポジトリ | gitリポジトリ |
|---|---|
| branches | ブランチ |
| releases | タグ |
| tags | - |
| trunk | ブランチ(master) |
git-svn
git-svn は Subversion と git の相互運用を可能にするコマンドです。git-svn コマンドにより Subversion リポジトリの一部または全体を git リポジトリに変換することができます。
git-svn コマンドは tags として指定された Subversion ディレクトリを git のブランチにマッピングします。例えば、上記の releases/releases-2.6.2 は tags/releases-2.6.2 にマッピングされます。今回は releases をタグとして扱いたいため、git-svn コマンドだけでは目的を達成できません。(実行後にいくつか作業を行う必要があります。)
svn2git
svn2git は git-svn のラッパーですが、git-svn とは異なり、タグとして指定した Subversion ディレクトリを git のタグにマッピングします。svn2git には 2 つ 多くのバージョン があり、今回使わせていただいたのは Kevin Menard 氏による forkされたバージョン です。(オリジナルバージョン は筆者の環境では動作しませんでした。)
ノート: Kevin Menard 氏によるバージョンは下記のコマンドでインストールすることができます。gem sources -a http://gems.github.com gem install nirvdrum-svn2git(2009/6/11)
これで思い通りのマッピングができると期待しましたが、そのままではモジュールのロードに失敗したり、tags/release-xxx がタグに変換されなかったりしたため、ソースコードにいくつか手を加えました。変更点は下記のとおりです。(このパッチを適用したバージョンは こちら からダウンロードすることができます。)
ノート: Kevin Menard 氏によるバージョン 1.3.1 ではこのような問題は発生しませんでした。よって下記のパッチを適用する必要はありません。(2009/6/11)
diff --git a/bin/svn2git b/bin/svn2git
index 2d2055c..aff089c 100644
--- a/bin/svn2git
+++ b/bin/svn2git
@@ -20,6 +20,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
+require 'rubygems'
+gem 'svn2git'
+
require 'svn2git'
url = ARGV.shift
diff --git a/lib/svn2git/migration.rb b/lib/svn2git/migration.rb
index 06c2151..ca1deec 100644
--- a/lib/svn2git/migration.rb
+++ b/lib/svn2git/migration.rb
@@ -61,12 +61,12 @@ module Svn2Git
def get_branches
@remote = `git branch -r`.split(/\n/)
- @tags = @remote.find_all { |b| b.strip =~ %r{^#{@options[:tags]}\/} }
+ @tags = @remote.find_all { |b| b.strip =~ %r{^tags\/} }
end
def fix_tags
@tags.each do |tag|
- id = tag.strip.gsub(%r{^#{@options[:tags]}\/}, '')
+ id = tag.strip.gsub(%r{^tags\/}, '')
subject = `git log -1 --pretty=format:"%s" #{tag.strip()}`
date = `git log -1 --pretty=format:"%ci" #{tag.strip()}`
`export GIT_COMMITER_DATE="#{date}"`
svn2git を実行する
マッピングルールに基づいて svn2git のコマンドラインを構築し実行します。--authors オプションで示すリストに含まれていない author が現れるとコマンドは終了しますが、慌てずに author をリストに加えて再度コマンドを実行します。この場合、作業は途中から再開されるため作業用ディレクトリを削除する必要はありません。
mkdir stagehand-testrunner
cd stagehand-testrunner
svn2git \
https://sh-testrunner.svn.sourceforge.net/svnroot/sh-testrunner \
--verbose \
--trunk trunk \
--branches branches \
--tags releases \
--authors /path/to/authors.txt 2>&1 | tee svn2git.log
ローカルリポジトリの状態を確認する
マッピングルールに基づいた変換が正常に行われたか、git branch と git tag で確認します。
$ git branch 1.0 branch-1.0 * master $ git tag release-0.3.0 ... release-2.6.2
不要なブランチやタグがあればこの段階で削除しておくといいでしょう。もちろん、共用リポジトリへの反映後に削除することもできます。
$ git branch -D 1.0 Deleted branch 1.0. $ git branch branch-1.0 * master
ローカルリポジトリの内容を共用リポジトリへ反映する
準備が整ったらローカルリポジトリの内容を共用リポジトリへ反映します。
git remote add origin git@github.com:piece/stagehand-testrunner.git git push --all git push --tags
Git の利用を開始する
移行に使った作業用ディレクトリを削除し、改めて git clone を実行します。
$ cd .. $ rm -rf stagehand-testrunner $ git clone git@github.com:piece/stagehand-testrunner.git $ cd stagehand-testrunner $ git branch -a * master origin/HEAD origin/branch-1.0 origin/master $ git tag release-0.3.0 ... release-2.6.2
これで移行は完了です。
使用したソフトウェアのバージョン
$ git svn --version git-svn version 1.6.0.4 (svn 1.5.4) $ gem list *** LOCAL GEMS *** nirvdrum-svn2git (1.3.1)
参考文献
- Import from Subversion - Guides - GitHub
- jcoglan's svn2git at master - GitHub
- nirvdrum's svn2git at master - GitHub
- Rubyのパッケージマネジメントシステムgem(Rubygems)のコマンド一覧 - Knowledge Database IT
更新履歴
- 2009/6/11: 最新の svn2git に合わせて内容を見直した。
- 2009/2/14: 公開
トラックバック(0)
- このブログ記事のトラックバックURL:
