mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-05-10 15:25:04 -07:00
New VC commands for remote unintegrated changes
* lisp/vc/vc.el (vc--outgoing-base, vc--outgoing-base-mergebase): New FORCE-TOPIC parameter. (vc--maybe-read-outgoing-base): New NO-DOUBLE parameter. (vc-root-diff-remote-unintegrated, vc-diff-remote-unintegrated) (vc-log-remote-unintegrated, vc-root-log-remote-unintegrated): New commands (bug#80434). * lisp/vc/vc-dir.el (vc-dir-mode-map): * lisp/vc/vc-hooks.el (vc-prefix-map): Bind them. * doc/emacs/vc1-xtra.texi (Unintegrated Changes): * etc/NEWS: Document them.
This commit is contained in:
parent
ae40c3a438
commit
7d9dad4241
5 changed files with 181 additions and 13 deletions
|
|
@ -296,6 +296,7 @@ yet merged into the target branch.
|
|||
@node Unintegrated Changes
|
||||
@subsubsection Commands to see all unintegrated changes
|
||||
@cindex unintegrated changes
|
||||
@cindex remote unintegrated changes
|
||||
|
||||
@table @kbd
|
||||
@item C-x v T =
|
||||
|
|
@ -314,6 +315,26 @@ of this branch and its upstream counterpart
|
|||
@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-unintegrated}).
|
||||
|
||||
@item C-x v T R =
|
||||
Display diffs of remote changes to the VC fileset since the merge base
|
||||
of this topic branch and its upstream counterpart
|
||||
(@code{vc-diff-remote-unintegrated}).
|
||||
|
||||
@item C-x v T R D
|
||||
Display a diff of all remote changes since the merge base of this topic
|
||||
branch and its upstream counterpart
|
||||
(@code{vc-root-diff-remote-unintegrated}).
|
||||
|
||||
@item C-x v T R l
|
||||
Display log messages for remote changes to the VC fileset since the
|
||||
merge base of this topic branch and its upstream counterpart
|
||||
(@code{vc-log-remote-unintegrated}).
|
||||
|
||||
@item C-x v T R L
|
||||
Display log messages for all remote changes since the merge base of this
|
||||
topic branch and its upstream counterpart
|
||||
(@code{vc-root-log-remote-unintegrated}).
|
||||
@end table
|
||||
|
||||
For decentralized version control systems (@pxref{VCS Repositories}),
|
||||
|
|
@ -388,7 +409,24 @@ 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
|
||||
@findex vc-diff-remote-unintegrated
|
||||
@findex vc-root-diff-remote-unintegrated
|
||||
@findex vc-log-remote-unintegrated
|
||||
@findex vc-root-log-remote-unintegrated
|
||||
On topic branches, it is sometimes also useful to see the same
|
||||
information but for the remote repository's version of the topic branch.
|
||||
This is the outstanding work on the topic branch that has been pushed,
|
||||
but not yet merged. It is visible to your collaborators but is
|
||||
otherwise still unintegrated. We call such work @dfn{remote
|
||||
unintegrated changes}. There is a command corresponding to each of the
|
||||
four commands discussed so far but which operates on the remote
|
||||
repository's version of the current topic branch: @w{@kbd{C-x v R T =}}
|
||||
(@code{vc-diff-remote-unintegrated}), @w{@kbd{C-x v R T D}}
|
||||
(@code{vc-root-diff-remote-unintegrated}), @w{@kbd{C-x v R T l}}
|
||||
(@code{vc-log-remote-unintegrated}), and @w{@kbd{C-x v R T L}}
|
||||
(@code{vc-root-log-remote-unintegrated}).
|
||||
|
||||
All this functionality relies on Emacs correctly detecting whether the
|
||||
current branch is a trunk or a topic branch, and in the latter case,
|
||||
correctly determining the branch to which the topic branch will
|
||||
eventually be merged. If the autodetection doesn't produce the right
|
||||
|
|
|
|||
6
etc/NEWS
6
etc/NEWS
|
|
@ -3008,6 +3008,12 @@ 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 Directory buffers.
|
||||
|
||||
'C-x v T R =' ('vc-diff-remote-unintegrated'), 'C-x v T R D'
|
||||
('vc-root-diff-remote-unintegrated'), 'C-x v T R l'
|
||||
('vc-log-remote-unintegrated') and 'C-x v T R L'
|
||||
('vc-root-log-remote-unintegrated') are corresponding commands which
|
||||
report information about the remote versions of a topic branch.
|
||||
|
||||
+++
|
||||
*** New commands to report combined diffs of all local changes.
|
||||
'C-x v E =' ('vc-diff-outgoing-and-edited') and 'C-x v E D'
|
||||
|
|
|
|||
|
|
@ -412,6 +412,10 @@ an \\+`up-to-date' or \\+`ignored' file."
|
|||
(define-key map "TL" #'vc-root-log-unintegrated)
|
||||
(define-key map "T=" #'vc-diff-unintegrated)
|
||||
(define-key map "TD" #'vc-root-diff-unintegrated)
|
||||
(define-key map "TRl" #'vc-log-remote-unintegrated)
|
||||
(define-key map "TRL" #'vc-root-log-remote-unintegrated)
|
||||
(define-key map "TR=" #'vc-diff-remote-unintegrated)
|
||||
(define-key map "TRD" #'vc-root-diff-remote-unintegrated)
|
||||
(define-key map "EL" #'vc-root-log-outgoing)
|
||||
(define-key map "E=" #'vc-diff-outgoing-and-edited)
|
||||
(define-key map "ED" #'vc-root-diff-outgoing-and-edited)
|
||||
|
|
|
|||
|
|
@ -1040,6 +1040,10 @@ In the latter case, VC mode is deactivated for this buffer."
|
|||
"T L" #'vc-root-log-unintegrated
|
||||
"T =" #'vc-diff-unintegrated
|
||||
"T D" #'vc-root-diff-unintegrated
|
||||
"T R l" #'vc-log-remote-unintegrated
|
||||
"T R L" #'vc-root-log-remote-unintegrated
|
||||
"T R =" #'vc-diff-remote-unintegrated
|
||||
"T R D" #'vc-root-diff-remote-unintegrated
|
||||
;; There are no -log-outgoing-and-edited commands because by
|
||||
;; definition these are the same as -log-outgoing.
|
||||
;; Additionally bind the -log-outgoing commands under C-x v E l/L as
|
||||
|
|
|
|||
140
lisp/vc/vc.el
140
lisp/vc/vc.el
|
|
@ -3357,27 +3357,30 @@ BACKEND is the VC backend."
|
|||
;; branch has no name.
|
||||
(vc-call-backend backend 'trunk-or-topic-p branch))))
|
||||
|
||||
(defun vc--outgoing-base (backend)
|
||||
(defun vc--outgoing-base (backend force-topic)
|
||||
"Return an outgoing base for the current branch under VC backend BACKEND.
|
||||
The outgoing base is the upstream location for which unintegrated
|
||||
changes on this branch are destined once they are integrated.
|
||||
|
||||
There are two stages to determining the outgoing base.
|
||||
First we decide whether we think this is a shorter-lived or a
|
||||
longer-lived (\"trunk\") branch by calling `vc-trunk-or-topic-p'.
|
||||
If that function returns nil, assume this is a shorter-lived branch.
|
||||
This is based on how it's commands primarily intended for working with
|
||||
shorter-lived branches that call this function.
|
||||
longer-lived (\"trunk\") branch. If FORCE-TOPIC is non-nil, assume this
|
||||
is a shorter-lived branch. Otherwise call `vc-trunk-or-topic-p'.
|
||||
If that function returns nil, also assume this is a shorter-lived
|
||||
branch. This is based on how it's commands primarily intended for
|
||||
working with shorter-lived branches that call this function.
|
||||
Second, if we have determined that this is a trunk, return nil, meaning
|
||||
that the outgoing base is the place to which `vc-push' would push.
|
||||
Otherwise, we have determined that this is a shorter-lived branch, and
|
||||
we return the value of calling BACKEND's `topic-outgoing-base' VC API
|
||||
function."
|
||||
;; For further discussion see bug#80006.
|
||||
(and (memq (vc-trunk-or-topic-p nil backend) '(topic nil))
|
||||
(and (or force-topic
|
||||
(memq (vc-trunk-or-topic-p nil backend) '(topic nil)))
|
||||
(vc-call-backend backend 'topic-outgoing-base)))
|
||||
|
||||
(defun vc--outgoing-base-mergebase (backend &optional upstream-location refresh)
|
||||
(defun vc--outgoing-base-mergebase
|
||||
(backend &optional upstream-location refresh force-topic)
|
||||
"Return, under VC backend BACKEND, the merge base with UPSTREAM-LOCATION.
|
||||
Normally UPSTREAM-LOCATION, if non-nil, is a string.
|
||||
If UPSTREAM-LOCATION is nil, it means to call `vc--outgoing-base' and
|
||||
|
|
@ -3387,12 +3390,15 @@ If UPSTREAM-LOCATION is the special value t, it means to use the place
|
|||
to which `vc-push' would push as UPSTREAM-LOCATION, unconditionally.
|
||||
(This is passed when the user invokes an outgoing base command with a
|
||||
\\`C-u C-u' prefix argument; see `vc--maybe-read-outgoing-base'.)
|
||||
REFRESH is passed on to `vc--incoming-revision'."
|
||||
REFRESH is passed on to `vc--incoming-revision'.
|
||||
FORCE-TOPIC is passed on to `vc--outgoing-base'."
|
||||
(vc-call-backend backend 'mergebase
|
||||
(vc--incoming-revision backend
|
||||
(pcase upstream-location
|
||||
('t nil)
|
||||
('nil (vc--outgoing-base backend))
|
||||
('nil
|
||||
(vc--outgoing-base backend
|
||||
force-topic))
|
||||
(_ upstream-location))
|
||||
refresh)))
|
||||
|
||||
|
|
@ -3552,6 +3558,115 @@ topic branch."
|
|||
(vc--with-backend-in-rootdir "VC revision log"
|
||||
(vc-log-unintegrated upstream-location `(,backend (,rootdir)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-root-diff-remote-unintegrated (&optional upstream-location)
|
||||
"Report diff of remote changes since merge base with UPSTREAM-LOCATION.
|
||||
Remote changes are changes in the incoming revision (instead of the
|
||||
working revision), and the merge base with UPSTREAM-LOCATION is the
|
||||
common ancestor of the incoming revision and UPSTREAM-LOCATION.
|
||||
This command only makes sense for decentralized VCS, because otherwise
|
||||
there is no distinction between locally committed changes and upstream
|
||||
changes.
|
||||
|
||||
When unspecified, UPSTREAM-LOCATION is the outgoing base when this
|
||||
branch is considered as a topic branch (whether or not it actually is).
|
||||
This command with unspecified UPSTREAM-LOCATION only makes sense on
|
||||
topic branches. See `vc-trunk-or-topic-p'.
|
||||
|
||||
When called interactively with a prefix argument, prompt for
|
||||
UPSTREAM-LOCATION, which should be a remote branch name."
|
||||
(interactive (list (vc--maybe-read-outgoing-base nil 'no-double)))
|
||||
(vc--with-backend-in-rootdir "VC root-diff"
|
||||
(vc-diff-remote-unintegrated upstream-location
|
||||
`(,backend (,rootdir)))))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-diff-remote-unintegrated (&optional upstream-location fileset)
|
||||
"Show remote fileset changes since merge base with UPSTREAM-LOCATION.
|
||||
Remote changes are changes in the incoming revision (instead of the
|
||||
working revision), and the merge base with UPSTREAM-LOCATION is the
|
||||
common ancestor of the incoming revision and UPSTREAM-LOCATION.
|
||||
This command only makes sense for decentralized VCS, because otherwise
|
||||
there is no distinction between locally committed changes and remote
|
||||
changes.
|
||||
|
||||
When unspecified, UPSTREAM-LOCATION is the outgoing base when this
|
||||
branch is considered as a topic branch (whether or not it actually is).
|
||||
This command with unspecified UPSTREAM-LOCATION only makes sense on
|
||||
topic branches. See `vc-trunk-or-topic-p'.
|
||||
|
||||
When called interactively with a prefix argument, prompt for
|
||||
UPSTREAM-LOCATION, which should be a remote branch name.
|
||||
|
||||
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)
|
||||
'no-double)
|
||||
fileset)))
|
||||
(let* ((fileset (or fileset (vc-deduce-fileset t)))
|
||||
(backend (car fileset)))
|
||||
(vc-diff-internal vc-allow-async-diff fileset
|
||||
(vc--outgoing-base-mergebase backend
|
||||
upstream-location
|
||||
'refresh 'force-topic)
|
||||
;; REFRESH nil here because we just refreshed.
|
||||
(vc--incoming-revision backend)
|
||||
(called-interactively-p 'interactive))))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-log-remote-unintegrated (&optional upstream-location fileset)
|
||||
"Show remote log for VC fileset since merge base with UPSTREAM-LOCATION.
|
||||
Remote changes are changes in the incoming revision (instead of the
|
||||
working revision), and the merge base with UPSTREAM-LOCATION is the
|
||||
common ancestor of the incoming revision and UPSTREAM-LOCATION.
|
||||
This command only makes sense for decentralized VCS, because otherwise
|
||||
there is no distinction between locally committed changes and remote
|
||||
changes.
|
||||
|
||||
When unspecified, UPSTREAM-LOCATION is the outgoing base when this
|
||||
branch is considered as a topic branch (whether or not it actually is).
|
||||
This command with unspecified UPSTREAM-LOCATION only makes sense on
|
||||
topic branches. See `vc-trunk-or-topic-p'.
|
||||
|
||||
When called interactively with a prefix argument, prompt for
|
||||
UPSTREAM-LOCATION, which should be a remote branch name.
|
||||
|
||||
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)
|
||||
(vc--incoming-revision backend nil 'refresh)
|
||||
'is-start-revision
|
||||
;; REFRESH nil here because we just refreshed.
|
||||
(vc--outgoing-base-mergebase backend
|
||||
upstream-location
|
||||
nil 'force-topic))))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-root-log-remote-unintegrated (&optional upstream-location)
|
||||
"Show log of remote revisions since merge base with UPSTREAM-LOCATION.
|
||||
Remote changes are changes in the incoming revision (instead of the
|
||||
working revision), and the merge base with UPSTREAM-LOCATION is the
|
||||
common ancestor of the incoming revision and UPSTREAM-LOCATION.
|
||||
This command only makes sense for decentralized VCS, because otherwise
|
||||
there is no distinction between locally committed changes and remote
|
||||
changes.
|
||||
|
||||
When unspecified, UPSTREAM-LOCATION is the outgoing base when this
|
||||
branch is considered as a topic branch (whether or not it actually is).
|
||||
This command with unspecified UPSTREAM-LOCATION only makes sense on
|
||||
topic branches. See `vc-trunk-or-topic-p'.
|
||||
|
||||
When called interactively with a prefix argument, prompt for
|
||||
UPSTREAM-LOCATION, which should be a remote branch name."
|
||||
(interactive (list (vc--maybe-read-outgoing-base nil 'no-double)))
|
||||
(vc--with-backend-in-rootdir "VC revision log"
|
||||
(vc-log-remote-unintegrated 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))
|
||||
|
|
@ -4481,14 +4596,15 @@ starting at that revision. Tags and remote references also work."
|
|||
nil 'vc-remote-location-history)))
|
||||
(and (not (string-empty-p res)) res))))
|
||||
|
||||
(defun vc--maybe-read-outgoing-base (&optional backend)
|
||||
(defun vc--maybe-read-outgoing-base (&optional backend no-double)
|
||||
"Return upstream location for interactive uses of outgoing base commands.
|
||||
If there is no prefix argument, return nil.
|
||||
If the current prefix argument is \\`C-u C-u', return t.
|
||||
If the current prefix argument is \\`C-u C-u' and NO-DOUBLE is nil,
|
||||
return t.
|
||||
Otherwise prompt for an upstream location.
|
||||
BACKEND is the VC backend."
|
||||
(cond
|
||||
((equal current-prefix-arg '(16)) t)
|
||||
((and (not no-double) (equal current-prefix-arg '(16))) t)
|
||||
(current-prefix-arg
|
||||
(let* ((outgoing-base (vc-call-backend (or backend
|
||||
(vc-deduce-backend))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue