はじめに
ネットにはそれなりに情報があるですが、自分のやりたいことが1箇所にまとまっていなかったので、案外サクッとできず困ったので、今後のためのメモとして残しておきます。
移行手順
今回は Macbook Pro の M3 で行なったものを記事にしています。Windows でも出来ないことはないと思いますが、記載したコマンドが多少違ってくるかなと思います。
まず、こちらに最初のイメージ図を置いておきます。
以後、この図を使って幾つか説明していきます。
0. 前置き
SVN では
- branches
- tags
- trunk
の3つがディレクトリ構成で管理することが多いと思います。
今回のゴールは、リモートにある SVN で管理されたファイルを
- branches -> Git のブランチ
- tags -> Git のタグ
- trunk -> Git の main/master のブランチ
これらを Git のリモートリポジトリに反映できるまでを行います。
1. 必要なものをインストールする
- Git
デフォルトで入っていると思いますが、確認のためのコマンドはこちら
$ git --version
- git-svn
これを使うことで楽に移行できます。今回は Homebrew
で入れましたが、好きなようにインストールしてください。
$ brew install git-svn
バージョン確認のコマンドはこちら
$ git svn --version
こんな感じで git-svn version 2.46.0 (svn 1.14.3)
と表示されれば OK です。
2. SVN を Git として Clone する
git-svn
のコマンドを使っていきます。
歴史が長いと clone に時間がかかるので気長に待ちましょう...
$ git svn clone --stdlayout --no-metadata --prefix=svn/ --localtime http://YOUR_SVN_REPO
オプションがモリモリですが、詳しくはこちらをみてください。
必要に応じてオプションの いるもの・いらないもの は判断してください。
SVN の構成が先に書いた branches / tags/ trunk の場合、clone したものは trunk 配下のファイルがあると思います。
3. 新しい Git のリモートリポジトリに反映する
すでに Git で空のリモートリポジトリを準備している想定です。
まず、Git のリモートリポジトリが設定されていないことを確認します。
$ git remote -v
何も表示されないと思います。なので設定を追加します。
$ git remote add origin https://YOUR_NEW_GIT_REMOTE_URL
ちなみに名前が origin
である必要はないですが、一般的なのでそのまま使う方が良いでしょう。
もう一度確認すると
$ git remote -v
以下のように表示されれば OK です。
origin https://YOUR_NEW_GIT_REMOTE_URL (fetch)
origin https://YOUR_NEW_GIT_REMOTE_URL (push)
最後にリポジトリへ今あるブランチのコードを反映します。
$ git push --set-upstream origin master
コードが反映されているかどうかは、リモートリポジトリの管理画面を(ex GitHub, Bitbucket)を確認してください。
4. ブランチをリモートに反映する
SVN で開発途中のブランチがあり、移行したい場合などもあると思います。
ローカルのブランチをチェックしてみましょう。
$ git branch
おそらく、この段階では master しかないと思います。
リモートのブランチを確認します。
$ git branch -r
そうすると SVN で作ったブランチの一覧が出てくるはずです。これをローカルの Git にも反映させていきます。
少なければブランチを1個ずつチェックアウトして(ローカルにもってきて)、push すれば良いです。
ただし、面倒だと思うので以下のスクリプトでまとめてチェックアウトすることで、ローカルに全てのブランチを持ってくることができます。
for branch in $(git branch -r | grep -v '\->' | grep -v 'trunk' | grep -v 'tags/' | grep -v 'HEAD' | sed 's/ //g'); do
branch_name=$(echo $branch | sed 's/svn\///')
git checkout -b $branch_name $branch
done
これは先ほどの手順で --prefix=svn/
としているため、これに当てはまらない場合は、自分で直してください。
終了後にもう一度ローカルでブランチを確認すると、一覧があるはずです。
$ git branch
注意点として、コマンドを実行した結果、最後にチェックアウトしてブランチにいるはずなので、メインのブランチに戻っておきましょう。
【example command】
$ git checkout master
最後にリモートの Git へ反映します。
$ git push origin --all
ブランチが反映されているか、リモートリポジトリの管理画面を(ex GitHub,Bitbucket)を確認してください。
5. タグをリモートに反映する
SVN において、tags はコピーしたブランチみたいなものなので、git-svn
で clone してきた場合も、ブランチ配下に設置されます。
【example - SourceTree】

これをタグとして取り出すことになります。
まずはローカルにある Git のタグを確認しましょう。
$ git tag
おそらくまだ何も出ないと思います。そこで以下のスクリプトからまとめて取り出します。
for tag in $(git branch -r | grep 'tags'); do
tag_name=$(echo $tag | sed 's/svn\/tags\///')
git tag $tag_name $tag
done
こちらも先ほどと同じく、clone 時に--prefix=svn/
としているため、これに当てはまらない場合は、自分でコードを直してください。
終わってからもう一度確認すると
$ git tag
ローカルのタグがすべて出ると思います。
【example】

最後にタグを全てリモートの Git に反映します。
$ git push origin --tags
【example】

タグが反映されているか、リモートリポジトリの管理画面を(ex GitHub,Bitbucket)を確認してください。
6. SVN の追跡を消す
これは必要なら行ってください。
実は git-svn
で clone したものは、SVN の追跡も生きています。たとえば SourceTree などでコードを管理した場合に「Git or SVN どちらに反映しますか?」みたいなことを聞かれてしまい煩わしいです。
なので、.git
にある SVN 関連のものを削除していきます。
$ rm -rf .git/svn
$ rm -rf .git/refs/remotes/svn
$ rm -rf .git/logs/refs/remotes/svn
また、.git/config
にある SVN 関連の設定も削除しましょう。
最後に、以下のコマンドで何も表示されなければ、SVN の追跡はもうありません。
$ git config --get-regexp svn
何か表示された場合は、そこにあるパスを追って削除しましょう。
終わりに
ただコードを移行するだけなら、 clone して Git のリポジトリに突っ込むだけです。
ただ、過去の修正した背景も全部移行するなら、branches と tags への対応が必要で、うまいことまとまった記事がなくて困りました。
この記事が誰かの助けになれば幸いですmm