diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index ffa3b7f2a58..4e531805f26 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1070,11 +1070,18 @@ non-@code{nil}, @kbd{C-x v I} becomes a prefix key, and @code{vc-log-incoming} becomes bound to @kbd{C-x v I L}. @item M-x vc-root-diff-incoming -Display a diff of the changes that a pull operation will retrieve. +Display a diff of all changes that a pull operation will retrieve. If you customize @code{vc-use-incoming-outgoing-prefixes} to non-@code{nil}, this command becomes available on @kbd{C-x v I D}. +@item M-x vc-fileset-diff-incoming +Display a diff of changes that a pull operation will retrieve, but +limited to the current fileset. + +If you customize @code{vc-use-incoming-outgoing-prefixes} to +non-@code{nil}, this command becomes available on @kbd{C-x v I =}. + @item C-x v O Display log entries for the changes that will be sent by the next ``push'' operation (@code{vc-log-outgoing}). @@ -1084,12 +1091,19 @@ non-@code{nil}, @kbd{C-x v O} becomes a prefix key, and @code{vc-log-outgoing} becomes bound to @kbd{C-x v O L}. @item M-x vc-root-diff-outgoing -Display a diff of the changes that will be sent by the next push +Display a diff of all changes that will be sent by the next push operation. If you customize @code{vc-use-incoming-outgoing-prefixes} to non-@code{nil}, this command is bound to @kbd{C-x v O D}. +@item M-x vc-fileset-diff-outgoing +Display a diff of changes that will be sent by the next push operation, +but limited to the current fileset. + +If you customize @code{vc-use-incoming-outgoing-prefixes} to +non-@code{nil}, this command becomes available on @kbd{C-x v O =}. + @item C-x v h Display the history of changes made in the region of file visited by the current buffer (@code{vc-region-history}). @@ -1176,13 +1190,22 @@ version control system can be a branch name. @findex vc-root-diff-outgoing The closely related commands @code{vc-root-diff-incoming} and @code{vc-root-diff-outgoing} are the diff analogues of -@code{vc-log-incoming} and @code{vc-log-outgoing}. These display a diff -buffer reporting the changes that would be pulled or pushed. You can +@code{vc-log-incoming} and @code{vc-log-outgoing}. These display diff +buffers reporting the changes that would be pulled or pushed. You can use a prefix argument here too to specify a particular remote location. @code{vc-root-diff-outgoing} is useful as a way to preview your push and quickly check that all and only the changes you intended to include were committed and will be pushed. +@findex vc-fileset-diff-incoming +@findex vc-fileset-diff-outgoing + The commands @code{vc-fileset-diff-incoming} and +@code{vc-fileset-diff-outgoing} are very similar. They also display +changes that would be pulled or pushed. The difference is that the +diffs reported are limited to the current fileset. Don't forget that +actual pull and push operations always affect the whole working tree, +not just the current fileset. + @cindex VC log buffer, commands in @cindex vc-log buffer In the @file{*vc-change-log*} buffer, you can use the following keys diff --git a/etc/NEWS b/etc/NEWS index 4a193484591..ebf03b53e12 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2131,15 +2131,19 @@ relevant buffers before generating the contents of a VC Directory buffer (like the third-party package Magit does with its status buffer). +++ -*** New commands 'vc-root-diff-incoming' and 'vc-root-diff-outgoing'. -These commands report diffs of all the changes that would be pulled and -would be pushed, respectively. They are the diff analogues of the -existing commands 'vc-log-incoming' and 'vc-log-outgoing'. +*** New commands to report incoming and outgoing diffs. +'vc-root-diff-incoming' and 'vc-root-diff-outgoing' report diffs of all +the changes that would be pulled and would be pushed, respectively. +They are the diff analogues of the existing commands 'vc-log-incoming' +and 'vc-log-outgoing'. In particular, 'vc-root-diff-outgoing' is useful as a way to preview your push and ensure that all and only the changes you intended to include were committed and will be pushed. +'vc-fileset-diff-incoming' and 'vc-fileset-diff-outgoing' are similar +but limited to the current VC fileset. + +++ *** New user option 'vc-use-incoming-outgoing-prefixes'. If this is customized to non-nil, 'C-x v I' and 'C-x v O' become prefix diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index 7d46f9f0ee3..e3b2d207156 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -976,9 +976,11 @@ In the latter case, VC mode is deactivated for this buffer." (defvar-keymap vc-incoming-prefix-map "L" #'vc-log-incoming + "=" #'vc-fileset-diff-incoming "D" #'vc-root-diff-incoming) (defvar-keymap vc-outgoing-prefix-map "L" #'vc-log-outgoing + "=" #'vc-fileset-diff-outgoing "D" #'vc-root-diff-outgoing) (defcustom vc-use-incoming-outgoing-prefixes nil diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 73f4f5d6f1d..6f8985dc0c9 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2546,12 +2546,27 @@ See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." (interactive (list (vc--maybe-read-remote-location))) (vc--with-backend-in-rootdir "VC root-diff" - (let ((incoming (vc--incoming-revision backend - (or remote-location "")))) - (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) - (vc-call-backend backend 'mergebase incoming) - incoming - (called-interactively-p 'interactive))))) + (vc-fileset-diff-incoming remote-location `(,backend (,rootdir))))) + +;;;###autoload +(defun vc-fileset-diff-incoming (&optional remote-location fileset) + "Report changes to VC fileset that would be pulled from REMOTE-LOCATION. +When unspecified REMOTE-LOCATION is the place \\[vc-update] would pull from. +When called interactively with a prefix argument, prompt for REMOTE-LOCATION. +In some version control systems REMOTE-LOCATION can be a remote branch name. +When called from Lisp optional argument FILESET overrides the VC fileset. + +See `vc-use-incoming-outgoing-prefixes' regarding giving this command a +global binding." + (interactive (list (vc--maybe-read-remote-location) nil)) + (let* ((fileset (or fileset (vc-deduce-fileset t))) + (backend (car fileset)) + (incoming (vc--incoming-revision backend + (or remote-location "")))) + (vc-diff-internal vc-allow-async-diff fileset + (vc-call-backend backend 'mergebase incoming) + incoming + (called-interactively-p 'interactive)))) ;;;###autoload (defun vc-root-diff-outgoing (&optional remote-location) @@ -2560,6 +2575,20 @@ When unspecified REMOTE-LOCATION is the place \\[vc-push] would push to. When called interactively with a prefix argument, prompt for REMOTE-LOCATION. In some version control systems REMOTE-LOCATION can be a remote branch name. +See `vc-use-incoming-outgoing-prefixes' regarding giving this command a +global binding." + (interactive (list (vc--maybe-read-remote-location))) + (vc--with-backend-in-rootdir "VC root-diff" + (vc-fileset-diff-outgoing remote-location `(,backend (,rootdir))))) + +;;;###autoload +(defun vc-fileset-diff-outgoing (&optional remote-location fileset) + "Report changes to VC fileset that would be pushed to REMOTE-LOCATION. +When unspecified REMOTE-LOCATION is the place \\[vc-push] would push to. +When called interactively with a prefix argument, prompt for REMOTE-LOCATION. +In some version control systems REMOTE-LOCATION can be a remote branch name. +When called from Lisp optional argument FILESET overrides the VC fileset. + See `vc-use-incoming-outgoing-prefixes' regarding giving this command a global binding." ;; For this command, for distributed VCS, we want to ignore @@ -2568,36 +2597,37 @@ global binding." ;; changes and remote committed changes. ;; (Hence why we don't call `vc-buffer-sync-fileset'.) (interactive (list (vc--maybe-read-remote-location))) - (vc--with-backend-in-rootdir "VC root-diff" - (let ((incoming (vc--incoming-revision backend - (or remote-location "")))) - (vc-diff-internal vc-allow-async-diff (list backend (list rootdir)) - (vc-call-backend backend 'mergebase incoming) - ;; FIXME: In order to exclude uncommitted - ;; changes we need to pass the most recent - ;; revision as REV2. Calling `working-revision' - ;; like this works for all the backends we have - ;; in core that implement `mergebase' and so can - ;; be used with this command (Git and Hg). - ;; However, it is not clearly permitted by the - ;; current semantics of `working-revision' to - ;; call it on a directory. - ;; - ;; A possible alternative would be something - ;; like this which effectively falls back to - ;; including uncommitted changes in the case of - ;; an older VCS or where the backend rejects our - ;; attempt to call `working-revision' on a - ;; directory: - ;; (and (eq (vc-call-backend backend - ;; 'revision-granularity) - ;; 'repository) - ;; (ignore-errors - ;; (vc-call-backend backend 'working-revision - ;; rootdir))) - (vc-call-backend backend 'working-revision - rootdir) - (called-interactively-p 'interactive))))) + (let* ((fileset (or fileset (vc-deduce-fileset t))) + (backend (car fileset)) + (incoming (vc--incoming-revision backend + (or remote-location "")))) + (vc-diff-internal vc-allow-async-diff fileset + (vc-call-backend backend 'mergebase incoming) + ;; FIXME: In order to exclude uncommitted + ;; changes we need to pass the most recent + ;; revision as REV2. Calling `working-revision' + ;; like this works for all the backends we have + ;; in core that implement `mergebase' and so can + ;; be used with this command (Git and Hg). + ;; However, it is not clearly permitted by the + ;; current semantics of `working-revision' to + ;; call it on a directory. + ;; + ;; A possible alternative would be something + ;; like this which effectively falls back to + ;; including uncommitted changes in the case of + ;; an older VCS or where the backend rejects our + ;; attempt to call `working-revision' on a + ;; directory: + ;; (and (eq (vc-call-backend backend + ;; 'revision-granularity) + ;; 'repository) + ;; (ignore-errors + ;; (vc-call-backend backend 'working-revision + ;; (car fileset))) + (vc-call-backend backend 'working-revision + (car fileset)) + (called-interactively-p 'interactive)))) (declare-function ediff-load-version-control "ediff" (&optional silent)) (declare-function ediff-vc-internal "ediff-vers"