ubuntu 20.04 LTSでsvn2gitを試してみた

今更ですが、Subversionで管理していたリポジトリをGit管理に変換する必要が出てきたので、svn2gitで変換を行えるか調査したときの備忘録です。

#環境

Ubuntu 20.04 LTS
Subversion 1.13.0
Git 2.25.1
svn2git 2.4.0

※Subversion, Git, svn2gitは、apt installでインストールしました。

#Subversionリポジトリの用意

簡単な以下のSubversionのリポジトリを、/home/v1471/qiita/svn.repoに用意しておきます。subversionリポジトリの作成については割愛します。

![subversion構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2343121/4c03bfb4-4372-353f-5dfc-3d47300ec0ca.png)

#svn2gitで変換してみる

svn2gitでsubversionリポジトリを、/home/v1471/qiita/repo.gitにgit変換を試みましたが、エラーが発生して変換できない。
詳細を見るために**``-v``**オプションを付加して実行した結果が以下で、23行目のgit branchコマンドで失敗していました。

```
 1. $ cd /home/v1471/qiita/repo.git
 2. $ svn2git -v file:///home/v1471/qiita/svn.repo
 3. unning command: git svn init --prefix=svn/ --no-metadata --trunk='trunk' --tags='tags' --branches='branches' file:///home/v1471/qiita/svn.repo
 4. Initialized empty Git repository in /home/v1471/qiita/repo.git/.git/
 5. Running command: git svn fetch 
 6. r1 = ab41e6eab090f4681bb204c57a600dfb340897d2 (refs/remotes/svn/trunk)
 7. 	A	fileA
 8. r2 = dcd4c32e58f30e3e6f7e2a124532925d0802f66a (refs/remotes/svn/trunk)
 9. Found possible branch point: file:///home/v1471/qiita/svn.repo/trunk => file:///home/v1471/qiita/svn.repo/branches/branchX, 2
10. Found branch parent: (refs/remotes/svn/branchX) dcd4c32e58f30e3e6f7e2a124532925d0802f66a
11. Following parent with do_switch
12. Successfully followed parent
13. r3 = adea0cc4bf30d4732aec2910c828408e4fd2101d (refs/remotes/svn/branchX)
14. 	A	fileB
15. r4 = 9fa2fbd24d975d174b29e1f0265cc05e069b76f0 (refs/remotes/svn/branchX)
16. Checked out HEAD:
17.   file:///home/v1471/qiita/svn.repo/trunk r2
18. Running command: git branch -l --no-color
19. * master
20. Running command: git branch -r --no-color
21.   svn/branchX
22.   svn/trunk
23. Running command: git branch --track "branchX" "remotes/svn/branchX"
24. fatal: Cannot setup tracking information; starting point 'remotes/svn/branchX' is not a branch.
25. ********************************************************************
26. svn2git warning: Tracking remote SVN branches is deprecated.
27. In a future release local branches will be created without tracking.
28. If you must resync your branches, run: svn2git --rebase
29. ********************************************************************
30. Running command: git checkout "branchX"
31. error: pathspec 'branchX' did not match any file(s) known to git
32. command failed:
33. git checkout "branchX"
```

svn2gitはRuby言語で記述されているので、エラーが発生している箇所のコードを見てみると気になるコメントを見つけました。
/usr/lib/ruby/vendor_ruby/svn2git/migration.rbの353行目のコメントには、git 1.8.3.2以降はtracking情報は設定できないと書かれています。

```ruby:/usr/lib/ruby/vendor_ruby/svn2git/migration.rb一部
351. status = run_command("git branch --track \"#{branch}\" \"remotes/svn/#{branch}\"", false)
352.
353. # As of git 1.8.3.2, tracking information cannot be set up for remote SVN branches:
354. # http://git.661346.n2.nabble.com/git-svn-Use-prefix-by-default-td7594288.html#a7597159
355. #
356. # Older versions of git can do it and it should be safe as long as remotes aren't pushed.
357. # Our --rebase option obviates the need for read-only tracked remotes, however.  So, we'll
358. # deprecate the old option, informing those relying on the old behavior that they should
359. # use the newer --rebase otion.
360. if status =~ /fatal:.+'#{branch}'.+/
361.   @cannot_setup_tracking_information = true
362.   run_command(Svn2Git::Migration.checkout_svn_branch(branch))
363. else
364.   unless @legacy_svn_branch_tracking_message_displayed
365.     warn '*' * 68
366.     warn "svn2git warning: Tracking remote SVN branches is deprecated."
367.     warn "In a future release local branches will be created without tracking."
368.     warn "If you must resync your branches, run: svn2git --rebase"
369.     warn '*' * 68
370.   end
371.
372.   @legacy_svn_branch_tracking_message_displayed = true
373.
374.   run_command("git checkout \"#{branch}\"")
375. end
```

git 1.8.3.2以降はtrackingできないと記述されているので、ダメ元で以下のように**``--track``**を削除してみました。

```diff:
$ diff -u0 migration_org.rb migration_new.rb 
--- migration_org.rb	2021-12-11 14:01:12.001436655 +0900
+++ migration_new.rb	2021-12-11 14:01:12.001436655 +0900
@@ -351 +351 @@
-          status = run_command("git branch --track \"#{branch}\" \"remotes/svn/#{branch}\"", false)
+          status = run_command("git branch \"#{branch}\" \"remotes/svn/#{branch}\"", false)
```

再度、svn2gitを実行すると、エラーは発生せず終了しました。

#branchが取り出せるか確認

git cloneで取り出し、branchXに切り替えてfileBが見えるか確認しました。

```
$ git clone /home/v1471/qiita/repo.git
Cloning into 'repo'...
done.
$ cd repo/
$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchX
  remotes/origin/master
$ git switch branchX
Switched to branch 'branchX'
Your branch is up to date with 'origin/branchX'.
$ ls
fileA  fileB
$ git log --oneline
f635b70 (HEAD -> branchX, origin/branchX) add fileB
0faa089 create branchX
ef2e8fd (origin/master, origin/HEAD, master) add fileA
4ccd5d8 first commit
$ 
```

fileBが見え、log情報も見えるようなので、Subversionからの変換はできているみたいです。

旬のときにツール類は使っておかないとダメですね。タイミングを逃すと思わぬ苦労に合う羽目になります。