Windows上で hg commit する時 utf-8 でコミットログを書くとエラー

date:2013-04-15
status:close
type:bug

結論

Mercurialの仕様で環境に合わせて文字コードを決定しているようです。 エディタの使用文字コードを切り替えることで回避しました。 emacs の場合 -l オプションで init.el の読み込みファイルを指定できるので cp932 用の init.el を作成して、それを hgrc の設定で切り替えて回避しました。

内容

Windows上で hg commit する時 utf-8 でコミットログを書くと エラーでコミットできないことがあります。

D:\ng\home\sximadaw3>hg commit
transaction abort!
rollback completed
note: commit message saved in .hg\last-message.txt
abort: decoding near '@縺セ縺吶€・: 'cp932' codec can't decode byte 0x82 in posi
tion 77: incomplete multibyte sequence!

私の場合コミットログの記述に emacs を使用しています。 init.elutf8 をデフォルトで使用する設定になっています。 そのためコミットログも utf8 で保存されます。

Mercurialはコミットログを次のような順序で保存しています。

  1. 一時ファイルを作成する

  2. hgrc で指定されているエディタで一時ファイルを開く

  3. ユーザが一時ファイルにコミットログを記述しセーブする

  4. Mercurialはプラットフォームにあわせて文字コードを選び、 選んだ文字コードで一時ファイルのデータをデコードする

    ノート

    このとき unicode になります。

  5. 変換した unicode のコミットログを utf8 でエンコードする

  6. その後いろいろ。。。 (あまり関係がないので省略します)

Mercurialはプラットフォームによって使用する文字コードを変更しています。 Windowsの場合 cp932 を使用します。 emacs でセーブした時点では utf8 でセーブされています。 そこに cp932 でデコードしようとするのでエラーしています。

cp932用のinit.elを作成して対処

utf-8 に切り替えているのは init.el 内なので cp932 用のファイルを作って読み込むinit.elを切り替えるのがよさそうです。

-l で切り替えることができます。

hgrc に次のようなエントリを記述しておくと commit時に cp932 の文字コードを使って開いてくれます。

editor = emacs -l ~/.emacs.d/init.cp932.el -rv

init.el はこちらです。最後の数行で文字コードを設定しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
;; color theme select
(require 'cc-mode)
;;(require 'color-theme)
;;(require 'menu-tree)

(add-hook 'html-helper-load-hook '(lambda () (require 'html-font)))
(add-hook 'html-helper-mode "html-helper-mode" "Yay HTML" t)

;; c-mode style settings
(setq c-default-style "k&r")
(add-hook 'c-mode-command-hook
	  '(lambda ()
	     (progn
	       (c-toggle-hungry-style 1)
	       (setq c-basic-offset 4 indent-tabs-mode nil))))

(setq auto-mode-alist
      (append
       '(("\\.hpp$" . c++-mode)
	 ("\\.h$" . c++-mode)
	 ) auto-mode-alist))

;; settings
(setq frame-title-format "%f - sakura 1.5.5.0")

(custom-set-variables
 '(column-number-mode t)
 '(line-number-mode t)
 '(fringe-mode 0 nil (fringe))
 '(scroll-bar-mode nil)
 '(tool-bar-mode nil)
 '(tooltip-mode nil)
 ;;'(menu-bar-mode nil)
 )

(eval-after-load "color-theme"
  '(progn 
     (color-theme-initialize)
     (color-theme-midnight)
     ))

(custom-set-faces
 ;;'(mode-line ((t (:foreground "#111111" :background "#000000" :box (:line-width 1 :color "#000000" :style nil)))))
 '(mode-line-inactive ((t (:foreground "#111111" :background "#000000" :box (:line-width 1 :color "#000000" :style nil)))))
 '(rst-level-0-face ((t (:background "black"))) t)
 '(rst-level-1-face ((t (:background "black"))) t)
 '(rst-level-2-face ((t (:background "black"))) t)
 '(rst-level-3-face ((t (:background "black"))) t)
 '(rst-level-4-face ((t (:background "black"))) t)
 '(rst-level-5-face ((t (:background "black"))) t)
 '(rst-level-6-face ((t (:background "black"))) t)
 )

(set-face-foreground 'minibuffer-prompt "#111111")

(require 'server)
(unless (server-running-p) (server-start))
(setq server-visit-hook
      '(lambda ()
	 (raise-frame (selected-frame))
	 (x-forcus-frame (selected-frame))))

(setq inhibit-startup-message t)
(global-set-key "\C-h" 'delete-backword-char)
(keyboard-translate ?\C-h ?\C-?)
(global-set-key "\C-h" nil)
(define-key global-map "\C-xl" 'goto-line)

(define-key global-map [f1] 'start-kbd-macro)
(define-key global-map [f2] 'end-kbd-macro)
(define-key global-map [f3] 'call-last-kbd-macro)
(fset 'tab-region [tab ?\C-n])


;; charactor encoding
;;(set-language-environment 'cp932)
;;(prefer-coding-system 'cp932)
(set-default-coding-systems 'cp932-unix)
(set-keyboard-coding-system 'cp932-unix)
inserted by FC2 system