Magitで部分的なstageができるようになったのはいいんだけど、同じ行を別な目的で修正してしまった場合はどうすればいいんだろう。行をコピーして、一方をコメントで残し、一方をstageしたい内容にすればいいのかな。で、コミットしたらコメントで残したほうだけにする、と。
Magitで部分的なstageができるようになったのはいいんだけど、同じ行を別な目的で修正してしまった場合はどうすればいいんだろう。行をコピーして、一方をコメントで残し、一方をstageしたい内容にすればいいのかな。で、コミットしたらコメントで残したほうだけにする、と。
今週は生活習慣改善週間とします。
言語まわりの方針・設定はこの前のままで。
.emacs
; *Meadowとgitとの間はutf-8にする。 ; コミットログをutf-8で記録したい。 ; i18n.commitEncodingはコミット時に変換してくれるわけではないっぽい。 ; また、magit.el内でgit log --format %sを使っている場所があるので、 ; どうしてもutf-8でやりとりせざるを得ない。 ; この設定はshell-file-name経由でgitを呼ぶ場合には適用されないので注意。 (modify-coding-system-alist 'process "git" '(utf-8-dos . utf-8-unix)) ; magitを使えるようにする。 (cond ((locate-library "magit") (require 'magit) ;; git diffとgit applyの文字エンコーディングを ;; .gitattributesのencoding属性に合わせて調整するラッパーを使う。 ;; git-encwrapperをコンパイルしてパスの通ったところに置くこと。 (setq magit-git-executable "git-encwrapper") ;; magitがshell-file-name(sh.exe)経由でgitを呼ぶとき、utf-8で入出力する。 ;; magitがshell-file-nameを使ってprocess-fileやcall-processする関数には次のものがある(magit-0.7では)。 ;; - magit-shell-command-to-string ;; - magit-git-exit-code ;; - magit-run-shell ;; これらの呼び出し時、一時的にprocess-coding-system-alistを書き換える。 ;; ;; shに対するprocess-coding-system-alistをutf-8にしている人は不要。 (defun add-sh-utf8-process-coding-system-alist () (cons (cons shell-file-name '(utf-8-dos . utf-8-unix)) process-coding-system-alist)) (defadvice magit-shell-command-to-string (around magit-shell-command-to-string-proc-coding activate) (let ((process-coding-system-alist (add-sh-utf8-process-coding-system-alist))) ad-do-it)) (defadvice magit-git-exit-code (around magit-git-exit-code-proc-coding activate) (let ((process-coding-system-alist (add-sh-utf8-process-coding-system-alist))) ad-do-it)) (defadvice magit-run-shell (around magit-run-shell-proc-coding activate) (let ((process-coding-system-alist (add-sh-utf8-process-coding-system-alist))) ad-do-it)) ))
2010-07-07追記: magit-0.8.1ではshell-file-name経由でgitを呼ぶ箇所は無くなったので、上記のdefun~defadvice部分は削除してよい。
2013-08-12追記: elisp側で何とかするコードを書きました。複数の文字符号化方式が混在しているときのmagit文字化け対策コード
結局gitのラッパーを書いた。git-encwrapper(GitHubを初めて利用してみた)。
このラッパーは標準入出力を通過するパッチテキストのファイルヘッダーを認識して、ファイル名に対応するgitattributesのencoding属性を取得し、そのエンコーディングを元に、パッチテキストのファイル内容部分を再エンコードする。
このラッパーのおかげで、エンコーディングを統一するためにexternal diffとnkfを使う必要はなくなった。ただ、nkfのように自動でエンコーディングを判定しないので、.gitattributesファイルに「*.txt encoding=utf-8」のように記述しないといけない。
apply時にはdiffの逆変換を行うので、Magitが(エンコーディングが)統一されたdiffの出力を元に部分適用のパッチを作成して(標準入力経由で)gitに送り返してきても、先にラッパーが(エンコーディングが)バラバラの状態に戻すので、gitは正しくパッチを適用することが出来る。
これで、今度こそようやくまともに使えるようになったと思う。マージ操作のやり方とかまだ学んでいないから、また動かないケースに遭遇するかもしれないけど……。
それにしても、何でこんなに苦労しなければならないのかさっぱり分からない。Meadow、Emacs、Windows、Linux、どこで使うにしてもいろいろな文字エンコーディングを柔軟に使いたい場合、素のgitでは使い物にならないと思う。こういう要求ってそれほど特殊なのものだろうか? 誰も気がつかないはず無いんだけど。現にgit-guiではそれなりに対応しているわけだし。git自体にエンコーディングに関する処理を入れたくない方針なのであれば(ログについてはすでに処理してるけどね。それも中途半端に)、git-cui(guiではなく)みたいなフロントエンドが必要なんじゃないんだろうか。私が知らないだけで、すでに何らかの対処がされていてもおかしくないと思う。いや、そうであってほしい。