mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
VC revert commands: Facilities to entirely delete revisions
* lisp/vc/vc.el (vc-revision-revert, vc-revision-cherry-pick): Rename to ... (vc-revert-or-delete-revision, vc-cherry-pick): ... these (bug#79408). All uses changed. * lisp/vc/log-view.el (log-view-revision-revert) (log-view-revision-cherry-pick): Rename to ... (log-view-revert-or-delete-revisions, log-view-cherry-pick): ... these. All uses changed. * lisp/vc/log-view.el (log-view-revert-or-delete-revisions): * lisp/vc/vc.el (vc-revert-or-delete-revision): New INTERACTIVE and DELETE parameters, and prefix argument. Offer to entirely delete REV in certain circumstances (bug#79408). * lisp/vc/log-view.el (log-view--pick-or-revert): * lisp/vc/vc.el (vc--pick-or-revert): New INTERACTIVE and DELETE parameters. All uses changes. * lisp/vc/log-view.el (log-view-revert-revisions) (log-view-delete-revisions): * lisp/vc/vc.el (vc-revert-revision, vc-delete-revision): New commands (bug#79408). * doc/emacs/maintaining.texi (VC Change Log, VC Undo) (Copying Between Branches): * etc/NEWS: Document the changes.
This commit is contained in:
parent
5dfcba699e
commit
2e8cc345d5
5 changed files with 343 additions and 94 deletions
|
|
@ -1268,11 +1268,11 @@ Unmark all marked entries (@code{log-view-unmark-all-entries}).
|
|||
@item C
|
||||
Copy changes to a currently checked out branch; either the changes from
|
||||
the revision at point, or the changes from all marked revisions
|
||||
(@code{log-view-revision-cherry-pick}).
|
||||
(@code{log-view-cherry-pick}).
|
||||
|
||||
@item R
|
||||
Undo the effects of old revisions; either the revision at point, or all
|
||||
marked revisions (@code{log-view-revision-revert}).
|
||||
marked revisions (@code{log-view-revert-or-delete-revisions}).
|
||||
@end table
|
||||
|
||||
@vindex vc-log-show-limit
|
||||
|
|
@ -1317,8 +1317,14 @@ also prompt for a specific VCS shell command to run for this purpose.
|
|||
Revert the work file(s) in the current VC fileset to the last revision
|
||||
(@code{vc-revert}).
|
||||
|
||||
@item M-x vc-revision-revert
|
||||
@item M-x vc-revert-or-delete-revision
|
||||
Undo the effects of an older commit.
|
||||
|
||||
@item M-x vc-revert-revision
|
||||
Make a new commit which undoes the changes made by an older one.
|
||||
|
||||
@item M-x vc-delete-revision
|
||||
Delete an unpushed commit from the revision history.
|
||||
@end table
|
||||
|
||||
@kindex C-x v u
|
||||
|
|
@ -1342,20 +1348,37 @@ unlocked; you must lock again to resume editing. You can also use
|
|||
@kbd{C-x v u} to unlock a file if you lock it and then decide not to
|
||||
change it.
|
||||
|
||||
@findex vc-revision-revert
|
||||
@findex vc-revert-or-delete-revision
|
||||
@cindex reverting commits
|
||||
To discard changes that have already been committed, by yourself or
|
||||
someone else, you can use @w{@kbd{M-x vc-revision-revert}}. This is
|
||||
called @dfn{reverting} a commit. The command prompts for a revision to
|
||||
revert, and then the VC backend reverts it. Most backends implement
|
||||
this by making a new commit which undoes the changes made by the
|
||||
revision.
|
||||
someone else, you can use @w{@kbd{M-x vc-revert-or-delete-revision}}.
|
||||
This is called @dfn{reverting} a commit. The command prompts for a
|
||||
revision to revert, and then the VC backend reverts it.
|
||||
|
||||
An alternative way to access this functionality is to the
|
||||
@code{log-view-revision-revert} command, bound to @kbd{R} in Log View
|
||||
mode buffers (@pxref{VC Change Log}). Compared to using @w{@kbd{M-x
|
||||
vc-revision revert}} directly, this can make it easier to be sure you
|
||||
are reverting the revision you intend.
|
||||
Most backends implement this by making a new commit which undoes the
|
||||
changes made by the revision. For a distributed VCS, if the commit is
|
||||
one that you made and have not yet pushed, Emacs will offer to delete it
|
||||
entirely, instead. With a prefix argument, this command will only try
|
||||
to entirely delete the revision, failing if it has already been pushed.
|
||||
|
||||
An alternative way to access this functionality is the
|
||||
@code{log-view-revert-or-delete-revisions} command, bound to @kbd{R} in
|
||||
Log View mode buffers (@pxref{VC Change Log}). Compared to using
|
||||
@w{@kbd{M-x vc-revision revert}} directly, this can make it easier to be
|
||||
sure you are reverting the revision you intend.
|
||||
|
||||
@findex vc-revert-revision
|
||||
@findex vc-delete-revision
|
||||
More specific, specialized commands are @w{@kbd{M-x
|
||||
vc-revert-revision}} and @w{@kbd{M-x vc-delete-revision}}. The first of
|
||||
these prompts for a revision and then always makes a new commit which
|
||||
undoes the changes made by that revision, regardless of the VCS in use
|
||||
and whether or not the revision is pushed. The second command prompts
|
||||
for a revision and then always deletes it, though it will stop if the
|
||||
commit has been pushed. Usually @code{vc-revert-or-delete-revision} is
|
||||
sufficient, but @code{vc-revert-revision} and @code{vc-delete-revision}
|
||||
can sometimes be useful for constructing particular version control
|
||||
histories.
|
||||
|
||||
@node VC Ignore
|
||||
@subsection Ignore Version Control Files
|
||||
|
|
@ -1889,7 +1912,7 @@ different revision with @kbd{C-u C-x v v}.
|
|||
@subsubsection Copying Changes Made By Revisions Between Branches
|
||||
|
||||
@table @kbd
|
||||
@item M-x vc-revision-cherry-pick
|
||||
@item M-x vc-cherry-pick
|
||||
Copy a single revision to branch checked out in this working tree.
|
||||
@end table
|
||||
|
||||
|
|
@ -1910,25 +1933,25 @@ can then cherry-pick that revision onto the feature-frozen branch in
|
|||
order to fix the bug there, too. This is called @dfn{backporting} the
|
||||
revision, or backporting the fix.
|
||||
|
||||
@findex vc-revision-cherry-pick
|
||||
You can use the command @kbd{M-x vc-revision-cherry-pick} to
|
||||
cherry-pick revisions. It prompts for a revision to cherry-pick. It
|
||||
then pops up a buffer for you to edit the log message for the new
|
||||
revision. Normally the VC backend generates a log message including a
|
||||
reference to the revision you want to copy, so that the copy can be
|
||||
traced. If you wish, you can delete this reference before typing
|
||||
@kbd{C-c C-c} to conclude the cherry-pick.
|
||||
@findex vc-cherry-pick
|
||||
You can use the command @kbd{M-x vc-cherry-pick} to cherry-pick
|
||||
revisions. It prompts for a revision to cherry-pick. It then pops up a
|
||||
buffer for you to edit the log message for the new revision. Normally
|
||||
the VC backend generates a log message including a reference to the
|
||||
revision you want to copy, so that the copy can be traced. If you wish,
|
||||
you can delete this reference before typing @kbd{C-c C-c} to conclude
|
||||
the cherry-pick.
|
||||
|
||||
Alternatively you can invoke the command with a prefix argument,
|
||||
i.e. @w{@kbd{C-u M-x vc-revision-cherry-pick}}. In this case the log
|
||||
message from the source revision is used unmodified, and the cherry-pick
|
||||
happens immediately, without popping up a buffer for log message edits.
|
||||
i.e. @w{@kbd{C-u M-x vc-cherry-pick}}. In this case the log message
|
||||
from the source revision is used unmodified, and the cherry-pick happens
|
||||
immediately, without popping up a buffer for log message edits.
|
||||
|
||||
An alternative way to access this functionality is the
|
||||
@code{log-view-revision-cherry-pick} command, bound to @kbd{C} in Log
|
||||
View mode buffers (@pxref{VC Change Log}). Compared to using
|
||||
@w{@kbd{M-x vc-revision-cherry-pick}} directly, this can make it easier
|
||||
to be sure you are cherry-picking the revision you intend.
|
||||
@code{log-view-cherry-pick} command, bound to @kbd{C} in Log View mode
|
||||
buffers (@pxref{VC Change Log}). Compared to using @w{@kbd{M-x
|
||||
vc-cherry-pick}} directly, this can make it easier to be sure you are
|
||||
cherry-picking the revision you intend.
|
||||
|
||||
@ifnottex
|
||||
@include vc1-xtra.texi
|
||||
|
|
|
|||
9
etc/NEWS
9
etc/NEWS
|
|
@ -2358,11 +2358,12 @@ the contents of those files.
|
|||
|
||||
+++
|
||||
*** New commands to cherry-pick and revert revisions.
|
||||
The commands 'vc-revision-cherry-pick' and 'vc-revision-revert' let you
|
||||
copy revisions between branches, and revert revisions.
|
||||
The commands 'vc-cherry-pick', 'vc-revert-or-delete-revision',
|
||||
'vc-revert-revision' and 'vc-delete-revision' let you copy revisions
|
||||
between branches, revert and delete revisions.
|
||||
From Log View buffers, you can use 'C' to cherry-pick the revision at
|
||||
point or all marked revisions, and 'R' to revert the revision at point
|
||||
or all marked revisions.
|
||||
point or all marked revisions, and 'R' to undo the revision at point or
|
||||
all marked revisions.
|
||||
|
||||
*** New command 'log-edit-done-strip-cvs-lines'.
|
||||
This command strips all lines beginning with "CVS:" from the buffer.
|
||||
|
|
|
|||
|
|
@ -141,8 +141,8 @@
|
|||
"w" #'log-view-copy-revision-as-kill
|
||||
"TAB" #'log-view-msg-next
|
||||
"<backtab>" #'log-view-msg-prev
|
||||
"C" #'log-view-revision-cherry-pick
|
||||
"R" #'log-view-revision-revert)
|
||||
"C" #'log-view-cherry-pick
|
||||
"R" #'log-view-revert-or-delete-revisions)
|
||||
|
||||
(easy-menu-define log-view-mode-menu log-view-mode-map
|
||||
"Log-View Display Menu."
|
||||
|
|
@ -165,9 +165,9 @@
|
|||
["Toggle Details at Point" log-view-toggle-entry-display
|
||||
:active log-view-expanded-log-entry-function]
|
||||
"-----"
|
||||
["Cherry-Pick Revision(s)" log-view-revision-cherry-pick
|
||||
["Cherry-Pick Revision(s)" log-view-cherry-pick
|
||||
:help "Copy changes from revision(s) to a branch"]
|
||||
["Revert Revision(s)" log-view-revision-revert
|
||||
["Revert Revision(s)" log-view-revert-or-delete-revisions
|
||||
:help "Undo the effects of old revision(s)"]
|
||||
"-----"
|
||||
["Next Log Entry" log-view-msg-next
|
||||
|
|
@ -703,7 +703,8 @@ If called interactively, annotate the version at point."
|
|||
(defvar vc-log-short-style)
|
||||
(declare-function vc-print-log-internal "vc")
|
||||
|
||||
(defun log-view--pick-or-revert (directory no-comment reverse)
|
||||
(defun log-view--pick-or-revert
|
||||
(directory no-comment reverse interactive delete)
|
||||
"Copy changes from revision at point or all marked revisions.
|
||||
DIRECTORY is the destination, the root of the target working tree.
|
||||
NO-COMMENT non-nil means use the log messages of the revisions
|
||||
|
|
@ -711,12 +712,15 @@ unmodified, instead of using the backend's default cherry-pick comment
|
|||
for that revision.
|
||||
NO-COMMENT non-nil with zero or one revisions marked also means don't
|
||||
prompt to edit the log message.
|
||||
REVERSE non-nil means to make commit(s) undoing the effects of the
|
||||
revisions, instead."
|
||||
REVERSE non-nil means to undo the effects of the revisions, instead.
|
||||
INTERACTIVE and DELETE are passed on to `vc--pick-or-revert', except
|
||||
additionally if INTERACTIVE is non-nil and `vc--pick-or-revert' returns
|
||||
`deleted', pass `no-confirm' to subsequent calls to that function."
|
||||
(let ((default-directory directory)
|
||||
(marked (log-view-get-marked)))
|
||||
(marked (log-view-get-marked))
|
||||
(buf (current-buffer)))
|
||||
(if (length> marked 1)
|
||||
(progn
|
||||
(let ((deleted 0))
|
||||
(save-excursion
|
||||
(dolist (rev (if reverse (reverse marked) marked))
|
||||
;; Unmark each revision *before* copying it.
|
||||
|
|
@ -724,38 +728,48 @@ revisions, instead."
|
|||
;; fails, after resolving that conflict and committing the
|
||||
;; cherry-pick, the right revisions will be marked to
|
||||
;; resume the original multiple cherry-pick operation.
|
||||
;; FIXME: This doesn't work so long as the backend
|
||||
;; functions just give up completely if there is a
|
||||
;; conflict (which behavior is also a FIXME). Then in
|
||||
;; fact the user has to mark the revision again.
|
||||
(log-view-goto-rev rev)
|
||||
(log-view-unmark-entry 1)
|
||||
(vc--pick-or-revert rev
|
||||
reverse
|
||||
(if no-comment
|
||||
(vc-call-backend log-view-vc-backend
|
||||
'get-change-comment
|
||||
nil rev)
|
||||
t)
|
||||
nil
|
||||
log-view-vc-backend)))
|
||||
(when (vc-find-backend-function log-view-vc-backend
|
||||
'modify-change-comment)
|
||||
(let (vc-log-short-style)
|
||||
(vc-print-log-internal log-view-vc-backend
|
||||
(list default-directory)
|
||||
nil nil (length marked)))
|
||||
(setq-local vc-log-short-style nil ; For \\`g'.
|
||||
vc-parent-buffer-name nil)
|
||||
(message (substitute-command-keys "Use \
|
||||
\\[log-view-modify-change-comment] to modify any of these messages"))))
|
||||
(cl-case
|
||||
(vc--pick-or-revert rev reverse interactive delete
|
||||
(if no-comment
|
||||
(vc-call-backend log-view-vc-backend
|
||||
'get-change-comment
|
||||
nil rev)
|
||||
t)
|
||||
nil
|
||||
log-view-vc-backend)
|
||||
(deleted (incf deleted)
|
||||
(when interactive
|
||||
(setq interactive 'no-confirm))))))
|
||||
(let ((new-commits (- (length marked) deleted)))
|
||||
(when (and (plusp new-commits)
|
||||
(vc-find-backend-function log-view-vc-backend
|
||||
'modify-change-comment))
|
||||
(let (vc-log-short-style)
|
||||
(vc-print-log-internal log-view-vc-backend
|
||||
(list default-directory)
|
||||
nil nil new-commits))
|
||||
(setq-local vc-log-short-style nil ; For \\`g'.
|
||||
vc-parent-buffer-name nil)
|
||||
(message (substitute-command-keys "Use \
|
||||
\\[log-view-modify-change-comment] to modify any of these messages")))))
|
||||
(let ((rev (or (car marked) (log-view-current-tag))))
|
||||
(vc--pick-or-revert rev
|
||||
reverse
|
||||
(vc--pick-or-revert rev reverse interactive delete
|
||||
(and no-comment
|
||||
(vc-call-backend log-view-vc-backend
|
||||
'get-change-comment
|
||||
nil rev))
|
||||
nil
|
||||
log-view-vc-backend)))))
|
||||
log-view-vc-backend)))
|
||||
(when (eq (current-buffer) buf)
|
||||
(revert-buffer))))
|
||||
|
||||
(defun log-view-revision-cherry-pick (directory &optional no-comment)
|
||||
(defun log-view-cherry-pick (directory &optional no-comment)
|
||||
"Copy changes from revision at point to current branch.
|
||||
If there are marked revisions, use those instead of the revision at point.
|
||||
|
||||
|
|
@ -774,31 +788,90 @@ traced. With optional argument NO-COMMENT non-nil (interactively, with
|
|||
a prefix argument), use the log messages from the source revisions
|
||||
unmodified.
|
||||
|
||||
See also `vc-revision-cherry-pick'."
|
||||
See also `vc-cherry-pick'."
|
||||
(interactive
|
||||
(list (vc--prompt-other-working-tree log-view-vc-backend
|
||||
"Cherry-pick to working tree"
|
||||
'allow-empty)
|
||||
current-prefix-arg))
|
||||
(log-view--pick-or-revert directory no-comment nil))
|
||||
(log-view--pick-or-revert directory no-comment nil nil nil))
|
||||
|
||||
(defun log-view-revision-revert (directory)
|
||||
(defun log-view-revert-or-delete-revisions
|
||||
(directory &optional interactive delete)
|
||||
"Undo the effects of the revision at point.
|
||||
When revisions are marked, undo the effects of each of them.
|
||||
When called interactively, prompts for the target working tree in which
|
||||
to revert; the current working tree is the default choice.
|
||||
When called from Lisp, DIRECTORY is the root of the target working tree.
|
||||
|
||||
When called interactively (or with optional argument INTERACTIVE
|
||||
non-nil), then if the underlying VCS is distributed, offer to entirely
|
||||
delete revisions that have not been pushed.
|
||||
This is instead of creating new commits undoing their effects.
|
||||
|
||||
With a prefix argument (or with optional argument DELETE non-nil),
|
||||
always delete revisions and never create new commits.
|
||||
In this case INTERACTIVE is ignored.
|
||||
This works only for unpublished commits, unless you have customized
|
||||
`vc-allow-rewriting-published-history' to a non-nil value.
|
||||
|
||||
When reverting a single revision, prompts for editing the log message
|
||||
for the new commit.
|
||||
When reverting multiple revisions, never prompts to edit log messages.
|
||||
|
||||
See also `vc-revision-revert'."
|
||||
See also `vc-revert-or-delete-revision'."
|
||||
(interactive (list (vc--prompt-other-working-tree
|
||||
(vc-responsible-backend default-directory)
|
||||
(if current-prefix-arg "Delete in working tree"
|
||||
"Revert in working tree")
|
||||
'allow-empty)
|
||||
t current-prefix-arg))
|
||||
(log-view--pick-or-revert directory nil t interactive delete))
|
||||
|
||||
;; These are left unbound by default. A user who doesn't like the DWIM
|
||||
;; behavior of `log-view-revert-or-delete-revisions' can unbind that and
|
||||
;; bind these two commands instead.
|
||||
|
||||
(defun log-view-revert-revisions (directory)
|
||||
"Make a commit undoing the effects of the revision at point.
|
||||
When revisions are marked, make such a commit for each of them.
|
||||
When called interactively, prompts for the target working tree in which
|
||||
to make new commits; the current working tree is the default choice.
|
||||
When called from Lisp, DIRECTORY is the root of the target working tree.
|
||||
|
||||
This is like `log-view-revert-or-delete-revisions' except that it only
|
||||
ever makes new commits undoing the effects of revisions, instead of
|
||||
considering VCS-specific alternative mechanisms to undo the effects of
|
||||
revisions.
|
||||
|
||||
When reverting a single revision, prompts for editing the log message
|
||||
for the new commit.
|
||||
When reverting multiple revisions, never prompts to edit log messages.
|
||||
|
||||
See also `vc-revert-revision'."
|
||||
(interactive (list (vc--prompt-other-working-tree
|
||||
(vc-responsible-backend default-directory)
|
||||
"Revert in working tree"
|
||||
'allow-empty)))
|
||||
(log-view--pick-or-revert directory nil t))
|
||||
(log-view--pick-or-revert directory nil t nil 'never))
|
||||
|
||||
(defun log-view-delete-revisions (directory)
|
||||
"Delete the revision at point from the revision history.
|
||||
When revisions are marked, delete all of them.
|
||||
When called interactively, prompts for the target working tree in which
|
||||
to delete revisions; the current working tree is the default choice.
|
||||
When called from Lisp, DIRECTORY is the root of the target working tree.
|
||||
|
||||
This works only for unpublished commits, unless you have customized
|
||||
`vc-allow-rewriting-published-history' to a non-nil value.
|
||||
|
||||
This is the same as `log-view-revert-or-delete-revisions' invoked
|
||||
interactively with a prefix argument. See also `vc-delete-revision'."
|
||||
(interactive (list (vc--prompt-other-working-tree
|
||||
(vc-responsible-backend default-directory)
|
||||
"Delete in working tree"
|
||||
'allow-empty)))
|
||||
(log-view--pick-or-revert directory nil t nil t))
|
||||
|
||||
;;;;
|
||||
;;;; diff
|
||||
|
|
|
|||
|
|
@ -1053,11 +1053,11 @@ other commands receive global bindings where they had none before."
|
|||
|
||||
(defvar vc-menu-map
|
||||
(let ((map (make-sparse-keymap "Version Control")))
|
||||
(define-key map [vc-revision-revert]
|
||||
'(menu-item "Revert Revision" vc-revision-revert
|
||||
(define-key map [vc-revert-or-delete-revision]
|
||||
'(menu-item "Revert Revision" vc-revert-or-delete-revision
|
||||
:help "Undo the effects of a revision"))
|
||||
(define-key map [vc-revision-cherry-pick]
|
||||
'(menu-item "Cherry-Pick Revision" vc-revision-cherry-pick
|
||||
(define-key map [vc-cherry-pick]
|
||||
'(menu-item "Cherry-Pick Revision" vc-cherry-pick
|
||||
:help "Copy the changes from a single revision to this branch"))
|
||||
(define-key map [separator1] menu-bar-separator)
|
||||
(define-key map [vc-retrieve-tag]
|
||||
|
|
|
|||
190
lisp/vc/vc.el
190
lisp/vc/vc.el
|
|
@ -2166,22 +2166,121 @@ have changed; continue with old fileset?" (current-buffer))))
|
|||
(declare-function diff-buffer-file-names "diff-mode")
|
||||
(declare-function diff-reverse-direction "diff-mode")
|
||||
|
||||
(defun vc--pick-or-revert (rev reverse comment initial-contents backend)
|
||||
(defun vc--pick-or-revert
|
||||
(rev reverse interactive delete comment initial-contents backend)
|
||||
"Copy a single revision REV to branch checked out in this working tree.
|
||||
REVERSE means to undo the effects of REV, instead.
|
||||
|
||||
REVERSE non-nil means to undo the effects of REV, instead.
|
||||
This is affected by whether the VCS is centralized or distributed and
|
||||
the INTERACTIVE and DELETE arguments, as follows:
|
||||
- For a centralized VCS for which Emacs knows how to do true undos, then
|
||||
unless DELETE is the special value `never', do a true undo of REV.
|
||||
This function supports creating new commits undoing the effects of REV
|
||||
for even a centralized VCS with true undos by passing `never' as
|
||||
DELETE (as `vc-revert-revision' does).
|
||||
For centralized VCS, INTERACTIVE is ignored.
|
||||
- For a distributed VCS, when INTERACTIVE is non-nil, DELETE is nil, and
|
||||
REV has not yet been pushed, offer to delete REV entirely instead of
|
||||
creating a new commit undoing its EFFECTS.
|
||||
If INTERACTIVE is `no-confirm', don't prompt to confirm the deletion.
|
||||
- For a distributed VCS, when DELETE is non-nil (but not `never'), only
|
||||
consider deleting REV, never create a new commit, but subject to
|
||||
`vc-allow-rewriting-published-history'.
|
||||
In this case INTERACTIVE is ignored.
|
||||
(This complex calling convention makes for simple usage of this
|
||||
workhorse function from the frontend VC commands that provide access to
|
||||
all this functionality.)
|
||||
|
||||
COMMENT is a comment string; if omitted, a buffer is popped up to accept
|
||||
a comment. If INITIAL-CONTENTS is non-nil, then COMMENT is used as the
|
||||
initial contents of the log entry buffer. If COMMENT is t then use
|
||||
BACKEND's default cherry-pick comment for REV without prompting.
|
||||
BACKEND is the VC backend to use."
|
||||
(let* ((backend (or backend (vc-responsible-backend default-directory)))
|
||||
;; `vc-*-prepare-patch' will always give us a patch with file
|
||||
;; names relative to the VC root, so switch to there now.
|
||||
;; In particular this is needed for `diff-buffer-file-names' to
|
||||
;; work properly.
|
||||
(default-directory (vc-call-backend backend 'root default-directory))
|
||||
(patch (vc-call-backend backend 'prepare-patch rev))
|
||||
files whole-patch-string diff-patch-string)
|
||||
BACKEND is the VC backend to use.
|
||||
|
||||
Return `deleted' if we actually undid/deleted a commit.
|
||||
Any other return value means we called `vc-start-logentry'."
|
||||
(cond*
|
||||
((bind* (backend (or backend
|
||||
(vc-responsible-backend default-directory)))))
|
||||
((and reverse (not (eq delete 'never))
|
||||
(null (vc-find-backend-function backend
|
||||
'revision-published-p))
|
||||
(vc-find-backend-function backend 'delete-revision))
|
||||
;; Centralized VCS implementing `delete-revision'.
|
||||
(vc-call-backend backend 'delete-revision rev)
|
||||
'deleted)
|
||||
((and reverse interactive (not delete)
|
||||
;; Distributed VCS for which we can do deletions.
|
||||
(vc-find-backend-function backend 'revision-published-p)
|
||||
(vc-find-backend-function backend 'delete-revision)
|
||||
;; REV is safe to delete.
|
||||
(not (vc-call-backend backend 'revision-published-p rev)))
|
||||
;; Require confirmation, because the commit is unpublished, and so
|
||||
;; this might be the only copy of the work in REV. Don't fall back
|
||||
;; to making a new commit undoing REV's changes because we don't
|
||||
;; know the user wants that just because they said "no" to our
|
||||
;; question here, and we want to avoid two y/n prompts in a row,
|
||||
;; which is probably a less good UI than this.
|
||||
(cond ((or (eq interactive 'no-confirm)
|
||||
(yes-or-no-p
|
||||
(format "Permanently delete %s from the revision history?"
|
||||
rev)))
|
||||
(vc-call-backend backend 'delete-revision rev)
|
||||
'deleted)
|
||||
((derived-mode-p 'log-view-mode)
|
||||
(user-error (substitute-command-keys "\
|
||||
Use \\[log-view-revert-revisions] to create new commits \
|
||||
undoing changes made by revision(s)")))
|
||||
(t
|
||||
(user-error (substitute-command-keys "\
|
||||
Use \\[vc-revert-revision] to create a new commit undoing %s's changes")
|
||||
rev))))
|
||||
((and reverse delete (not (eq delete 'never))
|
||||
;; Distributed VCS for which we can do deletions.
|
||||
(vc-find-backend-function backend 'revision-published-p)
|
||||
(vc-find-backend-function backend 'delete-revision))
|
||||
;; Even though the user has explicitly requested deletion with a
|
||||
;; prefix argument / invoking `vc-delete-revision' / invoking
|
||||
;; `log-view-delete-revisions', by default we still confirm such a
|
||||
;; destructive operation.
|
||||
;; However, we want to avoid prompting twice in the case that the
|
||||
;; user has set `vc-allow-rewriting-published-history' to `ask', and
|
||||
;; we should avoid prompting at all in the case that
|
||||
;; `vc-allow-rewriting-published-history' is another non-nil value.
|
||||
;; These requirements lead to the nested `cond*' form here.
|
||||
(cond*
|
||||
((and vc-allow-rewriting-published-history
|
||||
(not (eq vc-allow-rewriting-published-history 'ask)))
|
||||
(vc-call-backend backend 'delete-revision rev)
|
||||
'deleted)
|
||||
((bind* (published (vc-call-backend backend 'revision-published-p rev))))
|
||||
((and published
|
||||
(eq vc-allow-rewriting-published-history 'ask)
|
||||
(yes-or-no-p
|
||||
(format "Revision %s appears published; allow rewriting history?"
|
||||
rev)))
|
||||
(vc-call-backend backend 'delete-revision rev)
|
||||
'deleted)
|
||||
(published
|
||||
(user-error "Will not rewrite likely-public history"))
|
||||
((yes-or-no-p
|
||||
(format "Permanently delete %s from the revision history?"
|
||||
rev))
|
||||
(vc-call-backend backend 'delete-revision rev)
|
||||
'deleted)
|
||||
(t
|
||||
(user-error "Aborted"))))
|
||||
;; If we get this far we give up on `delete-revision', i.e. we fall
|
||||
;; back to creating a commit undoing the effects of REV.
|
||||
;;
|
||||
;; `vc-*-prepare-patch' will always give us a patch with file names
|
||||
;; relative to the VC root, so switch to there now. In particular
|
||||
;; this is needed for `diff-buffer-file-names' to work properly.
|
||||
((bind* (default-directory (vc-call-backend backend 'root
|
||||
default-directory))
|
||||
(patch (vc-call-backend backend 'prepare-patch rev))
|
||||
files whole-patch-string diff-patch-string))
|
||||
(t
|
||||
(with-current-buffer (plist-get patch :buffer)
|
||||
(diff-mode)
|
||||
(with-restriction
|
||||
|
|
@ -2218,14 +2317,14 @@ BACKEND is the VC backend to use."
|
|||
whole-patch-string comment))
|
||||
nil
|
||||
backend
|
||||
diff-patch-string)))
|
||||
diff-patch-string))))
|
||||
|
||||
;; No bindings in `vc-prefix-map' for the following two commands because
|
||||
;; we expect users will usually use `log-view-revision-cherry-pick' and
|
||||
;; `log-view-revision-revert', which do have bindings.
|
||||
;; No bindings in `vc-prefix-map' for the following three items because
|
||||
;; we expect users will usually use `log-view-cherry-pick' and
|
||||
;; `log-view-revert-or-delete-revisions', which do have bindings.
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-revision-cherry-pick (rev &optional comment initial-contents backend)
|
||||
(defun vc-cherry-pick (rev &optional comment initial-contents backend)
|
||||
"Copy the changes from a single revision REV to the current branch.
|
||||
When called interactively, prompts for REV.
|
||||
Typically REV is a revision from another branch, where that branch is
|
||||
|
|
@ -2256,13 +2355,55 @@ Optional argument BACKEND is the VC backend to use."
|
|||
nil rev))
|
||||
nil
|
||||
backend)))
|
||||
(vc--pick-or-revert rev nil comment initial-contents backend))
|
||||
(vc--pick-or-revert rev nil nil nil comment initial-contents backend))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-revision-revert (rev &optional comment initial-contents backend)
|
||||
(defun vc-revert-or-delete-revision
|
||||
(rev &optional interactive delete comment initial-contents backend)
|
||||
"Undo the effects of revision REV.
|
||||
When called interactively, prompts for REV.
|
||||
|
||||
When called interactively (or with optional argument INTERACTIVE
|
||||
non-nil), then if the underlying VCS is distributed and REV has not been
|
||||
pushed, offer to entirely delete REV.
|
||||
This is instead of creating a new commit undoing the effects of REV.
|
||||
|
||||
With a prefix argument (or with optional argument DELETE non-nil),
|
||||
only consider deleting REV, never create a new commit.
|
||||
In this case INTERACTIVE is ignored.
|
||||
This works only if REV has not been pushed, unless you have customized
|
||||
`vc-allow-rewriting-published-history' to a non-nil value.
|
||||
|
||||
When called from Lisp, there are three calling conventions for the
|
||||
COMMENT and INITIAL-CONTENTS optional arguments:
|
||||
- COMMENT a string, INITIAL-CONTENTS nil means use that comment string
|
||||
without prompting the user to edit it.
|
||||
- COMMENT a string, INITIAL-CONTENTS non-nil means use that comment
|
||||
string as the initial contents of the log entry buffer but stop for
|
||||
editing.
|
||||
- COMMENT t means use BACKEND's default revert comment for REV without
|
||||
prompting for editing, and ignore INITIAL-CONTENTS.
|
||||
|
||||
Optional argument BACKEND is the VC backend to use.
|
||||
|
||||
See also `vc-revert-revision'."
|
||||
(interactive (list (vc-read-revision (if current-prefix-arg
|
||||
"Revision to delete: "
|
||||
"Revision to revert: "))
|
||||
t current-prefix-arg))
|
||||
(vc--pick-or-revert rev t interactive delete
|
||||
comment initial-contents backend))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-revert-revision
|
||||
(rev &optional comment initial-contents backend)
|
||||
"Make a commit undoing the effects of revision REV.
|
||||
When called interactively, prompts for REV.
|
||||
|
||||
This is like `vc-revert-or-delete-revision' except that it only ever makes a new
|
||||
commit undoing the effects of REV, instead of considering VCS-specific
|
||||
alternative mechanisms to undo the effects of REV.
|
||||
|
||||
When called from Lisp, there are three calling conventions for the
|
||||
COMMENT and INITIAL-CONTENTS optional arguments:
|
||||
- COMMENT a string, INITIAL-CONTENTS nil means use that comment string
|
||||
|
|
@ -2275,7 +2416,18 @@ COMMENT and INITIAL-CONTENTS optional arguments:
|
|||
|
||||
Optional argument BACKEND is the VC backend to use."
|
||||
(interactive (list (vc-read-revision "Revision to revert: ")))
|
||||
(vc--pick-or-revert rev t comment initial-contents backend))
|
||||
(vc--pick-or-revert rev t nil 'never comment initial-contents backend))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-delete-revision (rev &optional backend)
|
||||
"Delete revision REV from the revision history.
|
||||
This works only if REV has not been pushed, unless you have customized
|
||||
`vc-allow-rewriting-published-history' to a non-nil value.
|
||||
|
||||
This is the same as `vc-revert-or-delete-revision' invoked interactively
|
||||
with a prefix argument."
|
||||
(interactive (list (vc-read-revision "Revision to delete: ")))
|
||||
(vc--pick-or-revert rev t nil t nil nil backend))
|
||||
|
||||
(declare-function diff-bounds-of-hunk "diff-mode")
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue