2010-04-15

Magitで複数の文字エンコーディングを扱う

プロジェクト内に2つのファイルがあって、一方はSJIS、もう一方はUTF-8で書かれている。両方修正してMagit上で差分を見ると、当然のように一方が文字化け。やれやれ。コミットログに関してはi18n.commitencodingだとかi18n.logoutputencodingだとか、それっぽいものが用意されているようだが(ちゃんと働くのか確認してないけど)、肝心のファイルの中身はどうすればいいのか分からなかった。

でも、diff.external(GIT_EXTERNAL_DIFF)でdiffを置き換えられると知って、nkfで変換することを思いついた。

.gitconfigに以下を追加。

[diff]
	external = ~/gitdiff.sh

gitdiff.shは以下のような感じ。自分はMeadowとgitの間は(今のところ)sjisにしているので–sjis。改行コードがLFになるように-d。

#!/bin/sh
echo diff --git a/$1 b/$5
echo index $3 $4
diff -u -L a/$1 -L b/$5 $2 $5 | nkf --sjis -d

echoの部分はMagitが認識できるように、できるだけgit標準の出力に近づけた。magit.el内には(looking-at "^diff –git ./\(.*\) ./\(.*\)(")という記述の下に(looking-at "^diff --cc +\(.*\))")という記述もあるのだけど、こっちはどういう状況での出力なのか分からないのでスルー。

なんかもう、Subversionでいいんじゃないかという気がしてくるのだが……。

2010-04-14

Git初体験5 コミットログの文字コード

Magitを使っている限りコミットログは普通に日本語が化けずに使えたので見過ごしそうになるけど、どうもサーバー上ではShift_JISで記録されているっぽい。これってUTF-8じゃなくても良いのだろうか。

仮にコミットログをUTF-8にしたとすると、ファイル内はShift_JIS(またはCP932)だから、Magitのバッファ内で差分表示をした時に文字化けしたりしないだろうか。

2010-04-14

Git初体験4 Meadow3上のMagitからpullできない

Magitからssh経由でpullができない。Cygwinのbashからやるとこんな感じ。

$ git pull
bash.exe: warning: could not find /tmp, please create!
Enter passphrase for key '/c/home/k-aki/.ssh/id_dsa':
Already up-to-date.

bashが/tmpが無いなどと寝ぼけたことを言ってから、パスフレーズを求めてきている。パスフレーズを求められるとMeadow上からは入力できないのでまずい(fakecygpty.exeを使えばできるのかもしれないけど)。

いろいろ調べてみたら、どうやら環境変数TMPとTEMPが設定されていないから、このwarningが出るようだ。つい先日Cygwin1.7にしたとき.bashrcはほとんどデフォルトのままいじらなかったのだけど、中を確認したらunset TMPなどとしているではないか。Windowsのテンポラリディレクトリと混ざると良くないらしい。.bashrcのunsetの後にset TMP=/tmpとset TEMP=/tmpを追加。

これでもMagitからpullできない。プロセス一覧を見るとssh.exeが起動しっぱなしで終了しないので、やはりパスフレーズが取れないで止まっているのだろう。複数のsh.exeも一緒に起動しっぱなしになっているので、msysgitのsh.exeを使えなくしてみた。すると今度はsed.exeがエラー。msysgitのsedはcygwinのパスを理解しないのでファイルが開けないらしい。msysgitのsedも無効化してCygwinのsedを使うようにしてみる。今度はgitが「git: 'Merge branch 'master' of ssh://********* is not a git command'」などという訳のわからないエラーを。う゛ー、なんだこりゃ。

たぶんCygwinのsedを使おうとしたせいで何かテキストの切り出しに失敗したのだろう。仕方ないのでshとsedはmsysgitのものを使うことにする。

となると、やはりパスフレーズが取れなくてssh.exeが止まったままになってしまう。

Cygwinのbash上からはちゃんと何も聞かれずにgit pullできるので、何が違うのだろうと環境変数一覧を比較してみた。

あ、TMPとTEMPの値が違う。Meadow3はスタートメニューから起動しているので%USERPROFILE%Tempだし、bashの方はさっき明示したとおり/tmp(私の場合c:appcygwintmp)だ。そういえばwin-ssh-askpassは/tmpの下にファイルを作ってたっけ。

というわけで、.emacsに(setenv "TMP" "c:/app/cygwin/tmp")(setenv "TEMP" "c:/app/cygwin/tmp")を追加したら、まともにpullできるようになった。いいのかこれで。

2010-04-14

Git初体験3 Magitを試す(Meadow3とCygwinとmsysgit)

M-x magit-status ……ぎゃー。

Local:  master ~/work/tmp/git_lesson/
Head:   6224579 first commit

Untracked files:
'c:Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

Stashes:
'c:Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

Changes:
'c:Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

すぐにmsysgitを別のパスへ入れ直した。

