aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2016-04-10 19:04:33 +0300
committerEli Zaretskii2016-04-10 19:04:33 +0300
commit668c7bc5ba761551ef0d08dc96080eb5aa169da1 (patch)
tree645abdf4180791db1bf7bf8959252020db9f606b
parentb57076929f0e904864e1457d5789f2fe6652fc84 (diff)
downloademacs-668c7bc5ba761551ef0d08dc96080eb5aa169da1.tar.gz
emacs-668c7bc5ba761551ef0d08dc96080eb5aa169da1.zip
Improve handling of non-ASCII characters in Git log messages
* lisp/vc/vc-git.el (vc-git-commits-coding-system): Now a defcustom. (vc-git-log-output-coding-system): New defcustom. (vc-git-print-log, vc-git-command, vc-git--call): Use 'vc-git-log-output-coding-system' for reading stuff from Git. Don't override values of 'coding-system-for-read/write' if they are bound by caller -- this allows the user to force an encoding via "C-x RET c". (vc-git-checkin): On MS-Windows, pass the log message via a temporary file, to work around the limitations on passing non-ASCII characters via command-line arguments. Force using the 'locale-coding-system' for Git command-line arguments. This fixes problems with non-ASCII commit log messages on MS-Windows. (Bug#23076) * etc/NEWS: Mention the new vc-git related defcustoms.
-rw-r--r--etc/NEWS11
-rw-r--r--lisp/vc/vc-git.el66
2 files changed, 62 insertions, 15 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 78d725bddf2..f5e5548ad63 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -987,6 +987,17 @@ back-end for the buffer's file, or remove it from version control.
987the color range from 'vc-annotate-color-map' is applied to the 987the color range from 'vc-annotate-color-map' is applied to the
988background or to the foreground. 988background or to the foreground.
989 989
990---
991*** New options for customizing encoding of Git commit log messages.
992The new options `vc-git-commits-coding-system' and
993`vc-git-log-output-coding-system' allow to customize the encoding of
994the log messages sent to Git when committing, and the decoding of the
995log messages read from Git history commands. Both default to UTF-8;
996if you customize them, make sure they are consistent with the Git
997config variables i18n.commitEncoding and i18n.logOutputEncoding.
998(`vc-git-commits-coding-system' existed previously, but was a
999variable, not a user option.)
1000
990+++ 1001+++
991*** 'compare-windows' now compares text with the most recently selected window 1002*** 'compare-windows' now compares text with the most recently selected window
992instead of the next window. If you want the previous behavior of 1003instead of the next window. If you want the previous behavior of
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el
index 2921b6470da..f8b0b6fcd54 100644
--- a/lisp/vc/vc-git.el
+++ b/lisp/vc/vc-git.el
@@ -165,8 +165,20 @@ matching the resulting Git log output, and KEYWORDS is a list of
165 :type '(list string string (repeat sexp)) 165 :type '(list string string (repeat sexp))
166 :version "24.1") 166 :version "24.1")
167 167
168(defvar vc-git-commits-coding-system 'utf-8 168(defcustom vc-git-commits-coding-system 'utf-8
169 "Default coding system for git commits.") 169 "Default coding system for sending commit log messages to Git.
170
171Should be consistent with the Git config value i18n.commitEncoding,
172and should also be consistent with `locale-coding-system'."
173 :type '(coding-system :tag "Coding system to encode Git commit logs")
174 :version "25.1")
175
176(defcustom vc-git-log-output-coding-system 'utf-8
177 "Default coding system for receiving log output from Git.
178
179Should be consistent with the Git config value i18n.logOutputEncoding."
180 :type '(coding-system :tag "Coding system to decode Git log output")
181 :version "25.1")
170 182
171;; History of Git commands. 183;; History of Git commands.
172(defvar vc-git-history nil) 184(defvar vc-git-history nil)
@@ -680,21 +692,43 @@ It is based on `log-edit-mode', and has Git-specific extensions.")
680 (default-directory (expand-file-name root)) 692 (default-directory (expand-file-name root))
681 (only (or (cdr files) 693 (only (or (cdr files)
682 (not (equal root (abbreviate-file-name file1))))) 694 (not (equal root (abbreviate-file-name file1)))))
683 (coding-system-for-write vc-git-commits-coding-system)) 695 (pcsw coding-system-for-write)
696 (coding-system-for-write
697 ;; On MS-Windows, we must encode command-line arguments in
698 ;; the system codepage.
699 (if (eq system-type 'windows-nt)
700 locale-coding-system
701 (or coding-system-for-write vc-git-commits-coding-system)))
702 (msg-file
703 ;; On MS-Windows, pass the commit log message through a
704 ;; file, to work around the limitation that command-line
705 ;; arguments must be in the system codepage, and therefore
706 ;; might not support the non-ASCII characters in the log
707 ;; message.
708 (if (eq system-type 'windows-nt) (make-temp-file "git-msg"))))
684 (cl-flet ((boolean-arg-fn 709 (cl-flet ((boolean-arg-fn
685 (argument) 710 (argument)
686 (lambda (value) (when (equal value "yes") (list argument))))) 711 (lambda (value) (when (equal value "yes") (list argument)))))
687 ;; When operating on the whole tree, better pass "-a" than ".", since "." 712 ;; When operating on the whole tree, better pass "-a" than ".", since "."
688 ;; fails when we're committing a merge. 713 ;; fails when we're committing a merge.
689 (apply 'vc-git-command nil 0 (if only files) 714 (apply 'vc-git-command nil 0 (if only files)
690 (nconc (list "commit" "-m") 715 (nconc (if msg-file (list "commit" "-F" msg-file)
691 (log-edit-extract-headers 716 (list "commit" "-m"))
692 `(("Author" . "--author") 717 (let ((args
693 ("Date" . "--date") 718 (log-edit-extract-headers
694 ("Amend" . ,(boolean-arg-fn "--amend")) 719 `(("Author" . "--author")
695 ("Sign-Off" . ,(boolean-arg-fn "--signoff"))) 720 ("Date" . "--date")
696 comment) 721 ("Amend" . ,(boolean-arg-fn "--amend"))
697 (if only (list "--only" "--") '("-a"))))))) 722 ("Sign-Off" . ,(boolean-arg-fn "--signoff")))
723 comment)))
724 (when msg-file
725 (let ((coding-system-for-write
726 (or pcsw vc-git-commits-coding-system)))
727 (write-region (car args) nil msg-file))
728 (setq args (cdr args)))
729 args)
730 (if only (list "--only" "--") '("-a")))))
731 (if (and msg-file (file-exists-p msg-file)) (delete-file msg-file))))
698 732
699(defun vc-git-find-revision (file rev buffer) 733(defun vc-git-find-revision (file rev buffer)
700 (let* (process-file-side-effects 734 (let* (process-file-side-effects
@@ -854,7 +888,7 @@ If SHORTLOG is non-nil, use a short format based on `vc-git-root-log-format'.
854If START-REVISION is non-nil, it is the newest revision to show. 888If START-REVISION is non-nil, it is the newest revision to show.
855If LIMIT is non-nil, show no more than this many entries." 889If LIMIT is non-nil, show no more than this many entries."
856 (let ((coding-system-for-read 890 (let ((coding-system-for-read
857 (or coding-system-for-read vc-git-commits-coding-system))) 891 (or coding-system-for-read vc-git-log-output-coding-system)))
858 ;; `vc-do-command' creates the buffer, but we need it before running 892 ;; `vc-do-command' creates the buffer, but we need it before running
859 ;; the command. 893 ;; the command.
860 (vc-setup-buffer buffer) 894 (vc-setup-buffer buffer)
@@ -1387,7 +1421,7 @@ This command shares argument histories with \\[rgrep] and \\[grep]."
1387The difference to vc-do-command is that this function always invokes 1421The difference to vc-do-command is that this function always invokes
1388`vc-git-program'." 1422`vc-git-program'."
1389 (let ((coding-system-for-read 1423 (let ((coding-system-for-read
1390 (or coding-system-for-read vc-git-commits-coding-system)) 1424 (or coding-system-for-read vc-git-log-output-coding-system))
1391 (coding-system-for-write 1425 (coding-system-for-write
1392 (or coding-system-for-write vc-git-commits-coding-system))) 1426 (or coding-system-for-write vc-git-commits-coding-system)))
1393 (apply 'vc-do-command (or buffer "*vc*") okstatus vc-git-program 1427 (apply 'vc-do-command (or buffer "*vc*") okstatus vc-git-program
@@ -1412,8 +1446,10 @@ The difference to vc-do-command is that this function always invokes
1412 ;; directories. We enable `inhibit-null-byte-detection', otherwise 1446 ;; directories. We enable `inhibit-null-byte-detection', otherwise
1413 ;; Tramp's eol conversion might be confused. 1447 ;; Tramp's eol conversion might be confused.
1414 (let ((inhibit-null-byte-detection t) 1448 (let ((inhibit-null-byte-detection t)
1415 (coding-system-for-read vc-git-commits-coding-system) 1449 (coding-system-for-read
1416 (coding-system-for-write vc-git-commits-coding-system) 1450 (or coding-system-for-read vc-git-log-output-coding-system))
1451 (coding-system-for-write
1452 (or coding-system-for-write vc-git-commits-coding-system))
1417 (process-environment (cons "PAGER=" process-environment))) 1453 (process-environment (cons "PAGER=" process-environment)))
1418 (apply 'process-file vc-git-program nil buffer nil command args))) 1454 (apply 'process-file vc-git-program nil buffer nil command args)))
1419 1455