diff options
| author | Eli Zaretskii | 2021-11-03 20:50:34 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2021-11-03 20:50:34 +0200 |
| commit | 44c4139dfbab08307b4076ec2a4e85edb4b39cb8 (patch) | |
| tree | bbd371c82dda6314a3896d6b0901f309ae1dc93f /admin/gitmerge.el | |
| parent | f78c819d9569ad18cc048554ddeb331a27a58989 (diff) | |
| download | emacs-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.el | 83 |
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." | |||
| 436 | Throw an user-error if we cannot resolve automatically." | 466 | Throw 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)) |