SVNからStash(Git)へ移行
SubversionリポジトリをStash(Git)へ移行します。
- 基本的にはAtlassianのサイト見ながらやれば出来ます。
準備
- とりあえずMacで作業してます。
- GitはHomebrewで入れたものを、Subversionではデフォルトのものを使うと良さげです。(※後述)
- Atlassianのサイトからsvn-migration-scripts.jarを落としてきます。
- 落としてきたらとりあえず動作確認。
$ java -jar svn-migration-scripts.jar verify svn-migration-scripts: using version 0.1.56bbc7f Git: using version 1.9.2 Subversion: using version 1.8.8 git-svn: using version 1.9.2 You appear to be running on a case-insensitive file-system. This is unsupported, and can result in data loss. Cannot connect directly to internet. This may interfere with your ability to clone Subversion repositories and push Git repositories.
- Macの場合は、ファイルシステムがダメだよという警告が出るので、以下の作業を行って移行用のディスクイメージをマウントする。
- svn-migration-scripts.jar の create-disk-image オプションというのを使うと出来る。
- サンプルでは5GBで書いてあったけど自分のところでは5GBでは足りないので多めにとってます。
$ java -jar svn-migration-scripts.jar create-disk-image 20 GitMigration created: /Users/gozu/GitMigration.sparseimage /dev/disk2 GUID_partition_scheme /dev/disk2s1 EFI /dev/disk2s2 Apple_HFS /Users/gozu/GitMigration The disk image was created successfully and mounted as: /Users/gozu/GitMigration
- ホームの直下に20GBのGitMigrationというのがマウントされました。
- svn-migration-scripts.jarはとりあえずGitMigrationに置いときました。
$ cp -p ~/Downlods/svn-migration-scripts.jar ~/GitMigration/.
移行(ローカルリポジトリの作業)
$ cd ~/GitMigration $ git svn clone -s http://www.example.com/svn/foo foo WARNING: --prefix is not given, defaulting to empty prefix. This is probably not what you want! In order to stay compatible with regular remote-tracking refs, provide a prefix like --prefix=origin/ (remember the trailing slash), which will cause the SVN-tracking refs to be placed at refs/remotes/origin/*. NOTE: In Git v2.0, the default prefix will change from empty to 'origin/'. Initialized empty Git repository in /Users/gozu/GitMigration/foo/.git/
- WARNINGはとりあえず無視しても大丈夫(たぶん)
- ブランチやタグの移行のシミュレーションします。
$ cd foo $ java -Dfile.encoding=utf-8 -jar ../svn-migration-scripts.jar clean-git ########################################################### # This is a dry run, add --force to commit # # No changes will be made to your repository # ########################################################### # Creating annotated tags... tag has diverged: b2 Creating annotated tag 'b2' at refs/remotes/tags/b2. Creating annotated tag 'release_1_0_0' at refs/remotes/tags/release_1_0_0. # Creating local branches... # Checking for obsolete tags... svn: E215004: Authentication failed and interactive prompting is disabled; see the --force-interactive option svn: E215004: Unable to connect to a repository at URL 'http://www.example.com/svn/foo/tags' svn: E215004: No more credentials or we tried too many times. Authentication failed No obsolete tags to remove. # Checking for obsolete branches... svn: E215004: Authentication failed and interactive prompting is disabled; see the --force-interactive option svn: E215004: Unable to connect to a repository at URL 'http://www.example.com/svn/foo/branches' svn: E215004: No more credentials or we tried too many times. Authentication failed No obsolete branches to remove. # Cleaning tag names # Cleaning branch names ########################################################### # This is a dry run, add --force to commit # # No changes will be made to your repository # ###########################################################
- うーん、何かSubversionのエラー出るな・・・。
- ぐぐってみたけど何かSubversion 1.8.8がいけないのかもしれないということなのでhomebrewで入れた1.8.8ではなくOS Xに付いている古い方でやってみることにする。
- 手っ取り早くbrewの方のsvnをアンインストールしました。
$ brew uninstall subversion Uninstalling /usr/local/Cellar/subversion/1.8.8... $ svn --version svn, version 1.7.10 (r1485443) compiled Jan 15 2014, 11:22:16
- もっかい実行!
$ java -Dfile.encoding=utf-8 -jar ../svn-migration-scripts.jar clean-git ########################################################### # This is a dry run, add --force to commit # # No changes will be made to your repository # ########################################################### # Creating annotated tags... tag has diverged: b2 Creating annotated tag 'b2' at refs/remotes/tags/b2. Creating annotated tag 'release_1_0_0' at refs/remotes/tags/release_1_0_0. # Creating local branches... # Checking for obsolete tags... No obsolete tags to remove. # Checking for obsolete branches... No obsolete branches to remove. # Cleaning tag names # Cleaning branch names ########################################################### # This is a dry run, add --force to commit # # No changes will be made to your repository # ###########################################################
- 上手くいったー!
- それではローカルリポジトリの状態を確認します。
$ git branch * master $ git tag
- masterブランチのみが存在する状態ですね。タグはありません。
- 今度は
--force
を付けて移行します。
$ java -Dfile.encoding=utf-8 -jar ../svn-migration-scripts.jar clean-git --force # Creating annotated tags... tag has diverged: b2 Creating annotated tag 'b2' at refs/remotes/tags/b2. Creating annotated tag 'release_1_0_0' at refs/remotes/tags/release_1_0_0. # Creating local branches... # Checking for obsolete tags... No obsolete tags to remove. # Checking for obsolete branches... No obsolete branches to remove. # Cleaning tag names # Cleaning branch names
- もっかい、確認します。
$ git branch * master $ git tag b2 release_1_0_0
- ブランチとタグが出来ました!
- SVNにブランチがなかったのでmasterブランチだけですがブランチがあればちゃんとGitのブランチに変換されます。
移行(リモートリポジトリへPush)
- Stashの方に移行用プロジェクトとしてmigrationプロジェクトを用意したので、そこにリポジトリ作成します。
$ git remote add origin http://username@stash.example.com/scm/migration/foo.git
- まずはブランチをPushします。
- 今回はSVNでブランチを切ってなかったのでmasterブランチだけですが、ブランチがあればすべてPushされます。
$ git push -u origin --all Counting objects: 996, done. Delta compression using up to 8 threads. Compressing objects: 100% (444/444), done. Writing objects: 100% (996/996), 16.37 MiB | 4.82 MiB/s, done. Total 996 (delta 449), reused 988 (delta 446) To http://username@stash.example.com/scm/migration/foo.git * [new branch] master -> master Branch master set up to track remote branch master from origin.
$ git push --tags Counting objects: 93, done. Delta compression using up to 8 threads. Compressing objects: 100% (73/73), done. Writing objects: 100% (91/91), 25.89 KiB | 0 bytes/s, done. Total 91 (delta 22), reused 37 (delta 12) To http://username@stash.example.com/scm/migration/foo.git * [new tag] b2 -> b2 * [new tag] release_1_0_0 -> release_1_0_0
- これで出来ました!
Gitへ移行した後でSubversionにコミットしてしまった場合
- SubversionをRead Onlyにしておけばいいのですがそうも行かない時もあるでしょう。
- その時は差分をPushする事ができます。
$ cd ~/GitMigration $ cd foo $ git svn fetch $ java -Dfile.encoding=utf-8 -jar ../svn-migration-scripts.jar sync-rebase $ java -Dfile.encoding=utf-8 -jar ../svn-migration-scripts.jar clean-git --force
- これでローカルのgit svnは最新になったので、今度はpushします。
$ git push -u origin --all $ git push --tags
注意:ブランチとタグが移行できなくなった
- しばらくして別のリポジトリを移行しようと思ったらブランチとタグの移行がうまく行かなくなりました。
- 色々考えるとbrew upgradeしてgitが2.0に上がったのが怪しいと推定。
- homebrewでgitのバージョンを切り替えてみます。
$ brew switch git 1.9.2 Cleaning /usr/local/Cellar/git/1.9.1 Cleaning /usr/local/Cellar/git/1.9.2 Cleaning /usr/local/Cellar/git/2.0.1 208 links created for /usr/local/Cellar/git/1.9.2
- 移行してみましょう。
$ git svn clone -s http://www.example.com/svn/test test $ test $ java -jar ../svn-migration-scripts.jar clean-git --force # Creating annotated tags... Creating annotated tag 'TestTag' at refs/remotes/tags/TestTag. # Creating local branches... Creating the local branch 'release-test1' for Subversion branch 'refs/remotes/release-test1'. # Checking for obsolete tags... Deleting Git tag 'TestTag' not in Subversion. Deleted tag 'TestTag' (was 697cc52) # Checking for obsolete branches... No obsolete branches to remove. # Cleaning tag names # Cleaning branch names
- あ、やっぱり・・・
移行が終わってからgitを2.0に戻そうかな。