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 を使ってダンプを取得する。

Subversionダンプ取得

1
svnadmin dump /opt/svn/reponame/ > svndump.dump

このダンプファイルは後で使いますので、作業する PC に持ってくる必要があります。

サーバー上でやるならそのままで OK です。

作業 PC 上での作業

Subversion リポジトリの準備

git に変換する対象だけが含まれた Subversion リポジトリを作業用 PC 上に準備します。

履歴のクリーニング

ゴミファイルがコミットされた履歴があったので、削除します。

※最新版からは消されていても、履歴に含まれていると git clone に時間がかかる原因になります。

ここの手順はオプションです。の時点ではまだ Subversion のダンプファイルに対しての作業です。

git は一切関係ありません。

ダンプファイルから不要なファイルを削除する

1
2
3
svndumpfilter exclude /document/ /sql/ /trunk/ruby/vendor/bundle/ /trunk/ruby/tmp/ < svndump.dump > svndump-clean.dump

excludeの後には、履歴からも削除するファイル (or ディレクトリ名)を列挙します。数に制限はありません。

ダンプファイルのロード

作業用 PC 内に、Subversion のリポジトリを作り、ダンプファイルをロードします。

※ 履歴のクリーニングを行ったのであれば、クリーニング済みのダンプ  ファイルを使用します。

1
2
3
4
5
# subversionリポジトリ作成
svnadmin create svnruby

# ダンプファイルのロード
svnadmin load svnruby/ < svndump-clean.dump

ローカルに Subversion サーバーを立てる

svn => git 変換時に file:// は使用できないので、サーバーをローカルに立ち上げる。

1
2
3
svnserve -d -R --foreground --root svnruby/

# ターミナルが占拠されるので、以降の作業は別ウィンドウで行う

git リポジトリへの変換

いよいよ、変換していきます。

Subversion アカウント名->git メールアドレスの読み替えファイルを作る

Subversion のコミット者は、アカウント名が記録されますが、git では、 名前 <メールアドレス> なので

対応表が必要です。ここでは、 svnauthors という名前で以下のような内容のファイルを作りました。

※私の場合は redmine と連携していたので、redmine のユーザー一覧から簡単に作る事ができました。

このファイルは履歴に対する変換表なので、現在いないユーザーでも履歴に含まれるのであれば設定が必要です。(適当な人に振っても良いと思いますが)

1
2
svnuser1 = Subversion user 1 <svnuser1@example.jp>
svnuser2 = Subversion user 2 <svnuser2@example.jp>

git リポジトリ生成

とりあえず、git リポジトリの生成だけします。

1
git svn init -s --prefix=svn/ svn://localhost/ gitruby/

Subversion -> git

Subversion リポジトリ内容を git に変換(取込)します。

1
2
> cd gitruby
git svn fetch -A ../svnauthors
  • 変換というか取込は Subversion のリポジトリから 1 コミットずつ取得して、その内容をそのまま git にコミットしていくイメージです。

コミット数・規模に応じて時間がかかります。

git の upstream に push

サーバーに push というと怒られそうなのですが、まぁサーバーに送ります。

実行前に、git branches でブランチを確認したり、中身がまともかどうかを確認したりした方が良いでしょう。

よさそうであれば、以下で push できます。よさそうでなかった場合は蛇足を読んで頂ければ。

1
2
> 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 アカウントはプロジェクト管理者権限をもっています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ 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 にする

作業完了です。(この辺、開発ルールによるのでご参考程度)