🛩️

Subversionからgitに引越してみた

2021/08/10に公開

前書き

残念なお話

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ダンプ取得

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 にする

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

Discussion