New C-x v T l and C-x v T L commands

* lisp/vc/vc.el (vc-log-outgoing-base)
(vc-root-log-outgoing-base): New commands.
* lisp/vc/vc-dir.el (vc-dir-mode-map):
* lisp/vc/vc-hooks.el (vc-prefix-map): Bind them.
* doc/emacs/vc1-xtra.texi (Outstanding Changes):
* etc/NEWS: Document them.
This commit is contained in:
Sean Whitton 2026-01-29 17:01:32 +00:00
parent 60b9435ad7
commit 12e53dfafe
5 changed files with 99 additions and 15 deletions

View file

@ -303,17 +303,26 @@ Display diffs of changes to the VC fileset since the merge base of this
branch and its upstream counterpart (@code{vc-diff-outgoing-base}).
@item C-x v T D
Display all changes since the merge base of this branch and its upstream
counterpart (@code{vc-root-diff-outgoing-base}).
Display a diff of all changes since the merge base of this branch and
its upstream counterpart (@code{vc-root-diff-outgoing-base}).
@item C-x v T l
Display log messages for changes to the VC fileset since the merge base
of this branch and its upstream counterpart
(@code{vc-log-outgoing-base}).
@item C-x v T L
Display log messages for all changes since the merge base of this branch
and its upstream counterpart (@code{vc-root-log-outgoing-base}).
@end table
For decentralized version control systems (@pxref{VCS Repositories}),
these commands provide specialized versions of @kbd{C-x v M D} (see
@pxref{Merge Bases}) which also take into account the state of upstream
repositories. These commands are useful both when working on a single
branch and when developing features on a separate branch
(@pxref{Branches}). These two cases are conceptually distinct, and so
we will introduce them separately.
these commands provide specialized versions of @kbd{C-x v M L} and
@w{@kbd{C-x v M D}} (see @pxref{Merge Bases}) which also take into
account the state of upstream repositories. These commands are useful
both when working on a single branch and when developing features on a
separate branch (@pxref{Branches}). These two cases are conceptually
distinct, and so we will introduce them separately.
First, consider working on a single branch. @dfn{Outstanding changes}
are those which you haven't yet pushed upstream. This includes both
@ -340,6 +349,16 @@ include uncommitted changes in the reported diffs. Like those other
commands, you can use a prefix argument to specify a particular upstream
location.}
@kindex C-x v T l
@findex vc-log-outgoing-base
@kindex C-x v T L
@findex vc-root-log-outgoing-base
Type @kbd{C-x v T L} (@code{vc-root-log-outgoing-base}) to display a
summary of the same changes in the form of a revision log; this does not
include uncommitted changes. You can use @kbd{C-x v T l}
(@code{vc-log-outgoing-base}) instead to limit the display of changes to
the current VC fileset.
Second, consider developing a feature on a separate branch. Call this
the @dfn{topic branch},@footnote{What we mean by a topic branch is any
shorter-lived branch used for work which will later be merged into a
@ -365,7 +384,9 @@ the trunk to which the current branch will be merged. This summary is
in the form of a diff of what committing and pushing all the changes,
@emph{and} subsequently merging the topic branch, would do to the trunk.
As above, you can use @kbd{C-x v T =} instead to limit the display of
changes to the current VC fileset.
changes to the current VC fileset. @kbd{C-x v T L} and @kbd{C-x v T l}
show the corresponding revision logs, excluding uncommitted changes as
above.
This functionality relies on Emacs correctly detecting whether the
current branch is a trunk or a topic branch, and in the latter case,
@ -379,8 +400,8 @@ The variables @code{vc-trunk-branch-regexps} and
@code{vc-topic-branch-regexps} contain lists of regular expressions
matching the names of branches that should always be considered trunk
and topic branches, respectively. You can also specify prefix arguments
to @kbd{C-x v T D} and @kbd{C-x v T =}. Here is a summary of how to use
these controls:
to @kbd{C-x v T @dots{}}. Here is a summary of how to use these
controls:
@enumerate
@item

View file

@ -2745,13 +2745,15 @@ include were committed and will be pushed.
current VC fileset.
+++
*** New commands to report diffs of outstanding changes.
*** New commands to report information about outstanding changes.
'C-x v T =' ('vc-diff-outgoing-base') and 'C-x v T D'
('vc-root-diff-outgoing-base') report diffs of changes since the merge
base with the remote branch, including uncommitted changes.
They are useful to view all outstanding (unmerged, unpushed) changes on
the current branch.
They are also available as 'T =' and 'T D' in VC-Dir buffers.
'C-x v T l' ('vc-log-outgoing-base') and 'C-x v T L'
('vc-root-log-outgoing-base') show the corresponding revision logs.
These are useful to view all outstanding (unmerged, unpushed) changes on
the current branch. They are also available as 'T =', 'T D', 'T l' and
'T L' in VC-Dir buffers.
+++
*** New user option 'vc-use-incoming-outgoing-prefixes'.

View file

@ -397,6 +397,8 @@ That is, refreshing the VC-Dir buffer also hides `up-to-date' and
(define-key map (kbd "M-s a M-C-s") #'vc-dir-isearch-regexp)
(define-key map "G" #'vc-dir-ignore)
(define-key map "@" #'vc-revert)
(define-key map "Tl" #'vc-log-outgoing-base)
(define-key map "TL" #'vc-root-log-outgoing-base)
(define-key map "T=" #'vc-diff-outgoing-base)
(define-key map "TD" #'vc-root-diff-outgoing-base)

View file

@ -1018,6 +1018,8 @@ In the latter case, VC mode is deactivated for this buffer."
"O" #'vc-root-log-outgoing
"M L" #'vc-log-mergebase
"M D" #'vc-diff-mergebase
"T l" #'vc-log-outgoing-base
"T L" #'vc-root-log-outgoing-base
"T =" #'vc-diff-outgoing-base
"T D" #'vc-root-diff-outgoing-base
"m" #'vc-merge

View file

@ -3403,6 +3403,63 @@ When called from Lisp, optional argument FILESET overrides the fileset."
nil
(called-interactively-p 'interactive))))
;;;###autoload
(defun vc-log-outgoing-base (&optional upstream-location fileset)
"Show log for the VC fileset since the merge base with UPSTREAM-LOCATION.
The merge base with UPSTREAM-LOCATION means the common ancestor of the
working revision and UPSTREAM-LOCATION.
When unspecified, UPSTREAM-LOCATION is the outgoing base.
For a trunk branch this is always the place \\[vc-push] would push to.
For a topic branch, query the backend for an appropriate outgoing base.
See `vc-trunk-branch-regexps' and `vc-topic-branch-regexps' regarding
the difference between trunk and topic branches.
When called interactively with a prefix argument, prompt for
UPSTREAM-LOCATION. In some version control systems, UPSTREAM-LOCATION
can be a remote branch name.
When called interactively with a \\[universal-argument] \\[universal-argument] \
prefix argument, always
use the place to which \\[vc-push] would push to as the outgoing base,
i.e., treat this branch as a trunk branch even if Emacs thinks it is a
topic branch.
When called from Lisp, optional argument FILESET overrides the fileset."
(interactive (let ((fileset (vc-deduce-fileset t)))
(list (vc--maybe-read-outgoing-base (car fileset))
fileset)))
(let* ((fileset (or fileset (vc-deduce-fileset t)))
(backend (car fileset)))
(vc-print-log-internal backend (cadr fileset) nil nil
(vc--outgoing-base-mergebase backend
upstream-location))))
;;;###autoload
(defun vc-root-log-outgoing-base (&optional upstream-location)
"Show log of revisions since the merge base with UPSTREAM-LOCATION.
The merge base with UPSTREAM-LOCATION means the common ancestor of the
working revision and UPSTREAM-LOCATION.
When unspecified, UPSTREAM-LOCATION is the outgoing base.
For a trunk branch this is always the place \\[vc-push] would push to.
For a topic branch, query the backend for an appropriate outgoing base.
See `vc-trunk-branch-regexps' and `vc-topic-branch-regexps' regarding
the difference between trunk and topic branches.
When called interactively with a prefix argument, prompt for
UPSTREAM-LOCATION. In some version control systems, UPSTREAM-LOCATION
can be a remote branch name.
When called interactively with a \\[universal-argument] \\[universal-argument] \
prefix argument, always
use the place to which \\[vc-push] would push to as the outgoing base,
i.e., treat this branch as a trunk branch even if Emacs thinks it is a
topic branch."
(interactive (list (vc--maybe-read-outgoing-base)))
(vc--with-backend-in-rootdir "VC revision log"
(vc-log-outgoing-base upstream-location `(,backend (,rootdir)))))
(declare-function ediff-load-version-control "ediff" (&optional silent))
(declare-function ediff-vc-internal "ediff-vers"
(rev1 rev2 &optional startup-hooks))