aboutsummaryrefslogtreecommitdiffstats
path: root/admin/gitmerge.el
diff options
context:
space:
mode:
authorEli Zaretskii2021-11-03 20:50:34 +0200
committerEli Zaretskii2021-11-03 20:50:34 +0200
commit44c4139dfbab08307b4076ec2a4e85edb4b39cb8 (patch)
treebbd371c82dda6314a3896d6b0901f309ae1dc93f /admin/gitmerge.el
parentf78c819d9569ad18cc048554ddeb331a27a58989 (diff)
downloademacs-44c4139dfbab08307b4076ec2a4e85edb4b39cb8.tar.gz
emacs-44c4139dfbab08307b4076ec2a4e85edb4b39cb8.zip
Fix encoding issues in gitmerge.el, make it work on MS-Windows
* admin/gitmerge.el (gitmerge-emacs-version, gitmerge-show-log) (gitmerge-show-diff, gitmerge-show-files, gitmerge-missing) (gitmerge-setup-log-buffer, gitmerge-resolve) (gitmerge-commit-message, gitmerge-apply) (gitmerge-resolve-unmerged, gitmerge-repo-clean) (gitmerge-commit): Bind coding-system-for-read/write to the appropriate vc-git values. (gitmerge-apply) [windows-nt]: Pass long merge log messages via a temporary file. (gitmerge): Clarify the description of the "R" flag.
Diffstat (limited to 'admin/gitmerge.el')
-rw-r--r--admin/gitmerge.el83
1 files changed, 58 insertions, 25 deletions
diff --git a/admin/gitmerge.el b/admin/gitmerge.el
index 851212c7bb1..adb13fc4e2e 100644
--- a/admin/gitmerge.el
+++ b/admin/gitmerge.el
@@ -122,7 +122,8 @@ If nil, the function `gitmerge-default-branch' guesses.")
122 (with-temp-buffer 122 (with-temp-buffer
123 (if (not branch) 123 (if (not branch)
124 (insert-file-contents "configure.ac") 124 (insert-file-contents "configure.ac")
125 (call-process "git" nil t nil "show" (format "%s:configure.ac" branch)) 125 (let ((coding-system-for-read vc-git-log-output-coding-system))
126 (call-process "git" nil t nil "show" (format "%s:configure.ac" branch)))
126 (goto-char (point-min))) 127 (goto-char (point-min)))
127 (re-search-forward "^AC_INIT([^,]+, \\([0-9]+\\)\\.") 128 (re-search-forward "^AC_INIT([^,]+, \\([0-9]+\\)\\.")
128 (string-to-number (match-string 1)))) 129 (string-to-number (match-string 1))))
@@ -148,7 +149,8 @@ If nil, the function `gitmerge-default-branch' guesses.")
148 (pop-to-buffer (get-buffer-create gitmerge-output-buffer)) 149 (pop-to-buffer (get-buffer-create gitmerge-output-buffer))
149 (fundamental-mode) 150 (fundamental-mode)
150 (erase-buffer) 151 (erase-buffer)
151 (call-process "git" nil t nil "log" "-1" commit) 152 (let ((coding-system-for-read vc-git-log-output-coding-system))
153 (call-process "git" nil t nil "log" "-1" commit))
152 (goto-char (point-min)) 154 (goto-char (point-min))
153 (gitmerge-highlight-skip-regexp))))) 155 (gitmerge-highlight-skip-regexp)))))
154 156
@@ -160,7 +162,8 @@ If nil, the function `gitmerge-default-branch' guesses.")
160 (when commit 162 (when commit
161 (pop-to-buffer (get-buffer-create gitmerge-output-buffer)) 163 (pop-to-buffer (get-buffer-create gitmerge-output-buffer))
162 (erase-buffer) 164 (erase-buffer)
163 (call-process "git" nil t nil "diff-tree" "-p" commit) 165 (let ((coding-system-for-read vc-git-log-output-coding-system))
166 (call-process "git" nil t nil "diff-tree" "-p" commit))
164 (goto-char (point-min)) 167 (goto-char (point-min))
165 (diff-mode))))) 168 (diff-mode)))))
166 169
@@ -173,7 +176,9 @@ If nil, the function `gitmerge-default-branch' guesses.")
173 (pop-to-buffer (get-buffer-create gitmerge-output-buffer)) 176 (pop-to-buffer (get-buffer-create gitmerge-output-buffer))
174 (erase-buffer) 177 (erase-buffer)
175 (fundamental-mode) 178 (fundamental-mode)
176 (call-process "git" nil t nil "diff" "--name-only" (concat commit "^!")) 179 (let ((coding-system-for-read vc-git-log-output-coding-system))
180 (call-process "git" nil t nil "diff" "--name-only"
181 (concat commit "^!")))
177 (goto-char (point-min)))))) 182 (goto-char (point-min))))))
178 183
179(defun gitmerge-toggle-skip () 184(defun gitmerge-toggle-skip ()
@@ -216,9 +221,10 @@ if and why this commit should be skipped."
216 ;; Go through the log and remember all commits that match 221 ;; Go through the log and remember all commits that match
217 ;; `gitmerge-skip-regexp' or are marked by --cherry-mark. 222 ;; `gitmerge-skip-regexp' or are marked by --cherry-mark.
218 (with-temp-buffer 223 (with-temp-buffer
219 (call-process "git" nil t nil "log" "--cherry-mark" "--left-only" 224 (let ((coding-system-for-read vc-git-log-output-coding-system))
220 "--no-decorate" 225 (call-process "git" nil t nil "log" "--cherry-mark" "--left-only"
221 (concat from "..." (car (vc-git-branches)))) 226 "--no-decorate"
227 (concat from "..." (car (vc-git-branches)))))
222 (goto-char (point-max)) 228 (goto-char (point-max))
223 (while (re-search-backward "^commit \\(.+\\) \\([0-9a-f]+\\).*" nil t) 229 (while (re-search-backward "^commit \\(.+\\) \\([0-9a-f]+\\).*" nil t)
224 (let ((cherrymark (match-string 1)) 230 (let ((cherrymark (match-string 1))
@@ -241,9 +247,10 @@ if and why this commit should be skipped."
241 "Create the buffer for choosing commits." 247 "Create the buffer for choosing commits."
242 (with-current-buffer (get-buffer-create gitmerge-buffer) 248 (with-current-buffer (get-buffer-create gitmerge-buffer)
243 (erase-buffer) 249 (erase-buffer)
244 (call-process "git" nil t nil "log" "--left-only" 250 (let ((coding-system-for-read vc-git-log-output-coding-system))
245 "--pretty=format:%h %<(20,trunc) %an: %<(100,trunc) %s" 251 (call-process "git" nil t nil "log" "--left-only"
246 (concat from "..." (car (vc-git-branches)))) 252 "--pretty=format:%h %<(20,trunc) %an: %<(100,trunc) %s"
253 (concat from "..." (car (vc-git-branches)))))
247 (goto-char (point-min)) 254 (goto-char (point-min))
248 (while (looking-at "^\\([a-f0-9]+\\)") 255 (while (looking-at "^\\([a-f0-9]+\\)")
249 (let ((skipreason (gitmerge-skip-commit-p (match-string 1) commits))) 256 (let ((skipreason (gitmerge-skip-commit-p (match-string 1) commits)))
@@ -326,7 +333,8 @@ Returns non-nil if conflicts remain."
326 ;; (pop-to-buffer (current-buffer)) (debug 'before-resolve) 333 ;; (pop-to-buffer (current-buffer)) (debug 'before-resolve)
327 )) 334 ))
328 ;; Try to resolve the conflicts. 335 ;; Try to resolve the conflicts.
329 (let (temp) 336 (let ((coding-system-for-read vc-git-log-output-coding-system)
337 temp)
330 (cond 338 (cond
331 ;; FIXME when merging release branch to master, we still 339 ;; FIXME when merging release branch to master, we still
332 ;; need to detect and handle the case where NEWS was modified 340 ;; need to detect and handle the case where NEWS was modified
@@ -392,9 +400,10 @@ is nil, only the single commit BEG is merged."
392 (if end "s were " " was ") 400 (if end "s were " " was ")
393 "skipped:\n\n") 401 "skipped:\n\n")
394 "")) 402 ""))
395 (apply #'call-process "git" nil t nil "log" "--oneline" 403 (let ((coding-system-for-read vc-git-log-output-coding-system))
396 (if end (list (concat beg "~.." end)) 404 (apply #'call-process "git" nil t nil "log" "--oneline"
397 `("-1" ,beg))) 405 (if end (list (concat beg "~.." end))
406 `("-1" ,beg))))
398 (insert "\n") 407 (insert "\n")
399 ;; Truncate to 72 chars so that the resulting ChangeLog line fits in 80. 408 ;; Truncate to 72 chars so that the resulting ChangeLog line fits in 80.
400 (goto-char (point-min)) 409 (goto-char (point-min))
@@ -408,8 +417,9 @@ MISSING must be a list of SHA1 strings."
408 (with-current-buffer (get-buffer-create gitmerge-output-buffer) 417 (with-current-buffer (get-buffer-create gitmerge-output-buffer)
409 (erase-buffer) 418 (erase-buffer)
410 (let* ((skip (cdar missing)) 419 (let* ((skip (cdar missing))
420 (coding-system-for-read vc-git-log-output-coding-system)
411 (beg (car (pop missing))) 421 (beg (car (pop missing)))
412 end commitmessage) 422 end commitmessage commitmessage1 commitmessage-file status)
413 ;; Determine last revision with same boolean skip status. 423 ;; Determine last revision with same boolean skip status.
414 (while (and missing 424 (while (and missing
415 (eq (null (cdar missing)) 425 (eq (null (cdar missing))
@@ -423,12 +433,32 @@ MISSING must be a list of SHA1 strings."
423 (if end (concat ".." (substring end 0 6)) "")) 433 (if end (concat ".." (substring end 0 6)) ""))
424 (unless end 434 (unless end
425 (setq end beg)) 435 (setq end beg))
426 (unless (zerop 436 (when (eq system-type 'windows-nt)
427 (apply #'call-process "git" nil t nil "merge" "--no-ff" 437 ;; Command lines on MS-Windows cannot include newlines.
428 (append (when skip '("-s" "ours")) 438 ;; Since "git merge" doesn't accept a -F FILE option, we
429 `("-m" ,commitmessage ,end)))) 439 ;; commit the merge with a shortened single-line log message,
440 ;; and then invoke "git commit --amend" with the full log
441 ;; message from a temporary file.
442 (setq commitmessage1
443 ;; Make sure the commit message is at most a single line.
444 (car (split-string commitmessage "[\f\n\r\v]+")))
445 (setq commitmessage-file (make-nearby-temp-file "gitmerge-msg"))
446 (let ((coding-system-for-write vc-git-commits-coding-system))
447 (write-region commitmessage nil commitmessage-file nil 'silent)))
448 (unless (setq status
449 (zerop
450 (apply #'call-process "git" nil t nil "merge" "--no-ff"
451 (append (when skip '("-s" "ours"))
452 (if commitmessage-file
453 `("-m" ,commitmessage1 ,end)
454 `("-m" ,commitmessage ,end))))))
430 (gitmerge-write-missing missing from) 455 (gitmerge-write-missing missing from)
431 (gitmerge-resolve-unmerged))) 456 (gitmerge-resolve-unmerged))
457 (when (and commitmessage-file (file-exists-p commitmessage-file))
458 (if status
459 (call-process "git" nil t nil
460 "commit" "--amend" "-F" commitmessage-file))
461 (delete-file commitmessage-file)))
432 missing)) 462 missing))
433 463
434(defun gitmerge-resolve-unmerged () 464(defun gitmerge-resolve-unmerged ()
@@ -436,7 +466,8 @@ MISSING must be a list of SHA1 strings."
436Throw an user-error if we cannot resolve automatically." 466Throw an user-error if we cannot resolve automatically."
437 (with-current-buffer (get-buffer-create gitmerge-output-buffer) 467 (with-current-buffer (get-buffer-create gitmerge-output-buffer)
438 (erase-buffer) 468 (erase-buffer)
439 (let (files conflicted) 469 (let ((coding-system-for-read vc-git-log-output-coding-system)
470 files conflicted)
440 ;; List unmerged files 471 ;; List unmerged files
441 (if (not (zerop 472 (if (not (zerop
442 (call-process "git" nil t nil 473 (call-process "git" nil t nil
@@ -479,17 +510,19 @@ Throw an user-error if we cannot resolve automatically."
479(defun gitmerge-repo-clean () 510(defun gitmerge-repo-clean ()
480 "Return non-nil if repository is clean." 511 "Return non-nil if repository is clean."
481 (with-temp-buffer 512 (with-temp-buffer
513 (let ((coding-system-for-read vc-git-log-output-coding-system))
482 (call-process "git" nil t nil 514 (call-process "git" nil t nil
483 "diff" "--staged" "--name-only") 515 "diff" "--staged" "--name-only")
484 (call-process "git" nil t nil 516 (call-process "git" nil t nil
485 "diff" "--name-only") 517 "diff" "--name-only")
486 (zerop (buffer-size)))) 518 (zerop (buffer-size)))))
487 519
488(defun gitmerge-commit () 520(defun gitmerge-commit ()
489 "Commit, and return non-nil if it succeeds." 521 "Commit, and return non-nil if it succeeds."
490 (with-current-buffer (get-buffer-create gitmerge-output-buffer) 522 (with-current-buffer (get-buffer-create gitmerge-output-buffer)
491 (erase-buffer) 523 (let ((coding-system-for-read vc-git-log-output-coding-system))
492 (eq 0 (call-process "git" nil t nil "commit" "--no-edit")))) 524 (erase-buffer)
525 (eq 0 (call-process "git" nil t nil "commit" "--no-edit")))))
493 526
494(defun gitmerge-maybe-resume () 527(defun gitmerge-maybe-resume ()
495 "Check if we have to resume a merge. 528 "Check if we have to resume a merge.
@@ -603,7 +636,7 @@ Branch FROM will be prepended to the list."
603 "(s) Toggle skip, (l) Show log, (d) Show diff, " 636 "(s) Toggle skip, (l) Show log, (d) Show diff, "
604 "(f) Show files, (m) Start merge\n" 637 "(f) Show files, (m) Start merge\n"
605 (propertize "Flags: " 'font-lock-face 'bold) 638 (propertize "Flags: " 'font-lock-face 'bold)
606 "(C) Detected backport (cherry-mark), (R) Log matches " 639 "(C) Detected backport (cherry-mark), (R) Matches skip "
607 "regexp, (M) Manually picked\n\n") 640 "regexp, (M) Manually picked\n\n")
608 (gitmerge-mode) 641 (gitmerge-mode)
609 (pop-to-buffer (current-buffer)) 642 (pop-to-buffer (current-buffer))