CVSリポジトリをGitリポジトリに変換する
ファイルサーバの整理をしてたら、古(いにしえ)のCVSリポジトリが発掘された。考古学的価値しか無い代物だが、CVSのままでは鑑賞もしづらいので、Gitリポジトリに変換してみた。
git cvsimportを使う場合
Gitの公式ページに書かれている方法。
git cvsimportコマンドでCVSリポジトリとモジュールを指定すると、-Cオプションで指定したパスにGitリポジトリが出力される流れ。
git-cvsをインストールして(下請けのcvsとcvspsは自動で入る)、git cvsimportで変換を実施する。なお、CVSリポジトリのコミットコメントがEUC-JPだったので、文字化けしないよう一時的にi18n.commitencodingをeuc-jpにしておき、変換が終わってから設定を戻した。
sudo apt install git-cvs
git config --global i18n.commitencoding euc-jp
git cvsimport -d ~/cvsrepo1 -C project1_git project1
git config --global --unset i18n.commitencoding
GitリポジトリのルートはCVSモジュールの階層になった。つまり、
- 「CVSリポ/project1/subdir1/file1」が「Gitリポ/subdir1/file1」になる。
cvs2gitを使う場合
cvs2svnに付属しているcvs2gitを使う方法。cvs2svnはTigris.orgにあったが、すでにサイトが閉鎖されている。果たして今はどこに移ったのか。ドキュメントはRobert Jacobさんのページにある。
cvs2gitコマンドでCVSリポジトリかモジュール(さらにそのサブディレクトリでもいい)を指定すると、Gitにインポートできるファイルが2つ出力されるので、それをgit fast-importでGitリポジトリに取り込む流れ。
cvsとcvs2svnをインストールして、RCSファイル(*,v)が存在するディレクトリを指定して変換する。コミットコメントのエンコーディングは–encodingオプションで指定できる。
sudo apt install cvs cvs2svn
cvs2git --blobfile=git-blob.dat --dumpfile=git-dump.dat --encoding euc-jp ~/cvsrepo1/project1
新規にGitのベアリポジトリを作って、上記で出力された2ファイルを結合してgit fast-importに流し込む。
git init --bare project1.git
cd project1.git
cat ../git-blob.dat ../git-dump.dat | git fast-import
cvs2gitの引数で指定した階層が、Gitリポジトリのルートになった。つまり、
- 引数で「CVSリポ」を指定した場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/project1/subdir1/file1」になる。
- 引数で「CVSリポ/project1」を指定した場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/subdir1/file1」になる。
- 引数で「CVSリポ/project1/subdir1」を指定した場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/file1」になる。
cvs-fast-exportを使う場合
cvs-fast-exportを使う方法。
RCSファイル名のリストをcvs-fast-exportに食わせると、Gitにインポートできるデータが出力されるので、それをgit fast-importでGitリポジトリに取り込む流れ。
cvs-fast-exportをインストールして、変換対象のRCSファイルリストをcvs-fast-exportの標準入力に渡すと、インポートデータが標準出力に吐かれるので、いったんファイルに保存する。
sudo apt install cvs-fast-export
cd ~/cvsrepo1/project1
find . | cvs-fast-export > ~/stream.fi
新規にGitのベアリポジトリを作って、上記で出力されたファイルをgit fast-importに流し込む。
cd # CVSリポジトリから抜ける
git init --bare project1.git
cd project1.git
git fast-import < ~/stream.fi
エンコーディングの指定ができないので、EUC-JPのコミットコメントは文字化けした。findを実行した階層が、Gitリポジトリのルートになった。つまり、
- 「CVSリポ」でfindした場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/project1/subdir1/file1」になる。
- 「CVSリポ/project1」でfindした場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/subdir1/file1」になる。
- 「CVSリポ/project1/subdir1」でfindした場合は「CVSリポ/project1/subdir1/file1」が「Gitリポ/file1」になる。
cvsconvertを使う場合
cvs-fast-exportに付属しているcvsconvertを使う方法。
CVSリポジトリがあるディレクトリでcvsconvertコマンドを打つと、カレントディレクトリにGitリポジトリが出力される流れ。
cvs-fast-exportをインストールして、CVSリポジトリとモジュールを指定して変換するだけ。引数には必ずスラッシュが1つだけ入っていないとエラーになる。
sudo apt install cvs-fast-export
cvsconvert cvsrepo1/project1
エンコーディングの指定ができないので、EUC-JPのコミットコメントは文字化けした。Gitリポジトリのルートは、CVSリポジトリと同じ階層になった。つまり、
- 「CVSリポ/project1/subdir1/file1」が「Gitリポ/project1/subdir1/file1」になる。
変換対象にproject1まで指定しているにもかかわらず、Gitリポにproject1ディレクトリができるこの動きは、ちょっとおかしい気がする(個人の感想です)。
感想
4つの方法を試したが、変換後のGitリポジトリのブランチ構成は少しずつ違っていて、この中ではcvs2gitの結果がいちばん素直な感じがした。
コマンド | Gitリポのルート指定 | コミットメッセージのエンコーディング | ブランチの解釈 |
---|---|---|---|
git cvsimport | △モジュール固定 | ○指定できる | ×ちょっと変 |
cvs2git | ○任意 | ○指定できる | ○スッキリ |
cvs-fast-export | ○任意 | ×指定できない | △まあまあ |
cvsconvert | ×無駄にモジュール固定 | ×指定できない | △まあまあ |
というわけで、個人的にはcvs2gitがいちばん好み。
※バージョンメモ
- VirtualBox 6.1.6
- Vagrant 2.2.9
- Utuntu 18.04 (vagrant box ubuntu/bionic64 (virtualbox, 20200521.0.0))
- git-cvs 1:2.17.1-1ubuntu0.7
- cvs2svn 2.5.0-1
- cvs-fast-export 1.43-1