diff options
| author | Sean Whitton | 2025-07-07 15:44:34 +0100 |
|---|---|---|
| committer | Sean Whitton | 2025-07-07 15:44:34 +0100 |
| commit | 6c0c985cee4e1ce4798a4ab192e8ca36013e7fa1 (patch) | |
| tree | 8597f23b78dc36785f78fd7051f0a28868cca6ee | |
| parent | f85f3c30ddc986e6d6c6ae738cee578556cc0eac (diff) | |
| download | emacs-6c0c985cee4e1ce4798a4ab192e8ca36013e7fa1.tar.gz emacs-6c0c985cee4e1ce4798a4ab192e8ca36013e7fa1.zip | |
Resolve FIXME regarding running vc-checkin-hook
Running vc-checkin-hook needs to be delayed in the case of an
async checkin. As a quick fix we had been relying on the
backend checkin functions to run the hook in the async case.
This restores handling running the hook in generic code even for
the async case.
* lisp/vc/vc.el (vc-checkin): Always pass vc-checkin-hook to
vc-start-logentry. Return the result of calling the backend
'checkin-patch' or 'checkin' function to vc-finish-logentry.
* lisp/vc/vc-dispatcher.el (vc-finish-logentry): If the log
operation returns a cons of the form (async . #<process ...>),
use vc-exec-after to delay vc-resynch-buffer and hooks until the
async process completes. Approach suggested by Dmitry Gutov.
* lisp/vc/vc-git.el (vc-git-checkin):
* lisp/vc/vc-hg.el (vc-hg-checkin): For an async checkin, return
a cons (async . #<process ...>) containing the async checkin
process. No longer run vc-checkin-hook.
* lisp/vc/vc.el (with-vc-properties): Return the result of
evaluating FORM.
* lisp/vc/vc-dispatcher.el (vc-exec-after): Change to PROC's
buffer before calling vc-set-mode-line-busy-indicator.
| -rw-r--r-- | lisp/vc/vc-dispatcher.el | 55 | ||||
| -rw-r--r-- | lisp/vc/vc-git.el | 8 | ||||
| -rw-r--r-- | lisp/vc/vc-hg.el | 8 | ||||
| -rw-r--r-- | lisp/vc/vc.el | 75 |
4 files changed, 76 insertions, 70 deletions
diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index 97f1971dd1d..97c58ca9ea2 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el | |||
| @@ -276,7 +276,10 @@ Only run CODE if the SUCCESS process has a zero exit code." | |||
| 276 | (if (functionp code) (funcall code) (eval code t)))) | 276 | (if (functionp code) (funcall code) (eval code t)))) |
| 277 | ;; If a process is running, add CODE to the sentinel | 277 | ;; If a process is running, add CODE to the sentinel |
| 278 | ((eq (process-status proc) 'run) | 278 | ((eq (process-status proc) 'run) |
| 279 | (vc-set-mode-line-busy-indicator) | 279 | (let ((buf (process-buffer proc))) |
| 280 | (when (buffer-live-p buf) | ||
| 281 | (with-current-buffer buf | ||
| 282 | (vc-set-mode-line-busy-indicator)))) | ||
| 280 | (letrec ((fun (lambda (p _msg) | 283 | (letrec ((fun (lambda (p _msg) |
| 281 | (remove-function (process-sentinel p) fun) | 284 | (remove-function (process-sentinel p) fun) |
| 282 | (vc--process-sentinel p code success)))) | 285 | (vc--process-sentinel p code success)))) |
| @@ -863,26 +866,38 @@ the buffer contents as a comment." | |||
| 863 | 866 | ||
| 864 | ;; save the parameters held in buffer-local variables | 867 | ;; save the parameters held in buffer-local variables |
| 865 | (let ((logbuf (current-buffer)) | 868 | (let ((logbuf (current-buffer)) |
| 866 | (log-operation vc-log-operation) | 869 | (log-operation vc-log-operation) |
| 867 | (log-fileset vc-log-fileset) | 870 | (log-fileset vc-log-fileset) |
| 868 | (log-entry (buffer-string)) | 871 | (log-entry (buffer-string)) |
| 869 | (after-hook vc-log-after-operation-hook)) | 872 | (after-hook vc-log-after-operation-hook) |
| 873 | (parent vc-parent-buffer)) | ||
| 870 | ;; OK, do it to it | 874 | ;; OK, do it to it |
| 871 | (with-current-buffer vc-parent-buffer | 875 | (let ((log-operation-ret |
| 872 | (funcall log-operation log-fileset log-entry)) | 876 | (with-current-buffer parent |
| 873 | (pop-to-buffer vc-parent-buffer) | 877 | (funcall log-operation log-fileset log-entry)))) |
| 874 | (setq vc-log-operation nil) | 878 | (pop-to-buffer parent) |
| 875 | 879 | (setq vc-log-operation nil) | |
| 876 | ;; Quit windows on logbuf. | 880 | |
| 877 | (cond ((not logbuf)) | 881 | ;; Quit windows on logbuf. |
| 878 | (vc-delete-logbuf-window | 882 | (cond ((not logbuf)) |
| 879 | (quit-windows-on logbuf t (selected-frame))) | 883 | (vc-delete-logbuf-window |
| 880 | (t | 884 | (quit-windows-on logbuf t (selected-frame))) |
| 881 | (quit-windows-on logbuf nil 0))) | 885 | (t |
| 882 | 886 | (quit-windows-on logbuf nil 0))) | |
| 883 | ;; Now make sure we see the expanded headers | 887 | |
| 884 | (mapc (lambda (file) (vc-resynch-buffer file t t)) log-fileset) | 888 | ;; Now make sure we see the expanded headers. |
| 885 | (run-hooks after-hook 'vc-finish-logentry-hook))) | 889 | ;; If the `vc-log-operation' started an async operation then we |
| 890 | ;; need to delay running the hooks. It tells us whether it did | ||
| 891 | ;; that with a special return value. | ||
| 892 | (cl-flet ((resynch-and-hooks () | ||
| 893 | (when (buffer-live-p parent) | ||
| 894 | (with-current-buffer parent | ||
| 895 | (mapc (lambda (file) (vc-resynch-buffer file t t)) | ||
| 896 | log-fileset) | ||
| 897 | (run-hooks after-hook 'vc-finish-logentry-hook))))) | ||
| 898 | (if (eq (car-safe log-operation-ret) 'async) | ||
| 899 | (vc-exec-after #'resynch-and-hooks nil (cadr log-operation-ret)) | ||
| 900 | (resynch-and-hooks)))))) | ||
| 886 | 901 | ||
| 887 | (defun vc-dispatcher-browsing () | 902 | (defun vc-dispatcher-browsing () |
| 888 | "Are we in a directory browser buffer?" | 903 | "Are we in a directory browser buffer?" |
diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 6a8e5924198..958f3f7e6d1 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el | |||
| @@ -1273,11 +1273,9 @@ It is based on `log-edit-mode', and has Git-specific extensions." | |||
| 1273 | (with-current-buffer buffer | 1273 | (with-current-buffer buffer |
| 1274 | (vc-run-delayed | 1274 | (vc-run-delayed |
| 1275 | (vc-compilation-mode 'git) | 1275 | (vc-compilation-mode 'git) |
| 1276 | (funcall post) | 1276 | (funcall post))) |
| 1277 | (when (buffer-live-p parent) | 1277 | (vc-set-async-update buffer) |
| 1278 | (with-current-buffer parent | 1278 | (list 'async (get-buffer-process buffer))) |
| 1279 | (run-hooks 'vc-checkin-hook))))) | ||
| 1280 | (vc-set-async-update buffer)) | ||
| 1281 | (apply #'vc-git-command nil 0 files args) | 1279 | (apply #'vc-git-command nil 0 files args) |
| 1282 | (funcall post))))) | 1280 | (funcall post))))) |
| 1283 | 1281 | ||
diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index e5a7c10ed96..b5556cfb3ba 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el | |||
| @@ -1229,11 +1229,9 @@ REV is ignored." | |||
| 1229 | "Finishing checking in files...") | 1229 | "Finishing checking in files...") |
| 1230 | (with-current-buffer buffer | 1230 | (with-current-buffer buffer |
| 1231 | (vc-run-delayed | 1231 | (vc-run-delayed |
| 1232 | (vc-compilation-mode 'hg) | 1232 | (vc-compilation-mode 'hg))) |
| 1233 | (when (buffer-live-p parent) | 1233 | (vc-set-async-update buffer) |
| 1234 | (with-current-buffer parent | 1234 | (list 'async (get-buffer-process buffer))) |
| 1235 | (run-hooks 'vc-checkin-hook))))) | ||
| 1236 | (vc-set-async-update buffer)) | ||
| 1237 | (apply #'vc-hg-command nil 0 files args)))) | 1235 | (apply #'vc-hg-command nil 0 files args)))) |
| 1238 | 1236 | ||
| 1239 | (defun vc-hg-checkin-patch (patch-string comment) | 1237 | (defun vc-hg-checkin-patch (patch-string comment) |
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index a6a4aa50579..b20cadc94cc 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el | |||
| @@ -1081,24 +1081,25 @@ If any of FILES is actually a directory, then do the same for all | |||
| 1081 | buffers for files in that directory. | 1081 | buffers for files in that directory. |
| 1082 | SETTINGS is an association list of property/value pairs. After | 1082 | SETTINGS is an association list of property/value pairs. After |
| 1083 | executing FORM, set those properties from SETTINGS that have not yet | 1083 | executing FORM, set those properties from SETTINGS that have not yet |
| 1084 | been updated to their corresponding values." | 1084 | been updated to their corresponding values. |
| 1085 | Return the result of evaluating FORM." | ||
| 1085 | (declare (debug t)) | 1086 | (declare (debug t)) |
| 1086 | `(let ((vc-touched-properties (list t)) | 1087 | `(let ((vc-touched-properties (list t)) |
| 1087 | (flist nil)) | 1088 | (flist nil)) |
| 1088 | (dolist (file ,files) | 1089 | (prog2 (dolist (file ,files) |
| 1089 | (if (file-directory-p file) | 1090 | (if (file-directory-p file) |
| 1090 | (dolist (buffer (buffer-list)) | 1091 | (dolist (buffer (buffer-list)) |
| 1091 | (let ((fname (buffer-file-name buffer))) | 1092 | (let ((fname (buffer-file-name buffer))) |
| 1092 | (when (and fname (string-prefix-p file fname)) | 1093 | (when (and fname (string-prefix-p file fname)) |
| 1093 | (push fname flist)))) | 1094 | (push fname flist)))) |
| 1094 | (push file flist))) | 1095 | (push file flist))) |
| 1095 | ,form | 1096 | ,form |
| 1096 | (dolist (file flist) | 1097 | (dolist (file flist) |
| 1097 | (dolist (setting ,settings) | 1098 | (dolist (setting ,settings) |
| 1098 | (let ((property (car setting))) | 1099 | (let ((property (car setting))) |
| 1099 | (unless (memq property vc-touched-properties) | 1100 | (unless (memq property vc-touched-properties) |
| 1100 | (put (intern file vc-file-prop-obarray) | 1101 | (put (intern file vc-file-prop-obarray) |
| 1101 | property (cdr setting)))))))) | 1102 | property (cdr setting))))))))) |
| 1102 | 1103 | ||
| 1103 | ;;; Code for deducing what fileset and backend to assume | 1104 | ;;; Code for deducing what fileset and backend to assume |
| 1104 | 1105 | ||
| @@ -2005,34 +2006,28 @@ have changed; continue with old fileset?" (current-buffer)))) | |||
| 2005 | ;; NOQUERY parameter non-nil. | 2006 | ;; NOQUERY parameter non-nil. |
| 2006 | (vc-buffer-sync-fileset (list backend files))) | 2007 | (vc-buffer-sync-fileset (list backend files))) |
| 2007 | (when register (vc-register (list backend register))) | 2008 | (when register (vc-register (list backend register))) |
| 2008 | (cl-labels ((do-it () | 2009 | (cl-flet ((do-it () |
| 2009 | ;; We used to change buffers to get local value of | 2010 | ;; We used to change buffers to get local value of |
| 2010 | ;; `vc-checkin-switches', but the (singular) local | 2011 | ;; `vc-checkin-switches', but the (singular) local |
| 2011 | ;; buffer is not well defined for filesets. | 2012 | ;; buffer is not well defined for filesets. |
| 2012 | (if patch-string | 2013 | (prog1 (if patch-string |
| 2013 | (vc-call-backend backend 'checkin-patch | 2014 | (vc-call-backend backend 'checkin-patch |
| 2014 | patch-string comment) | 2015 | patch-string comment) |
| 2015 | (vc-call-backend backend 'checkin | 2016 | (vc-call-backend backend 'checkin |
| 2016 | files comment rev)) | 2017 | files comment rev)) |
| 2017 | (mapc #'vc-delete-automatic-version-backups files))) | 2018 | (mapc #'vc-delete-automatic-version-backups files)))) |
| 2018 | (if do-async | 2019 | (if do-async |
| 2019 | ;; Rely on `vc-set-async-update' to update properties. | 2020 | ;; Rely on `vc-set-async-update' to update properties. |
| 2020 | (do-it) | 2021 | (do-it) |
| 2021 | (message "Checking in %s..." (vc-delistify files)) | 2022 | (prog2 (message "Checking in %s..." (vc-delistify files)) |
| 2022 | (with-vc-properties files (do-it) | 2023 | (with-vc-properties files (do-it) |
| 2023 | `((vc-state . up-to-date) | 2024 | `((vc-state . up-to-date) |
| 2024 | (vc-checkout-time | 2025 | (vc-checkout-time |
| 2025 | . ,(file-attribute-modification-time | 2026 | . ,(file-attribute-modification-time |
| 2026 | (file-attributes file))) | 2027 | (file-attributes file))) |
| 2027 | (vc-working-revision . nil))) | 2028 | (vc-working-revision . nil))) |
| 2028 | (message "Checking in %s...done" (vc-delistify files))))) | 2029 | (message "Checking in %s...done" (vc-delistify files)))))) |
| 2029 | 2030 | 'vc-checkin-hook | |
| 2030 | ;; FIXME: In the async case we need the hook to be added to the | ||
| 2031 | ;; buffer with the checkin process, using `vc-run-delayed'. Ideally | ||
| 2032 | ;; the identity of that buffer would be exposed to this code, | ||
| 2033 | ;; somehow, so we could always handle running the hook up here. | ||
| 2034 | (and (not do-async) 'vc-checkin-hook) | ||
| 2035 | |||
| 2036 | backend | 2031 | backend |
| 2037 | patch-string))) | 2032 | patch-string))) |
| 2038 | 2033 | ||