mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-05 22:20:24 -08:00
New commands to rewind decentralized VCS branches
* lisp/vc/vc.el (vc--remove-revisions-from-end): New function. (vc-uncommit-revisions-from-end, vc-delete-revisions-from-end): * lisp/vc/log-view.el (log-view-uncommit-revisions-from-end) (log-view-delete-revisions-from-end): New commands (bug#79408). (log-view-mode-map): Bind them. * doc/emacs/maintaining.texi (VC Change Log): * doc/emacs/vc1-xtra.texi (VC Auto-Reverting): * etc/NEWS: Document them.
This commit is contained in:
parent
dcc909917b
commit
11b68c6223
7 changed files with 194 additions and 2 deletions
|
|
@ -877,6 +877,7 @@ Miscellaneous Commands and Features of VC
|
|||
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
|
||||
* Preparing Patches:: Preparing and composing patches from within VC.
|
||||
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
|
||||
* Rewinding Branches:: Commands to delete revisions from ends of branches.
|
||||
|
||||
Customizing VC
|
||||
|
||||
|
|
|
|||
|
|
@ -1273,6 +1273,15 @@ the revision at point, or the changes from all marked revisions
|
|||
@item R
|
||||
Undo the effects of old revisions; either the revision at point, or all
|
||||
marked revisions (@code{log-view-revert-or-delete-revisions}).
|
||||
|
||||
@item x
|
||||
Delete revisions newer than the revision at point from the current
|
||||
branch without touching the working tree
|
||||
(@code{log-view-uncommit-revisions-from-end}).
|
||||
|
||||
@item X
|
||||
Delete revisions newer than the revision at point from the current
|
||||
branch (@code{log-view-delete-revisions-from-end}).
|
||||
@end table
|
||||
|
||||
@vindex vc-log-show-limit
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
* Editing VC Commands:: Editing the VC shell commands that Emacs will run.
|
||||
* Preparing Patches:: Preparing and composing patches from within VC.
|
||||
* VC Auto-Reverting:: Updating buffer contents after VCS operations.
|
||||
* Rewinding Branches:: Commands to delete revisions from ends of branches.
|
||||
@end menu
|
||||
|
||||
@node Change Logs and VC
|
||||
|
|
@ -678,6 +679,60 @@ contents, regardless of whether Emacs initiated those operations.
|
|||
@xref{VC Mode Line}, for details regarding Auto Revert mode in buffers
|
||||
visiting tracked files (which is what @code{vc-auto-revert-mode} enables).
|
||||
|
||||
@node Rewinding Branches
|
||||
@subsubsection Rewinding Branches
|
||||
@cindex rewinding a branch (VC)
|
||||
|
||||
@table @kbd
|
||||
@item M-x vc-delete-revisions-from-end
|
||||
Delete revisions from the end of the current branch.
|
||||
|
||||
@item M-x vc-uncommit-revisions-from-end
|
||||
Delete revisions from the end of the current branch without touching the
|
||||
working tree.
|
||||
@end table
|
||||
|
||||
@findex vc-delete-revisions-from-end
|
||||
For decentralized version control systems (@pxref{VCS Repositories}),
|
||||
these commands provide ways to move the current branch back to an
|
||||
earlier revision. @code{vc-delete-revisions-from-end} prompts for a
|
||||
revision, then removes all revisions from the end of the branch up to
|
||||
but not including the specified revision. We say that the branch is
|
||||
@dfn{rewound} back to the specified revision.
|
||||
|
||||
This command removes the changes made by the revisions from the
|
||||
working tree. Therefore, if there are any uncommitted changes, they
|
||||
must be reverted, first (@pxref{VC Undo}). This command will prompt you
|
||||
to do that if necessary. If you supply a prefix argument, Emacs will
|
||||
delete uncommitted changes without prompting.
|
||||
|
||||
@cindex uncommitting revisions
|
||||
@findex vc-uncommit-revisions-from-end
|
||||
To ``uncommit'' a revision means to remove it from the revision
|
||||
history without removing its changes from the working tree. It is as
|
||||
though you had made the changes but had not yet checked them in. The
|
||||
command @code{vc-uncommit-revisions-from-end} prompts for a revision,
|
||||
and then uncommits all revisions from the end of the branch up to but
|
||||
not including the specified revision. The branch is rewound back to the
|
||||
specified revision but the changes are left behind in the working tree.
|
||||
|
||||
When rewinding the current branch, if all the revisions deleted from
|
||||
the revision history are among those you have pulled or pushed, then
|
||||
these operations do not permanently delete anything: a simple
|
||||
@w{@kbd{C-x v +}} (@pxref{Pulling / Pushing}) will bring the revisions
|
||||
back. On the other hand, if there are new revisions on the end of the
|
||||
branch that have not yet been pushed, then these commands will delete
|
||||
them permanently. Emacs tries to detect this situation and ask you if
|
||||
you are sure you want to delete them.
|
||||
|
||||
Alternative ways to access this functionality are the
|
||||
@code{log-view-uncommit-revisions-from-end} and
|
||||
@code{log-view-delete-revisions-from-end} commands, bound to @kbd{x} and
|
||||
@kbd{X}, respectively, in Log View mode buffers (@pxref{VC Change Log}).
|
||||
Compared to using the commands described here directly, the Log View
|
||||
mode commands can make it easier to be sure you are rewinding back to
|
||||
the revision you intend.
|
||||
|
||||
@node Customizing VC
|
||||
@subsection Customizing VC
|
||||
|
||||
|
|
|
|||
7
etc/NEWS
7
etc/NEWS
|
|
@ -2393,6 +2393,13 @@ From Log View buffers, you can use 'C' to cherry-pick the revision at
|
|||
point or all marked revisions, and 'R' to undo the revision at point or
|
||||
all marked revisions.
|
||||
|
||||
+++
|
||||
*** New commands to rewind branches.
|
||||
In Log View mode, 'x' deletes revisions newer than the revision at point
|
||||
from the history of the current branch, though without undoing the
|
||||
changes made by those revisions to the working tree. 'X' is similar
|
||||
except that it does remove the changes from the working tree.
|
||||
|
||||
*** New command 'log-edit-done-strip-cvs-lines'.
|
||||
This command strips all lines beginning with "CVS:" from the buffer.
|
||||
It is intended to be added to the 'log-edit-done-hook' so that
|
||||
|
|
|
|||
|
|
@ -2235,7 +2235,8 @@ With a prefix argument, try to REVERSE the hunk."
|
|||
|
||||
This command is useful in buffers generated by \\[vc-diff] and \\[vc-root-diff],
|
||||
especially when preparing to commit the patch with \\[vc-next-action].
|
||||
You can use \\<diff-mode-map>\\[diff-hunk-kill] to temporarily remove changes that you intend to
|
||||
You can use \\<diff-mode-map>\\[diff-hunk-kill] \
|
||||
to temporarily remove changes that you intend to
|
||||
include in a separate commit or commits, and you can use this command
|
||||
to permanently drop changes you didn't intend, or no longer want.
|
||||
|
||||
|
|
|
|||
|
|
@ -115,6 +115,7 @@
|
|||
(autoload 'vc-find-revision "vc")
|
||||
(autoload 'vc-diff-internal "vc")
|
||||
(autoload 'vc--pick-or-revert "vc")
|
||||
(autoload 'vc--remove-revisions-from-end "vc")
|
||||
(autoload 'vc--prompt-other-working-tree "vc")
|
||||
|
||||
(defvar cvs-minor-wrap-function)
|
||||
|
|
@ -142,7 +143,9 @@
|
|||
"TAB" #'log-view-msg-next
|
||||
"<backtab>" #'log-view-msg-prev
|
||||
"C" #'log-view-cherry-pick
|
||||
"R" #'log-view-revert-or-delete-revisions)
|
||||
"R" #'log-view-revert-or-delete-revisions
|
||||
"x" #'log-view-uncommit-revisions-from-end
|
||||
"X" #'log-view-delete-revisions-from-end)
|
||||
|
||||
(easy-menu-define log-view-mode-menu log-view-mode-map
|
||||
"Log-View Display Menu."
|
||||
|
|
@ -828,6 +831,36 @@ See also `vc-revert-or-delete-revision'."
|
|||
t current-prefix-arg))
|
||||
(log-view--pick-or-revert directory nil t interactive delete))
|
||||
|
||||
(defun log-view-uncommit-revisions-from-end ()
|
||||
"Uncommit revisions newer than the revision at point.
|
||||
The revision at point must be on the current branch. The newer
|
||||
revisions are deleted from the revision history but the changes made by
|
||||
those revisions to files in the working tree are not undone.
|
||||
|
||||
To delete revisions from the revision history and also undo the changes
|
||||
in the working tree, see `log-edit-delete-revisions-from-end'."
|
||||
(interactive)
|
||||
(vc--remove-revisions-from-end (log-view-current-tag)
|
||||
nil t log-view-vc-backend)
|
||||
(revert-buffer))
|
||||
|
||||
(defun log-view-delete-revisions-from-end (&optional discard)
|
||||
"Delete revisions newer than the revision at point.
|
||||
The revision at point must be on the current branch. The newer
|
||||
revisions are deleted from the revision history and the changes made by
|
||||
those revisions to files in the working tree are undone.
|
||||
If the are uncommitted changes, prompts to discard them.
|
||||
With a prefix argument (when called from Lisp, with optional argument
|
||||
DISCARD non-nil), discard any uncommitted changes without prompting.
|
||||
|
||||
To delete revisions from the revision history without undoing the
|
||||
changes in the working tree, see `log-edit-uncommit-revisions-from-end'."
|
||||
(interactive "P")
|
||||
(vc--remove-revisions-from-end (log-view-current-tag)
|
||||
(if discard 'discard t)
|
||||
t log-view-vc-backend)
|
||||
(revert-buffer))
|
||||
|
||||
;; 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.
|
||||
|
|
|
|||
|
|
@ -2429,6 +2429,92 @@ with a prefix argument."
|
|||
(interactive (list (vc-read-revision "Revision to delete: ")))
|
||||
(vc--pick-or-revert rev t nil t nil nil backend))
|
||||
|
||||
(defun vc--remove-revisions-from-end (rev delete prompt backend)
|
||||
"Delete revisions newer than REV.
|
||||
DELETE non-nil means to remove the changes from the working tree.
|
||||
DELETE `discard' means to silently discard uncommitted changes.
|
||||
PROMPT non-nil means to always get confirmation. (This is passed by
|
||||
`log-view-uncommit-revisions-from-end' and `log-view-delete-revisions'
|
||||
because they have single-letter bindings and don't otherwise prompt, so
|
||||
might be easy to use accidentally.)
|
||||
BACKEND is the VC backend."
|
||||
(let ((backend (or backend (vc-responsible-backend default-directory))))
|
||||
(unless (eq (vc-call-backend backend 'revision-granularity)
|
||||
'repository)
|
||||
(error "Requires VCS with whole-repository revision granularity"))
|
||||
(unless (vc-find-backend-function backend 'revision-published-p)
|
||||
(signal 'vc-not-supported (list 'revision-published-p backend)))
|
||||
;; Rewinding the end of the branch to REV does not in itself mean
|
||||
;; rewriting public history because a subsequent pull will generally
|
||||
;; undo the rewinding. Rewinding and then making new commits before
|
||||
;; syncing with the upstream will necessitate merging, but that's
|
||||
;; just part of the normal workflow with a distributed VCS.
|
||||
;; Therefore we don't prompt about deleting published revisions (and
|
||||
;; so we ignore `vc-allow-rewriting-published-history').
|
||||
;; We do care about deleting *unpublished* revisions, however,
|
||||
;; because that could potentially mean losing work permanently.
|
||||
(when (if (vc-call-backend backend 'revision-published-p
|
||||
(vc-call-backend backend
|
||||
'working-revision-symbol))
|
||||
(and prompt
|
||||
(not (y-or-n-p
|
||||
(format "Uncommit revisions newer than %s?"
|
||||
rev))))
|
||||
;; FIXME: Actually potentially not all revisions newer than
|
||||
;; REV would be permanently deleted -- only those which are
|
||||
;; unpushed. So this prompt is a little misleading.
|
||||
(not (yes-or-no-p
|
||||
(format "Permanently delete revisions newer than %s?"
|
||||
rev))))
|
||||
(user-error "Aborted"))
|
||||
(if delete
|
||||
;; FIXME: As discussed in bug#79408, instead of just failing if
|
||||
;; the user declines reverting the changes, we would leave
|
||||
;; behind some sort of conflict for the user to resolve, like we
|
||||
;; do when there is a merge conflict.
|
||||
(let ((root (vc-root-dir)))
|
||||
(when (vc-dir-status-files root nil backend)
|
||||
(if (eq delete 'discard)
|
||||
(vc-revert-file root)
|
||||
(let ((vc-buffer-overriding-fileset `(,backend (,root))))
|
||||
(vc-revert))))
|
||||
(vc-call-backend backend 'delete-revisions-from-end rev))
|
||||
(vc-call-backend backend 'uncommit-revisions-from-end rev))))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-uncommit-revisions-from-end (rev &optional backend)
|
||||
"Delete revisions newer than REV without touching the working tree.
|
||||
REV must be on the current branch. The newer revisions are deleted from
|
||||
the revision history but the changes made by those revisions to files in
|
||||
the working tree are not undone.
|
||||
When called interactively, prompts for REV.
|
||||
BACKEND is the VC backend.
|
||||
|
||||
To delete revisions from the revision history and also undo the changes
|
||||
in the working tree, see `vc-delete-revisions-from-end'."
|
||||
(interactive (list
|
||||
(vc-read-revision "Uncommit revisions newer than revision: ")))
|
||||
(vc--remove-revisions-from-end rev nil nil backend))
|
||||
|
||||
;;;###autoload
|
||||
(defun vc-delete-revisions-from-end (rev &optional discard backend)
|
||||
"Delete revisions newer than REV.
|
||||
REV must be on the current branch. The newer revisions are deleted from
|
||||
the revision history and the changes made by those revisions to files in
|
||||
the working tree are undone.
|
||||
When called interactively, prompts for REV.
|
||||
If the are uncommitted changes, prompts to discard them.
|
||||
With a prefix argument (when called from Lisp, with optional argument
|
||||
DISCARD non-nil), discard any uncommitted changes without prompting.
|
||||
BACKEND is the VC backend.
|
||||
|
||||
To delete revisions from the revision history without undoing the
|
||||
changes in the working tree, see `vc-uncommit-revisions-from-end'."
|
||||
(interactive (list
|
||||
(vc-read-revision "Delete revisions newer than revision: ")
|
||||
current-prefix-arg))
|
||||
(vc--remove-revisions-from-end rev (if discard 'discard t) nil backend))
|
||||
|
||||
(declare-function diff-bounds-of-hunk "diff-mode")
|
||||
|
||||
(defun vc-default-checkin-patch (_backend patch-string comment)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue