aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Whitton2025-07-07 15:44:34 +0100
committerSean Whitton2025-07-07 15:44:34 +0100
commit6c0c985cee4e1ce4798a4ab192e8ca36013e7fa1 (patch)
tree8597f23b78dc36785f78fd7051f0a28868cca6ee
parentf85f3c30ddc986e6d6c6ae738cee578556cc0eac (diff)
downloademacs-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.el55
-rw-r--r--lisp/vc/vc-git.el8
-rw-r--r--lisp/vc/vc-hg.el8
-rw-r--r--lisp/vc/vc.el75
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
1081buffers for files in that directory. 1081buffers for files in that directory.
1082SETTINGS is an association list of property/value pairs. After 1082SETTINGS is an association list of property/value pairs. After
1083executing FORM, set those properties from SETTINGS that have not yet 1083executing FORM, set those properties from SETTINGS that have not yet
1084been updated to their corresponding values." 1084been updated to their corresponding values.
1085Return 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