diff options
| author | Sean Whitton | 2025-04-05 10:58:35 +0800 |
|---|---|---|
| committer | Sean Whitton | 2025-05-09 10:52:06 +0100 |
| commit | 8e02537d0be3cfdeaaf7764e2ef2db8b66de542a (patch) | |
| tree | 8c01f49798e56296a2780eb56ef79bbd3703a7a8 | |
| parent | 3739b86f5af654ec0ae3e47a3662e19ea79d2b3c (diff) | |
| download | emacs-8e02537d0be3cfdeaaf7764e2ef2db8b66de542a.tar.gz emacs-8e02537d0be3cfdeaaf7764e2ef2db8b66de542a.zip | |
New vc-async-checkin user option
* lisp/vc/vc.el (vc-async-checkin): New option.
(vc-checkin): Don't use with-vc-properties on or display
messages around asynchronous checkins.
* lisp/vc/vc-git.el (vc-git-checkin):
* lisp/vc/vc-hg.el (vc-hg-checkin, vc-hg-checkin-patch): Perform
an async checkin operation when vc-async-checkin is non-nil.
* doc/emacs/vc1-xtra.texi (General VC Options):
* etc/NEWS: Document the new option.
* lisp/vc/vc-dispatcher.el (vc-wait-for-process-before-save):
New function.
(vc-set-async-update): If the current buffer visits a file, call
vc-refresh-state.
* lisp/vc/vc-hg.el (vc-wait-for-process-before-save): Autoload.
(vc-hg--async-command, vc-hg--async-buffer, vc-hg--command-1):
New utilities, partially factored out of vc-hg-command.
(vc-hg-merge-branch): Use vc-hg--async-command, thereby newly
respecting vc-hg-global-switches.
| -rw-r--r-- | doc/emacs/vc1-xtra.texi | 19 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | lisp/vc/vc-dispatcher.el | 66 | ||||
| -rw-r--r-- | lisp/vc/vc-git.el | 69 | ||||
| -rw-r--r-- | lisp/vc/vc-hg.el | 82 | ||||
| -rw-r--r-- | lisp/vc/vc.el | 63 |
6 files changed, 219 insertions, 84 deletions
diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index 5c448e741f2..b4e1e82dcb9 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi | |||
| @@ -380,6 +380,25 @@ appropriate version control system. If @code{vc-command-messages} is | |||
| 380 | non-@code{nil}, VC displays messages to indicate which shell commands | 380 | non-@code{nil}, VC displays messages to indicate which shell commands |
| 381 | it runs, and additional messages when the commands finish. | 381 | it runs, and additional messages when the commands finish. |
| 382 | 382 | ||
| 383 | @vindex vc-async-checkin | ||
| 384 | Normally checkin operations are done synchronously; that is, Emacs | ||
| 385 | waits until the checkin has completed before doing anything else. This | ||
| 386 | can be inconvenient for repositories in which the checkin operation is | ||
| 387 | slow, such as Git repositories where you check in changes to very large | ||
| 388 | files, or Mercurial repositories with a very large number of files. | ||
| 389 | |||
| 390 | For those backends which support it, setting @code{vc-async-checkin} | ||
| 391 | to non-nil switches to doing checkin operations asynchronously. This is | ||
| 392 | particularly useful as a directory local variable in repositories where | ||
| 393 | checkin operations are slow | ||
| 394 | (@pxref{Directory Local Variables,,,elisp,GNU Emacs Lisp Reference Manual}). | ||
| 395 | |||
| 396 | While an asynchronous checkin operation is in progress, if you use | ||
| 397 | @kbd{C-x C-s} to save a buffer visiting any file within the current VC | ||
| 398 | tree, then the operation reverts to a synchronous checkin and Emacs | ||
| 399 | waits for it to complete before saving the buffer. This is to avoid | ||
| 400 | nondeterminism regarding exactly what changes get checked in. | ||
| 401 | |||
| 383 | @node RCS and SCCS | 402 | @node RCS and SCCS |
| 384 | @subsubsection Options for RCS and SCCS | 403 | @subsubsection Options for RCS and SCCS |
| 385 | 404 | ||
| @@ -1752,6 +1752,10 @@ were added, removed or edited, Emacs would refuse to proceed. | |||
| 1752 | Now Emacs prompts to first register the unregistered files, so that all | 1752 | Now Emacs prompts to first register the unregistered files, so that all |
| 1753 | files in the fileset are in a compatible state for a checkin. | 1753 | files in the fileset are in a compatible state for a checkin. |
| 1754 | 1754 | ||
| 1755 | +++ | ||
| 1756 | *** New user option 'vc-async-checkin' to enable async checkin operations. | ||
| 1757 | Currently only supported by the Git and Mercurial backends. | ||
| 1758 | |||
| 1755 | --- | 1759 | --- |
| 1756 | *** New 'log-edit-hook' option to display diff of changes to commit. | 1760 | *** New 'log-edit-hook' option to display diff of changes to commit. |
| 1757 | You can customize 'log-edit-hook' to include its new | 1761 | You can customize 'log-edit-hook' to include its new |
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index a454a0bfc78..27837ddace1 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el | |||
| @@ -294,6 +294,41 @@ Only run CODE if the SUCCESS process has a zero exit code." | |||
| 294 | (declare (indent 0) (debug (def-body))) | 294 | (declare (indent 0) (debug (def-body))) |
| 295 | `(vc-exec-after (lambda () ,@body))) | 295 | `(vc-exec-after (lambda () ,@body))) |
| 296 | 296 | ||
| 297 | (defun vc-wait-for-process-before-save (proc message) | ||
| 298 | "Make Emacs wait for PROC before saving buffers under current VC tree. | ||
| 299 | If waiting for PROC takes more than a second, display MESSAGE. | ||
| 300 | |||
| 301 | This is used to implement `vc-async-checkin'. It effectively switches | ||
| 302 | to a synchronous checkin in the case that the user asks to save a buffer | ||
| 303 | under the tree in which the checkin operation is running. | ||
| 304 | |||
| 305 | The hook installed by this function will make Emacs unconditionally wait | ||
| 306 | for PROC if the root of the current VC tree couldn't be determined, and | ||
| 307 | whenever writing out a buffer which doesn't have any `buffer-file-name' | ||
| 308 | yet." | ||
| 309 | (letrec ((root (vc-root-dir)) | ||
| 310 | (hook | ||
| 311 | (lambda () | ||
| 312 | (cond ((not (process-live-p proc)) | ||
| 313 | (remove-hook 'before-save-hook hook)) | ||
| 314 | ((or (and buffer-file-name | ||
| 315 | (or (not root) | ||
| 316 | (file-in-directory-p buffer-file-name | ||
| 317 | root))) | ||
| 318 | ;; No known buffer file name but we are saving: | ||
| 319 | ;; perhaps writing out a `special-mode' buffer. | ||
| 320 | ;; A `before-save-hook' cannot know whether or | ||
| 321 | ;; not it'll be written out under ROOT. | ||
| 322 | ;; Err on the side of switching to synchronous. | ||
| 323 | (not buffer-file-name)) | ||
| 324 | (with-delayed-message (1 message) | ||
| 325 | (while (process-live-p proc) | ||
| 326 | (when (input-pending-p) | ||
| 327 | (discard-input)) | ||
| 328 | (sit-for 0.05))) | ||
| 329 | (remove-hook 'before-save-hook hook)))))) | ||
| 330 | (add-hook 'before-save-hook hook))) | ||
| 331 | |||
| 297 | (defvar vc-filter-command-function #'list | 332 | (defvar vc-filter-command-function #'list |
| 298 | "Function called to transform VC commands before execution. | 333 | "Function called to transform VC commands before execution. |
| 299 | The function is called inside the buffer in which the command | 334 | The function is called inside the buffer in which the command |
| @@ -525,23 +560,24 @@ asynchronous VC command has completed. PROCESS-BUFFER is the | |||
| 525 | buffer for the asynchronous VC process. | 560 | buffer for the asynchronous VC process. |
| 526 | 561 | ||
| 527 | If the current buffer is a VC Dir buffer, call `vc-dir-refresh'. | 562 | If the current buffer is a VC Dir buffer, call `vc-dir-refresh'. |
| 528 | If the current buffer is a Dired buffer, revert it." | 563 | If the current buffer is a Dired buffer, revert it. |
| 564 | If the current buffer visits a file, call `vc-refresh-state'." | ||
| 529 | (let* ((buf (current-buffer)) | 565 | (let* ((buf (current-buffer)) |
| 530 | (tick (buffer-modified-tick buf))) | 566 | (tick (buffer-modified-tick buf))) |
| 531 | (cond | 567 | (cl-macrolet ((run-delayed (&rest body) |
| 532 | ((derived-mode-p 'vc-dir-mode) | 568 | `(with-current-buffer process-buffer |
| 533 | (with-current-buffer process-buffer | 569 | (vc-run-delayed |
| 534 | (vc-run-delayed | 570 | (when (buffer-live-p buf) |
| 535 | (if (buffer-live-p buf) | 571 | (with-current-buffer buf |
| 536 | (with-current-buffer buf | 572 | ,@body)))))) |
| 537 | (vc-dir-refresh)))))) | 573 | (cond ((derived-mode-p 'vc-dir-mode) |
| 538 | ((derived-mode-p 'dired-mode) | 574 | (run-delayed (vc-dir-refresh))) |
| 539 | (with-current-buffer process-buffer | 575 | ((derived-mode-p 'dired-mode) |
| 540 | (vc-run-delayed | 576 | (run-delayed |
| 541 | (and (buffer-live-p buf) | 577 | (when (= (buffer-modified-tick buf) tick) |
| 542 | (= (buffer-modified-tick buf) tick) | 578 | (revert-buffer)))) |
| 543 | (with-current-buffer buf | 579 | (buffer-file-name |
| 544 | (revert-buffer))))))))) | 580 | (run-delayed (vc-refresh-state))))))) |
| 545 | 581 | ||
| 546 | ;; These functions are used to ensure that the view the user sees is up to date | 582 | ;; These functions are used to ensure that the view the user sees is up to date |
| 547 | ;; even if the dispatcher client mode has messed with file contents (as in, | 583 | ;; even if the dispatcher client mode has messed with file contents (as in, |
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 4acacaff203..53dedb05320 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el | |||
| @@ -1209,32 +1209,49 @@ It is based on `log-edit-mode', and has Git-specific extensions." | |||
| 1209 | (vc-git-command nil 0 nil "apply" "--cached" patch-file) | 1209 | (vc-git-command nil 0 nil "apply" "--cached" patch-file) |
| 1210 | (delete-file patch-file)))) | 1210 | (delete-file patch-file)))) |
| 1211 | (when to-stash (vc-git--stash-staged-changes to-stash))) | 1211 | (when to-stash (vc-git--stash-staged-changes to-stash))) |
| 1212 | ;; When operating on the whole tree, better pass "-a" than ".", | 1212 | (let ((files (and only (not vc-git-patch-string) files)) |
| 1213 | ;; since "." fails when we're committing a merge. | 1213 | (args (vc-git--log-edit-extract-headers comment)) |
| 1214 | (apply #'vc-git-command nil 0 | 1214 | (buffer (format "*vc-git : %s*" (expand-file-name root))) |
| 1215 | (if (and only (not vc-git-patch-string)) files) | 1215 | (post |
| 1216 | (nconc (if msg-file (list "commit" "-F" | 1216 | (lambda () |
| 1217 | (file-local-name msg-file)) | 1217 | (when (and msg-file (file-exists-p msg-file)) |
| 1218 | (list "commit" "-m")) | 1218 | (delete-file msg-file)) |
| 1219 | (let ((args | 1219 | (when to-stash |
| 1220 | (vc-git--log-edit-extract-headers comment))) | 1220 | (let ((cached (make-nearby-temp-file "git-cached"))) |
| 1221 | (when msg-file | 1221 | (unwind-protect |
| 1222 | (let ((coding-system-for-write | 1222 | (progn |
| 1223 | (or pcsw vc-git-commits-coding-system))) | 1223 | (with-temp-file cached |
| 1224 | (write-region (car args) nil msg-file)) | 1224 | (vc-git-command t 0 nil "stash" "show" "-p")) |
| 1225 | (setq args (cdr args))) | 1225 | (vc-git-command nil 0 "apply" "--cached" cached)) |
| 1226 | args) | 1226 | (delete-file cached)) |
| 1227 | (unless vc-git-patch-string | 1227 | (vc-git-command nil 0 nil "stash" "drop")))))) |
| 1228 | (if only (list "--only" "--") '("-a"))))) | 1228 | (when msg-file |
| 1229 | (if (and msg-file (file-exists-p msg-file)) (delete-file msg-file)) | 1229 | (let ((coding-system-for-write |
| 1230 | (when to-stash | 1230 | (or pcsw vc-git-commits-coding-system))) |
| 1231 | (let ((cached (make-nearby-temp-file "git-cached"))) | 1231 | (write-region (car args) nil msg-file)) |
| 1232 | (unwind-protect | 1232 | (setq args (cdr args))) |
| 1233 | (progn (with-temp-file cached | 1233 | (setq args (nconc (if msg-file |
| 1234 | (vc-git-command t 0 nil "stash" "show" "-p")) | 1234 | (list "commit" "-F" |
| 1235 | (vc-git-command nil 0 nil "apply" "--cached" cached)) | 1235 | (file-local-name msg-file)) |
| 1236 | (delete-file cached)) | 1236 | (list "commit" "-m")) |
| 1237 | (vc-git-command nil 0 nil "stash" "drop"))))) | 1237 | args |
| 1238 | ;; When operating on the whole tree, better pass | ||
| 1239 | ;; "-a" than ".", since "." fails when we're | ||
| 1240 | ;; committing a merge. | ||
| 1241 | (and (not vc-git-patch-string) | ||
| 1242 | (if only (list "--only" "--") '("-a"))))) | ||
| 1243 | (if vc-async-checkin | ||
| 1244 | (progn (vc-wait-for-process-before-save | ||
| 1245 | (apply #'vc-do-async-command buffer root | ||
| 1246 | vc-git-program (nconc args files)) | ||
| 1247 | "Finishing checking in files...") | ||
| 1248 | (with-current-buffer buffer | ||
| 1249 | (vc-run-delayed | ||
| 1250 | (vc-compilation-mode 'git) | ||
| 1251 | (funcall post))) | ||
| 1252 | (vc-set-async-update buffer)) | ||
| 1253 | (apply #'vc-git-command nil 0 files args) | ||
| 1254 | (funcall post))))) | ||
| 1238 | 1255 | ||
| 1239 | (defun vc-git--stash-staged-changes (files) | 1256 | (defun vc-git--stash-staged-changes (files) |
| 1240 | "Stash only the staged changes to FILES." | 1257 | "Stash only the staged changes to FILES." |
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index a18c463c848..5c0758b93b2 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el | |||
| @@ -1181,25 +1181,42 @@ If toggling on, also insert its message into the buffer." | |||
| 1181 | "Major mode for editing Hg log messages. | 1181 | "Major mode for editing Hg log messages. |
| 1182 | It is based on `log-edit-mode', and has Hg-specific extensions.") | 1182 | It is based on `log-edit-mode', and has Hg-specific extensions.") |
| 1183 | 1183 | ||
| 1184 | (autoload 'vc-wait-for-process-before-save "vc-dispatcher") | ||
| 1185 | |||
| 1184 | (defun vc-hg-checkin (files comment &optional _rev) | 1186 | (defun vc-hg-checkin (files comment &optional _rev) |
| 1185 | "Hg-specific version of `vc-backend-checkin'. | 1187 | "Hg-specific version of `vc-backend-checkin'. |
| 1186 | REV is ignored." | 1188 | REV is ignored." |
| 1187 | (apply #'vc-hg-command nil 0 files | 1189 | (let ((args (nconc (list "commit" "-m") |
| 1188 | (nconc (list "commit" "-m") | 1190 | (vc-hg--extract-headers comment)))) |
| 1189 | (vc-hg--extract-headers comment)))) | 1191 | (if vc-async-checkin |
| 1192 | (let ((buffer (vc-hg--async-buffer))) | ||
| 1193 | (vc-wait-for-process-before-save | ||
| 1194 | (apply #'vc-hg--async-command buffer (nconc args files)) | ||
| 1195 | "Finishing checking in files...") | ||
| 1196 | (with-current-buffer buffer | ||
| 1197 | (vc-run-delayed | ||
| 1198 | (vc-compilation-mode 'hg))) | ||
| 1199 | (vc-set-async-update buffer)) | ||
| 1200 | (apply #'vc-hg-command nil 0 files args)))) | ||
| 1190 | 1201 | ||
| 1191 | (defun vc-hg-checkin-patch (patch-string comment) | 1202 | (defun vc-hg-checkin-patch (patch-string comment) |
| 1192 | (let ((patch-file (make-temp-file "hg-patch"))) | 1203 | (let ((patch-file (make-temp-file "hg-patch"))) |
| 1193 | (write-region patch-string nil patch-file) | 1204 | (write-region patch-string nil patch-file) |
| 1194 | (unwind-protect | 1205 | (unwind-protect |
| 1195 | (progn | 1206 | (let ((args (list "update" |
| 1207 | "--merge" "--tool" "internal:local" | ||
| 1208 | "tip"))) | ||
| 1196 | (apply #'vc-hg-command nil 0 nil | 1209 | (apply #'vc-hg-command nil 0 nil |
| 1197 | (nconc (list "import" "--bypass" patch-file "-m") | 1210 | (nconc (list "import" "--bypass" patch-file "-m") |
| 1198 | (vc-hg--extract-headers comment))) | 1211 | (vc-hg--extract-headers comment))) |
| 1199 | (vc-hg-command nil 0 nil | 1212 | (if vc-async-checkin |
| 1200 | "update" | 1213 | (let ((buffer (vc-hg--async-buffer))) |
| 1201 | "--merge" "--tool" "internal:local" | 1214 | (apply #'vc-hg--async-command buffer args) |
| 1202 | "tip")) | 1215 | (with-current-buffer buffer |
| 1216 | (vc-run-delayed | ||
| 1217 | (vc-compilation-mode 'hg))) | ||
| 1218 | (vc-set-async-update buffer)) | ||
| 1219 | (apply #'vc-hg-command nil 0 nil args))) | ||
| 1203 | (delete-file patch-file)))) | 1220 | (delete-file patch-file)))) |
| 1204 | 1221 | ||
| 1205 | (defun vc-hg--extract-headers (comment) | 1222 | (defun vc-hg--extract-headers (comment) |
| @@ -1543,15 +1560,14 @@ call \"hg push -r REVS\" to push the specified revisions REVS." | |||
| 1543 | (defun vc-hg-merge-branch () | 1560 | (defun vc-hg-merge-branch () |
| 1544 | "Prompt for revision and merge it into working directory. | 1561 | "Prompt for revision and merge it into working directory. |
| 1545 | This runs the command \"hg merge\"." | 1562 | This runs the command \"hg merge\"." |
| 1546 | (let* ((root (vc-hg-root default-directory)) | 1563 | (let ((buffer (vc-hg--async-buffer)) |
| 1547 | (buffer (format "*vc-hg : %s*" (expand-file-name root))) | 1564 | (branch (vc-read-revision "Revision to merge: "))) |
| 1548 | ;; Disable pager. | 1565 | (apply #'vc-hg--async-command buffer |
| 1549 | (process-environment (cons "HGPLAIN=1" process-environment)) | ||
| 1550 | (branch (vc-read-revision "Revision to merge: "))) | ||
| 1551 | (apply #'vc-do-async-command buffer root vc-hg-program | ||
| 1552 | (append '("--config" "ui.report_untrusted=0" "merge") | 1566 | (append '("--config" "ui.report_untrusted=0" "merge") |
| 1553 | (unless (string= branch "") (list branch)))) | 1567 | (and (not (string-empty-p branch)) (list branch)))) |
| 1554 | (with-current-buffer buffer (vc-run-delayed (vc-compilation-mode 'hg))) | 1568 | (with-current-buffer buffer |
| 1569 | (vc-run-delayed | ||
| 1570 | (vc-compilation-mode 'hg))) | ||
| 1555 | (vc-set-async-update buffer))) | 1571 | (vc-set-async-update buffer))) |
| 1556 | 1572 | ||
| 1557 | (defun vc-hg-prepare-patch (rev) | 1573 | (defun vc-hg-prepare-patch (rev) |
| @@ -1571,15 +1587,33 @@ This runs the command \"hg merge\"." | |||
| 1571 | "A wrapper around `vc-do-command' for use in vc-hg.el. | 1587 | "A wrapper around `vc-do-command' for use in vc-hg.el. |
| 1572 | This function differs from `vc-do-command' in that it invokes | 1588 | This function differs from `vc-do-command' in that it invokes |
| 1573 | `vc-hg-program', and passes `vc-hg-global-switches' to it before FLAGS." | 1589 | `vc-hg-program', and passes `vc-hg-global-switches' to it before FLAGS." |
| 1590 | (vc-hg--command-1 #'vc-do-command | ||
| 1591 | (list (or buffer "*vc*") | ||
| 1592 | okstatus vc-hg-program file-or-list) | ||
| 1593 | flags)) | ||
| 1594 | |||
| 1595 | (defun vc-hg--async-command (buffer &rest args) | ||
| 1596 | "Wrapper around `vc-do-async-command' like `vc-hg-command'." | ||
| 1597 | (vc-hg--command-1 #'vc-do-async-command | ||
| 1598 | (list buffer (vc-hg-root default-directory) | ||
| 1599 | vc-hg-program) | ||
| 1600 | args)) | ||
| 1601 | |||
| 1602 | (defun vc-hg--async-buffer () | ||
| 1603 | "Buffer passed to `vc-do-async-command' by vg-hg.el commands. | ||
| 1604 | Intended for use via the `vc-hg--async-command' wrapper." | ||
| 1605 | (format "*vc-hg : %s*" | ||
| 1606 | (expand-file-name (vc-hg-root default-directory)))) | ||
| 1607 | |||
| 1608 | (defun vc-hg--command-1 (fun args flags) | ||
| 1574 | ;; Disable pager. | 1609 | ;; Disable pager. |
| 1575 | (let ((process-environment (cons "HGPLAIN=1" process-environment)) | 1610 | (let ((process-environment (cons "HGPLAIN=1" process-environment))) |
| 1576 | (flags (append '("--config" "ui.report_untrusted=0") flags))) | 1611 | (apply fun (append args |
| 1577 | (apply #'vc-do-command (or buffer "*vc*") | 1612 | '("--config" "ui.report_untrusted=0") |
| 1578 | okstatus vc-hg-program file-or-list | 1613 | (if (stringp vc-hg-global-switches) |
| 1579 | (if (stringp vc-hg-global-switches) | 1614 | (cons vc-hg-global-switches flags) |
| 1580 | (cons vc-hg-global-switches flags) | 1615 | (append vc-hg-global-switches |
| 1581 | (append vc-hg-global-switches | 1616 | flags)))))) |
| 1582 | flags))))) | ||
| 1583 | 1617 | ||
| 1584 | (defun vc-hg-root (file) | 1618 | (defun vc-hg-root (file) |
| 1585 | (vc-find-root file ".hg")) | 1619 | (vc-find-root file ".hg")) |
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index f58290ccd69..dcb32e9da67 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el | |||
| @@ -1002,6 +1002,24 @@ the URL-REGEXP of the association." | |||
| 1002 | :value-type ,vc-cloneable-backends-custom-type) | 1002 | :value-type ,vc-cloneable-backends-custom-type) |
| 1003 | :version "31.1") | 1003 | :version "31.1") |
| 1004 | 1004 | ||
| 1005 | (defcustom vc-async-checkin nil | ||
| 1006 | "If non-nil, checkin operations should be done asynchronously. | ||
| 1007 | |||
| 1008 | This is useful to set as a directory local variable in repositories | ||
| 1009 | where the VCS in use performs checkin operations slowly. | ||
| 1010 | For example, Git is slow when committing changes to very large files, | ||
| 1011 | and Mercurial can be slow when there is a very large number of files. | ||
| 1012 | |||
| 1013 | While an asynchronous checkin operation is in progress, Emacs installs a | ||
| 1014 | `before-save-hook' to switch back to a synchronous checkin if you ask to | ||
| 1015 | save buffers under the current VC tree. This is to avoid nondeterminism | ||
| 1016 | regarding exactly what changes get checked in. | ||
| 1017 | |||
| 1018 | Not supported by all backends." | ||
| 1019 | :type 'boolean | ||
| 1020 | :safe #'booleanp | ||
| 1021 | :version "31.1") | ||
| 1022 | |||
| 1005 | 1023 | ||
| 1006 | ;; File property caching | 1024 | ;; File property caching |
| 1007 | 1025 | ||
| @@ -1857,26 +1875,33 @@ Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'." | |||
| 1857 | (lambda () | 1875 | (lambda () |
| 1858 | (vc-call-backend backend 'log-edit-mode)) | 1876 | (vc-call-backend backend 'log-edit-mode)) |
| 1859 | (lambda (files comment) | 1877 | (lambda (files comment) |
| 1860 | (message "Checking in %s..." (vc-delistify files)) | ||
| 1861 | ;; "This log message intentionally left almost blank". | 1878 | ;; "This log message intentionally left almost blank". |
| 1862 | ;; RCS 5.7 gripes about white-space-only comments too. | 1879 | ;; RCS 5.7 gripes about whitespace-only comments too. |
| 1863 | (or (and comment (string-match "[^\t\n ]" comment)) | 1880 | (unless (and comment (string-match "[^\t\n ]" comment)) |
| 1864 | (setq comment "*** empty log message ***")) | 1881 | (setq comment "*** empty log message ***")) |
| 1865 | (with-vc-properties | 1882 | (cl-labels ((do-it () |
| 1866 | files | 1883 | ;; We used to change buffers to get local value of |
| 1867 | ;; We used to change buffers to get local value of | 1884 | ;; `vc-checkin-switches', but the (singular) local |
| 1868 | ;; vc-checkin-switches, but 'the' local buffer is | 1885 | ;; buffer is not well defined for filesets. |
| 1869 | ;; not a well-defined concept for filesets. | 1886 | (if patch-string |
| 1870 | (progn | 1887 | (vc-call-backend backend 'checkin-patch |
| 1871 | (if patch-string | 1888 | patch-string comment) |
| 1872 | (vc-call-backend backend 'checkin-patch patch-string comment) | 1889 | (vc-call-backend backend 'checkin |
| 1873 | (vc-call-backend backend 'checkin files comment rev)) | 1890 | files comment rev)) |
| 1874 | (mapc #'vc-delete-automatic-version-backups files)) | 1891 | (mapc #'vc-delete-automatic-version-backups files))) |
| 1875 | `((vc-state . up-to-date) | 1892 | (if (and vc-async-checkin |
| 1876 | (vc-checkout-time . ,(file-attribute-modification-time | 1893 | ;; Backends which support `vc-async-checkin'. |
| 1877 | (file-attributes file))) | 1894 | (memq backend '(Git Hg))) |
| 1878 | (vc-working-revision . nil))) | 1895 | ;; Rely on `vc-set-async-update' to update properties. |
| 1879 | (message "Checking in %s...done" (vc-delistify files))) | 1896 | (do-it) |
| 1897 | (message "Checking in %s..." (vc-delistify files)) | ||
| 1898 | (with-vc-properties files (do-it) | ||
| 1899 | `((vc-state . up-to-date) | ||
| 1900 | (vc-checkout-time | ||
| 1901 | . ,(file-attribute-modification-time | ||
| 1902 | (file-attributes file))) | ||
| 1903 | (vc-working-revision . nil))) | ||
| 1904 | (message "Checking in %s...done" (vc-delistify files))))) | ||
| 1880 | 'vc-checkin-hook | 1905 | 'vc-checkin-hook |
| 1881 | backend | 1906 | backend |
| 1882 | patch-string)) | 1907 | patch-string)) |