diff --git a/doc/emacs/vc1-xtra.texi b/doc/emacs/vc1-xtra.texi index 9445368e2a6..e4e982f7861 100644 --- a/doc/emacs/vc1-xtra.texi +++ b/doc/emacs/vc1-xtra.texi @@ -896,6 +896,18 @@ to indicate which shell commands it runs, and logs additional messages when the commands finish. If the variable has any other non-@code{nil} value, Emacs both logs and displays these messages. +@vindex vc-display-failed-async-commands + VC mode runs certain shall commands asynchronously, allow you to +continue to use Emacs for other purposes while the command completes. +This is mostly used for commands which access the network, such as +pulling and pushing for distributed VCS (@pxref{Pulling / Pushing}). +When the command starts, VC displays a buffer into which the commands +output will be written. If @code{vc-display-failed-async-commands} is +non-@code{nil}, VC will additionally ensure that this buffer is +displayed when the command finishes running but failed. This means you +can freely close the window displaying the command's buffer and know +that it'll pop up again in the case that running the command failed. + @vindex vc-async-checkin Normally checkin operations are done synchronously; that is, Emacs waits until the checkin has completed before doing anything else. This diff --git a/etc/NEWS b/etc/NEWS index c23265a0d19..183b143756b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2932,6 +2932,11 @@ You can disable this by customizing 'vc-dir-show-outgoing-count' to nil. *** New user option 'vc-async-checkin' to enable async checkin operations. Currently only supported by the Git and Mercurial backends. ++++ +*** New user option 'vc-display-failed-async-commands'. +If non-nil, displays the buffer with the output of the failed command +when an asynchronous VC command (e.g. pulls and pushes) fails. + --- *** New 'log-edit-hook' option to display diff of changes to commit. 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 74c746e2fd5..190ed806028 100644 --- a/lisp/vc/vc-dispatcher.el +++ b/lisp/vc/vc-dispatcher.el @@ -150,6 +150,13 @@ logged in the *Messages* buffer, but not displayed." :type 'boolean :group 'vc) +(defcustom vc-display-failed-async-commands nil + "If non-nil, display VC async command buffers when the command fails. +Considers VC async commands to have failed whenever they die to a signal +or exit non-zero." + :type 'boolean + :group 'vc) + ;; Variables the user doesn't need to know about. (defvar vc-log-operation nil) @@ -527,7 +534,9 @@ that is inserted into the command line before the filename." (vc-run-delayed (let ((message-truncate-lines t) (inhibit-message vc--inhibit-message)) - (message "Done in background: %s" + (message "%s in background: %s" + (if (zerop (process-exit-status proc)) + "Done" "Failed") full-command))))) ;; Run synchronously (vc--command-message "Running in foreground: %s" @@ -596,7 +605,10 @@ Display the buffer in some window, but don't select it." (time-to-seconds (time-since start-time)))) (set-marker (process-mark proc) - (point)))))))))) + (point))))) + (when (and vc-display-failed-async-commands + (not (zerop (process-exit-status proc)))) + (vc--display-async-command-buffer buffer))))))) (setq buffer (get-buffer-create buffer)) (if (get-buffer-process buffer) (error "Another VC action on %s is running" root)) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 2b55cecb203..0d8e1dd0350 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2192,7 +2192,7 @@ have changed; continue with old fileset?" (current-buffer)))) ;; NOQUERY parameter non-nil. (vc-buffer-sync-fileset (list backend files))) (when register (vc-register (list backend register))) - (let (to-remove-props) + (let (to-remove-props proc) (cl-flet ((do-it () ;; We used to change buffers to get local value of ;; `vc-checkin-switches', but the (singular) local @@ -2206,18 +2206,23 @@ have changed; continue with old fileset?" (current-buffer)))) (remove-props-done-msg () (dolist (file to-remove-props) (vc-file-setprop file 'display-state nil)) - (message "Checking in %s...done" (vc-delistify files)))) + (message "Checking in %s...%s" + (vc-delistify files) + (if (or (not proc) + (zerop (process-exit-status proc))) + "done" "failed")))) (if do-async ;; Rely on `vc-set-async-update' to update properties ;; other than the display-only `display-state' property. (let ((ret (do-it))) (when (eq (car-safe ret) 'async) + (setq proc (cadr ret)) (dolist (file files) (let ((file (expand-file-name file))) (vc-file-setprop file 'display-state "committing") (vc-dir-resynch-file file) (push file to-remove-props))) - (vc-exec-after #'remove-props-done-msg nil (cadr ret))) + (vc-exec-after #'remove-props-done-msg nil proc)) ret) (prog2 (message "Checking in %s..." (vc-delistify files)) (with-vc-properties files (do-it)