どんな人向けか?
諸事情でGitからSubversionに移行するケースを想定しています。
例えば、GitHubの有料プランをやめて、社内にもとからあるSubversionのリポジトリサーバに全て統一しようとか。
そもそもSubGitはSubversionからGitに移行するためのものでは?
SubGit は、gitとsvnのマイグレーションツールのようです。もちろん、gitへの移行が主なユースケースだと思います。今回はgitとsvnのリポジトリの同期をとれるのを利用して、gitからsubversionへの移行を実現します。フリーの機能だけでいけます。
git-svnでもできるのでは?
もちろんできます。下記も参考しました。
ただ、すこし試してみて時間がかかりそうだったので、別のを探した結果、SubGitにいきつきました。
# 手順
- SubGitのインストール
- 移行先のリSubversionリポトリ作成
- SubGitで移行用Gitベアリポジトリ作成
- 移行元の内容をコピー
- Subversionへコミット
- checkoutして確認
わかりやすくするために、GitHubのリポジトリを、Subversionリポジトリがあるサーバに移行する形で記述します。
1. SubGitのインストール
公式サイトを参照。java7以上が必要なので、事前にインストールしておきます。
http://www.subgit.com/downloadingzip.html
展開したもの中にある、bin/subgitへのパスを通しておきます。
2. 移行先のSubversionリポジトリ作成
通常の手順通りにつくって、trunk,branches,tagsディレクトリを作成したのをコミットしておきます。
便宜上、リポジトリ名は移行元のと同じものとします。
# cd /var/www/svn
# svnadmin create [repo_name]
# svn mkdir file:///var/www/svn/[repo_name]/{trunk,branches,tags} -m "create trunk,branches and tags."
3. SubGitで移行用Gitベアリポジトリ作成
SubGitを使って、先につくったSubversionリポジトリと同期する、Gitのベアリポジトリをつくります。
# cd /var/www/git
# subgit configure --layout auto file:///var/www/svn/[repo_name]
# subgit install [repo_name].git
ディレクトリ作成のリビジョン1が、最初のコミットとして登録されます。
(Subversionから移行する場合、これでほぼ完了になります。移行するだけなら、subgit importをつかえばよいようですが。)
4. 移行元の内容をコピー
移行用のベアリポジトリからgit cloneして、作業用のリポジトリを用意します。
# git clone /var/www/git/[repo_name].git
一旦、リモートのURLを移行元のGitHubリポジトリに書き換えます。
# cd /var/www/git/[repo_name]
# vi .git/config
下記のようにすればOKです。sshでとる場合、GitHubに公開鍵を登録しておきます。
(gitのバージョンが1.7.10未満だと、httpsのbasic認証での取得ができないバグある模様。CentOSだと、epelなどの別のリポジトリから新しいバージョンを取得するか、ソースからビルドするかのどちらか)
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
#url = /var/www/git/[repo_name].git
url = git@github.com:[user_name]/[repo_name].git
これで、とにかくpullしてきます。subversionでディレクトリをきったのに相当するコミットが、先頭にきてしまいますが、subversionに移したときのリビジョンはうまくいっているので、このままいきます。
# git pull
つぎはリモートブランチの取得です。移行したいものだけチェックアウトするか、面倒なら全部やります。
# for branch_name in `git branch -r | grep -v master`;do
> git checkout -t $branch_name
> done
ただし、ブランチ名にスラッシュが含む(ex. feature/XXX)場合は、SubGitの設定ファイルで調整が必要です。
/var/www/git/[repo_name].git/subgit/config に branches = branches/feature/*:refs/heads/feature/*
などと追記します。詳しくはこの記事をどうぞ。
5. Subversionへコミット
必要ものを取得できたら、リモートのURLをもとに戻します。
[remote "origin"]
fetch = +refs/heads/*:refs/remotes/origin/*
url = /var/www/git/[repo_name].git
#url = git@github.com:[user_name]/[repo_name].git
あとはpushするだけです。タグもオプションつけてpushします。
# git push
# git push --tags
SubGitで、最初につくったSubversionリポジトリと連動しているので、リビジョンがコミット数に応じて進んでいきます。コミット数が1000くらいあっても、数分で終わりました。
6. checkoutして確認
適当なところに、Subversionリポジトリをチェックアウトして、移行できたか確認します。
# cd /tmp
# svn checkout file:///var/www/svn/[repo_name]
# cd [repo_name]
# svn log -l 5
チェックアウトのときに、想定しているファイルやブランチなどが標準出力されていれば、まず大丈夫です。
念のため、適当にsvn logで、直近のリビジョンのコミットメッセージが、gitのと対応しているかを確認しておきます。
まとめ
SubGitがあれば、gitとsvnの行き来は結構できますね。これでgitにもsvnにも移行できるノウハウが得られました。
蛇足
実は、GitHubはsvnクライアントからでもアクセスできます。
https://help.github.com/articles/support-for-subversion-clients/
tortoisesvnで普通にチェックアウトできましたよw
最初はこのワーキングコピーをつかって、subversionのリポジトリに移行できないかと思いましたが、subversionは中央集権型だから、それにつながるコマンドはないですよね... リポジトリが死んだら、過去のリビジョンを復元するのは絶望的なんでしょうか。
GitHub側も、svnから移行するための機能を用意していますね。
https://help.github.com/articles/importing-from-subversion/