動くようになったけど、やっぱりpcl-cvsやpsvnなんかとはちょっと違う。セクションって何だ? diffがとりたいのだけど=を押すんじゃないのか? など。

とりあえずコミットしてみようかとcを押したらNothing stagedとかなんとか言われた。staged、unstagedって何だろう。最初stag-edかと思ったらstage-dだったようだ。誰得UNIX-Blog: ステージを理解して git をもっと便利に使うを読んだ。

すげぇ、ファイル内の選択した部分だけをステージにあげてコミットできるんだ! これならこのインタフェースも納得だわ。確かに同一ファイルに違う目的の修正を施してしまって、分離するのが面倒だからそれを一度にコミットしてしまうということはよくあったんだよね。

2010-04-14

Git初体験2 msysgitを試す

msysgitをインストールしてC:Program FilesGitbinへパスを通してからやり直したらちゃんとできた。Cygwinのbashからも問題なく動いているように見える。

git addしたらgit commit。名前とメールアドレスを設定した方がいいと出たので、表示されたとおりに操作したら、%HOME%/.gitconfigが作成された。よしよし。

さて、サーバーとのやりとりも試してみようか。サーバー側にもGitを入れて、git –bare initでリポジトリを作る。–bareを指定するとローカルでやったときに作られた.gitディレクトリの内容相当が生でトップのディレクトリに展開されるみたいだ。確かに作業用のファイルなんかいらないので、サーバー上ではこの方が都合がいい。

ローカルに戻って、git remote add origin ssh://~でサーバーのリポジトリを設定して、git push origin masterすると……、んん? ssh鍵のパスフレーズを聞いてきた。win-ssh-askpassが効いてない? いや、どうやらmsysgitに付属のssh.exeが使われているせいらしい。__ssh.exeのようにファイル名を変えてCygwinのssh.exeが使われるようにしたら、パスフレーズを聞かれることはなくなった。

なるほど、細かい疑問点はいろいろあるけれど、ひとまずはよしとしよう。

次はMeadow上から操作できるようにしたい。Emacsクライアントはどうすればいいのだろうか。検索で上位に出てきたMagitというのを使えばいいのかな。とりあえず入れてみよう。

2010-04-14

Git初体験 Cygwinのgitで問題発生

なんかGitを勧められたのでこの際だから試してみることにした。CVSやSubversionで十分なんだけどなぁ。ぶつぶつ……。

せっかちな人のための git 入門 - git をインストールし、共同で開発できる環境を整えるまで : 僕は発展途上技術者を読んだ。なるほど、CVSやSubversionはローカルにワーキングコピーを作るけど、Gitは作業するところは常にリポジトリで、リポジトリ同士を同期していく感じなのかな。

とりあえずやってみよう。Cygwinでgitを入れて、適当なディレクトリを作ってgit init、readme.txtを書いてgit add readme.txt。

fatal: cannot use .git/info/exclude as an exclude file

あれ、なんだこりゃ。エラーメッセージで検索してみると、どうやらテキストモードでマウントしているとダメらしい。バイナリモードでマウントすべし、と。えー、バイナリモードだとCVSがUnix改行コードで入出力してしまうんですけど……。

どうしよう、道は二つ。

  • CVSをごった煮版のやつとかにしてバイナリマウントに切り替える(Gitは大丈夫なのかな)。
  • ほかのWindows用ビルド(msysgitとか?)を試してみる。

CVSを使うディレクトリはテキストにして、Gitを使うディレクトリはバイナリにする、なんてのはさすがに嫌。

2010-04-13

SVNリポジトリ

サーバーのトラブルでしばらくの間Subversionのリポジトリが使えなくて困っている。この際だからさくらのサーバーとかに移してしまおうかな。でもmod_svnは使えないからssh経由でしか使えないんだよね。まあ、一人で使うためのものだからそれでも良いのだけど。

2010-04-13

C++のテンプレートに疲れた

様々なバリエーションを生成するのにテンプレートを使っていたのだけど、もう疲れた。マクロでいいじゃん。

#define FUNCNAME func
#define DO_PROC1 0 //処理1をするかどうか。
#define DO_PROC2 0 //処理2をするかどうか。
#include "generate_func.h"

#define FUNCNAME funcWithProc1
#define DO_PROC1 1 //処理1をするかどうか。
#define DO_PROC2 0 //処理2をするかどうか。
#include "generate_func.h"

#define FUNCNAME funcWithProc2
#define DO_PROC1 0 //処理1をするかどうか。
#define DO_PROC2 1 //処理2をするかどうか。
#include "generate_func.h"

#define FUNCNAME funcWithProc1Proc2
#define DO_PROC1 1 //処理1をするかどうか。
#define DO_PROC2 1 //処理2をするかどうか。
#include "generate_func.h"

で、こんな感じで生成するものは、結局関数テンプレートだったり。