From 0791a547c070b6c6504553c30d93c59b99fa4cdb Mon Sep 17 00:00:00 2001 From: "Aaron L. Zeng" Date: Fri, 4 Sep 2026 16:27:10 -0400 Subject: [PATCH] Prevent vc-set-async-update error in process sentinel * lisp/vc/vc-dir.el (vc-dir-refresh): New OK-IF-ALREADY-RUNNING argument. (vc-dir): Use it so that we do not error if already refreshing (bug#81798). * lisp/vc/vc-dispatcher.el (vc-set-async-update): Use it such that if VC-Dir is already refreshing, we restart the refresh. --- lisp/vc/vc-dir.el | 26 ++++++++++++++++++++------ lisp/vc/vc-dispatcher.el | 4 ++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index b3d2dbb677a..1d732ab6d3c 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -1813,12 +1813,26 @@ Called by VC backend `dir-status-files' implementations." (with-current-buffer vc-parent-buffer (vc-dir-show-more-button text)))) -(defun vc-dir-refresh () +(defun vc-dir-refresh (&optional ok-if-already-running) "Refresh the contents of the *VC-Dir* buffer. -Throw an error if another update process is in progress." + +Signal an error if another update process is in progress, unless +OK-IF-ALREADY-RUNNING is non-nil. + +If OK-IF-ALREADY-RUNNING is `restart' and another update process is in +progress, kill it and start a new one." (interactive) - (if (vc-dir-busy) - (error "Another update process is in progress, cannot run two at a time") + (cond* + ((bind* (proc (and (buffer-live-p vc-dir-process-buffer) + (get-buffer-process vc-dir-process-buffer))))) + ((and proc (not ok-if-already-running)) + (error "Another update process is in progress, cannot run two at a time")) + ((and proc (not (eq ok-if-already-running 'restart)))) ;do nothing + (proc + ;; OK-IF-ALREADY-RUNNING is `restart'. + (delete-process proc) + :non-exit) + (t (let ((def-dir default-directory) (backend vc-dir-backend)) (when (and vc-dir-save-some-buffers-on-revert (not non-essential)) @@ -1860,7 +1874,7 @@ Throw an error if another update process is in progress." (vc-dir-refresh-files (mapcar #'vc-dir-fileinfo->name remaining)) (setq mode-line-process nil) - (run-hooks 'vc-dir-refresh-hook))))))))))) + (run-hooks 'vc-dir-refresh-hook)))))))))))) (defun vc-dir--refresh-headers (directory) "Refresh the headers for any VC-Dir buffers within DIRECTORY." @@ -2047,7 +2061,7 @@ These are the commands available for use in the file status buffer: (let (pop-up-windows) ; based on cvs-examine; bug#6204 (pop-to-buffer (vc-dir-prepare-status-buffer "*vc-dir*" dir backend))) (if (derived-mode-p 'vc-dir-mode) - (vc-dir-refresh) + (vc-dir-refresh t) ;; FIXME: find a better way to pass the backend to `vc-dir-mode'. (let ((use-vc-backend backend)) (vc-dir-mode) diff --git a/lisp/vc/vc-dispatcher.el b/lisp/vc/vc-dispatcher.el index bc025b177a6..a125abbc655 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -682,7 +682,7 @@ Sets `compilation-error-regexp-alist' in accordance with the VC backend." error-regexp-alist))) (run-mode-hooks 'vc-compilation-mode-hook)) -(declare-function vc-dir-refresh "vc-dir" ()) +(declare-function vc-dir-refresh "vc-dir" (&optional ok-if-already-running)) (defun vc-set-async-update (process-buffer) "Set a `vc-exec-after' action appropriate to the current buffer. @@ -706,7 +706,7 @@ If the current buffer visits a file, call `vc-refresh-state'." ;; Avoid interrupting the user with prompts to save ;; buffers. (let ((non-essential t)) - (vc-dir-refresh)))) + (vc-dir-refresh 'restart)))) ((derived-mode-p 'dired-mode) (run-delayed (when (= (buffer-modified-tick buf) tick)