-->

centos7 git-cvsimport

centos7

CentOS7のGitサーバ構築とCVS移管。Perlで書かれたgit-cvsimportのコミットログメッセージを最悪例外処理でエンコードエラー文字列定数化。

Gitサーバ

最低限のGit環境でよいのでgitoliteを採用。CentOS7でのパッケージはgitolite3。

$ sudo yum install gitolite3

管理者鍵(マスターキー)をgitoliteに登録。

# su - gitolite3
$ cd ~/.ssh
$ ssh-keygen #省略
$ mkdir git
$ cp id_rsa* git/.
$ rename id_rsa admin git/id_rsa*
$ gitolite setup -pk git/admin.pub

作業ユーザでマスターキーを使う事もできる。

秘密鍵の受け渡しは気持ち悪いのでやめたほうがいいかもね。

# cp /var/lib/gitolite3/.ssh/id_rsa /home/worker/.ssh/.
# chown worker:worker /home/worker/.ssh/id_rsa
# chmod 600 /home/worker/.ssh/id_rsa

作業ユーザで作業前にGit設定も済ませておき、Gitoliteの設定をする。

# su - worker
$ git config --global user.name "worker"
$ git config --global user.email worker@server.fake
$ git config --global core.autocrlf false ## 変換するものが混在しているため

$ mkdir -p ~/gitspace
$ cd ~/gitspace
$ git clone gitolite3@192.168.2.6:gitolite-admin
$ vim gitolite-admin/conf/gitolite.conf 

グループや追加リポジトリを書いて保存。とりあえず鍵認証があれば書込可能にしておく。

@root = admin
@dev = @all

repo gitolite-admin
  RW+ = admin

repo testing
  RW+ = admin
  RW  = @all

repo test
  RW+ = @root
  RW  = @dev

必要あれば鍵の追加をしておく。

admin.pubと見分けるためにusername-hostname.pubで命名。

$ cp /pub/git/keydir/*-*.pub gitolite-admin/keydir 

コミットしてプッシュ。

$ cd gitolite-admin
$ git commit -a -m 'update ssh-keys'
$ git push origin master

鍵の管理

鍵の管理をどうするか悩む。

共通鍵にしてしまおう案。皆面倒だと言うので。定期的に鍵変更するかな。

GitHubのような鍵登録用HTTP/CGIを建てる案。pythonでやれば楽だね。

共有フォルダ+at案。user-host.pubという形式で保存用バッチを上階層に置くかな。

CVS移管ツール

git-cvsimportを使う。CVS関連ツールが入ったgit-cvsを入れればよい。

cvs2gitもあるが、CVSROOTが入ったCVSリポジトリまるごと必要なので断念。また設定ファイルもシンプルでない。

$ sudo yum install git-cvs

git-cvsimport

CVSのログインも必要。CVSユーザにそこは委ねよう。

-pオプションはcvsps用。変換エラー(マルチバイト文字など)があれば追いやすい。結局分からないものもあるけどね。

-Aオプションもあるけどこちらの環境ではメールアドレスどうでもいいという事で無し。

-Cオプションは取って来るCVSリポジトリと名称を変えたいときに。

$ cvs -d :pserver:cvsuser@cvsserver/var/cvs login 

$ git cvsimport -v -i -p '-v' \
-d :pserver:cvsuser@cvsserver/var/cvs \
-C test test_

$ mkdir test.git
$ cd test.git
$ git --bare init --shared
$ git --bare fetch ../test master:master
$ git bramch -a
$ git remote add origin gitolite3@192.168.2.6:test
$ git push origin master
$ cd ..

マルチバイト文字対策

ん?失敗しまくる。日本語ファイル名やコミットログが豆腐(文字化け)。

git-cvsimportを環境に合わせていじる。Perlで書かれているが参考を元にコピペ程度での調整でいける。

--- /usr/libexec/git-core/git-cvsimport.bak
+++ /usr/libexec/git-core/git-cvsimport
@@ -???,? +???,? @@
 sub update_index (\@\@) {
        my $old = shift;
        my $new = shift;

+       ## * file-name * decode cp932
+       use Encode qw/decode encode/;
+       $_ = encode('utf8', decode('cp932', $_)) for @$old;
+       $_->[2] = encode('utf8', decode('cp932', $_->[2])) for @$new;

        open(my $fh, '|-', qw(git update-index -z --index-info))
                or die "unable to open git update-index: $!";
        print $fh
@@ -???,? +???,? @@
        substr($logmsg,32767) = "" if length($logmsg) > 32767;
        $logmsg =~ s/[\s\n]+\z//;

+       ## * commit-log-message * simple try-catch
+       use Encode::Guess qw/euc-jp cp932 7bit-jis/;
+       $logmsg = eval{ encode('utf8', decode('guess', $logmsg)) };
+       if($@){ $logmsg = '*** encode error log message ***'; }

        if (@skipped) {
            $logmsg .= "\n\n\nSKIPPED:\n\t";
            $logmsg .= join("\n\t", @skipped) . "\n";

もっと厳密なエンコード処理を行わないと例外で拾い捲るかもしれないので注意。

日本語ファイル名対策(file-name)。「~」用に念のためCP932。某チャットでやたら要望があったらしいので。

日本語コミットログメッセージ対策(commit-log-message)。簡易try-catchで失敗時止まらないように退避処置。最悪コミットログメッセージ不要という前提条件で。

それでもダメでそのCVSリポジトリが重要なら、最終手段CVS管理者に頼んであちら側でrebaseしてもらい再度取り込む。

参考文献

CVS レポジトリを Git に変換した手順とか注意点とか

Encodeでラクラク日本語処理