1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-02-08 00:33:13 -08:00

VC: New commands for incoming and outgoing fileset diffs

* lisp/vc/vc.el (vc-fileset-diff-incoming)
(vc-fileset-diff-outgoing): New commands.
(vc-root-diff-incoming): Refactor to call
vc-fileset-diff-incoming.
(vc-root-diff-outgoing): Refactor to call
vc-fileset-diff-outgoing.
* lisp/vc/vc-hooks.el (vc-incoming-prefix-map)
(vc-outgoing-prefix-map): Bind the new commands.
* doc/emacs/maintaining.texi (VC Change Log):
* etc/NEWS: Document the new commands.
This commit is contained in:
Sean Whitton 2025-08-17 11:36:13 +01:00
parent 70b5ad0192
commit da3973b657
4 changed files with 103 additions and 44 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"