CVS から Git へのリポジトリ移行用環境を docker で簡単作成

## きっかけ

 1. 職場での CVS ソース管理に限界を感じてきたので、そろそろ Git に移行したい
 2. CVS から Git へのリポジトリ移行環境の構築が必要
 3. せっかくなら docker で構築して…

## 書いたもの

`Dockerfile` と `cvs2git.sh` の 2本 だけです。

### Dockerfile

CVS から Git へリポジトリの変換を行う環境構築のための Dockerfile です。CVS から Git への変換には [cvs2svn](http://cvs2svn.tigris.org/) を使用しています。外部ホストとリポジトリをコピーするために、SSH  サーバーを起動しています。

```dockerfile:Dockerfile
FROM ubuntu
# cvs2git
#
# VERSION 0.1

FROM ubuntu
MAINTAINER noc06140728 xxxxxxxxxxxxxx@xxxxx.xxx

RUN apt-get update

RUN apt-get install -y openssh-server
RUN mkdir /var/run/sshd

RUN apt-get install -y cvs
RUN apt-get install -y subversion
RUN apt-get install -y git
RUN apt-get install -y python

RUN useradd -m cvs2git
RUN echo cvs2git:cvs2git | chpasswd

WORKDIR /home/cvs2git

ADD cvs2git.sh /home/cvs2git/cvs2git.sh
RUN chown cvs2git:cvs2git cvs2git.sh
RUN chmod u+x cvs2git.sh

USER cvs2git

RUN svn co --username=guest --password="" --no-auth-cache http://cvs2svn.tigris.org/svn/cvs2svn/trunk cvs2svn-trunk

RUN mkdir -p cvsrepo/CVSROOT gitrepo tmp

USER root
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```

### cvs2git.sh

一連のリポジトリ変換手続きを記述したシェルスクリプトです。上記の `Dockerfile` 内でコンテナ内へ ADD されるようになっています。

```bash:cvs2git.sh
#!/bin/bash
set -e

if [ "$1" == "" ]
then
	echo "USAGE: cvs2git.sh <CVS_REPO_DIR>"
	exit 1
fi

if [ ! -d ~/cvsrepo/$1 ]
then
	echo "ERROR: $1 is not directory."
	exit 1
fi

REPO_NAME=$1
~/cvs2svn-trunk/cvs2git --blobfile ~/tmp/git-blob.dat --dumpfile ~/tmp/git-dump.dat --encoding=sjis ~/cvsrepo/$REPO_NAME
mkdir ~/gitrepo/$REPO_NAME.git && true
cd ~/gitrepo/$REPO_NAME.git
git init --bare
cat ~/tmp/git-blob.dat ~/tmp/git-dump.dat | git fast-import
git branch -D TAG.FIXUP && true
git gc --prune=now
```

## コンテナの概要

コンテナ内は、下記のディレクトリ構造になります。

```
/home/cvs2git/
  + cvs2git.sh ... 変換用シェルスクリプト
  + cvs2svn-trunk/ ... cvs2svn 
  + cvsrepo/ ... 変換元となる CVS リポジトリを配置するディレクトリ
  + gitrepo/ ... 変換後の Git リポジトリが生成されるディレクトリ
  + tmp/ ... 変換途中に使用する一時ファイル保存用ディレクトリ
```

## 使い方

※ docker がインストールされているホストが必要になります。

### docker イメージをビルド、起動する

上記の2ファイルを任意のディレクトリへコピーして、そのディレクトリ内で下記のコマンドを実行してください。

```shell-session
$ docker build -t cvs2git-sv .
$ docker run -dit -p 2222:22 cvs2git-sv
```

### コンテナへ CVS リポジトリをコピーする
scp などで、変換したい CVS リポジトリをコンテナ内の `/home/cvs2git/cvsrepo` ディレクトリにコピーしてください。
（変換元になる CVS リポジトリが、ホストの `/var/cvsrepo/PROJECT` にある場合の例）

```shell-session
$ scp -r -P 2222 /var/cvsrepo/PROJECT cvs2git@localhost:~/cvsrepo/
# パスワードは、cvs2git です。
```

### コンテナ内で cvs2git.sh を実行する

ssh でコンテナ内部に接続して、`cvs2git.sh` を実行してください。`PROJECT` には、`/home/cvs2git/cvsrepo/` ディレクトリへコピーしてきた CVS のリポジトリ名を指定してください。（パスは不要です）

```shell-session
$ ssh -p 2222 cvs2git@localhost
# パスワードは、cvs2git です。
(CONTAINER)$ ./cvs2git.sh PROJECT
```

### Git リポジトリを確認する

変換された Git のリポジトリを確認してください。コンテナ内の `/home/cvs2git/gitrepo/` ディレクトリに bare リポジトリとして生成されます。

```shell-session
(CONTAINER)$ ls ~/gitrepo
PROJECT.git
```

あとは必要に応じて、外部ホストへ Git リポジトリをコピーしてください。

## 注意事項

今回作成した cvs2git.sh には、エンコード指定を sjis 固定で記述してしまっています。（ここは手抜きです）

## 参考サイト

 - [SourceForge.jpのCVSリポジトリをGitに移行する](http://d.hatena.ne.jp/tsntsumi/20120505/MigrateCVSRepositoryToGit)
 - [Dockerizing an SSH service] (https://docs.docker.com/examples/running_ssh_service/)