New *-revisions-from-end VC backend API functions (bug#79408)

* lisp/vc/vc-git.el (vc-git-delete-revisions-from-end)
(vc-git-uncommit-revisions-from-end):
* lisp/vc/vc-hg.el (vc-hg--assert-rev-on-current-branch)
(vc-hg--reset-back-to, vc-hg-delete-revisions-from-end)
(vc-hg-uncommit-revisions-from-end): New functions.
* lisp/vc/vc.el: Specify delete-revisions-from-end and
uncommit-revisions-from-end backend API functions (bug#79408).
This commit is contained in:
Sean Whitton 2025-10-31 18:49:19 +00:00
parent 1e47f7492a
commit 1fd4d3e070
3 changed files with 55 additions and 0 deletions

View file

@ -2332,6 +2332,18 @@ Rebase may --autosquash your other squash!/fixup!/amend!; proceed?")))
(vc-git-command nil 0 nil "rebase" "--abort")
(error "Merge conflicts while trying to delete %s; aborting" rev)))
(defun vc-git-delete-revisions-from-end (rev)
"Hard reset back to REV.
It is an error if REV is not on the current branch."
(vc-git--assert-revision-on-branch rev (vc-git--current-branch))
(vc-git-command nil 0 nil "reset" "--hard" rev))
(defun vc-git-uncommit-revisions-from-end (rev)
"Soft reset back to REV.
It is an error if REV is not on the current branch."
(vc-git--assert-revision-on-branch rev (vc-git--current-branch))
(vc-git-command nil 0 nil "reset" "--soft" rev))
(defvar vc-git-extra-menu-map
(let ((map (make-sparse-keymap)))
(define-key map [git-grep]

View file

@ -1906,6 +1906,35 @@ Always has to fetch, like `vc-hg-incoming-revision' does."
rev)))
(delete-file commands))))
(defun vc-hg--assert-rev-on-current-branch (rev)
"Assert that REV is on the current branch."
(with-temp-buffer
(vc-hg-command t nil nil "log" "--limit=1"
(format "--rev=%s & ancestors(.)" rev)
"--template={node}")
(when (bobp)
(error "Revision %s is not on the current branch" rev))))
(defun vc-hg--reset-back-to (rev keep)
"Strip revisions up to but not including rev.
If KEEP is non-nil, also pass --keep to `hg strip'."
(apply #'vc-hg-command nil 0 nil "--config=extensions.strip="
"strip" "--force"
(format "--rev=descendants(%s) & !%s" rev rev)
(and keep '("--keep"))))
(defun vc-hg-delete-revisions-from-end (rev)
"Strip revisions up to but not including REV.
It is an error if REV is not on the current branch."
(vc-hg--assert-rev-on-current-branch rev)
(vc-hg--reset-back-to rev nil))
(defun vc-hg-uncommit-revisions-from-end (rev)
"Strip revisions up to but not including REV w/o modifying working tree.
It is an error if REV is not on the current branch."
(vc-hg--assert-rev-on-current-branch rev)
(vc-hg--reset-back-to rev t))
(provide 'vc-hg)
;;; vc-hg.el ends here

View file

@ -408,6 +408,20 @@
;; different; for example CVS has true undos (not yet implemented in
;; Emacs). A distributed VCS that implements this must also implement
;; revision-published-p.
;;
;; - delete-revisions-from-end (rev)
;;
;; Delete revisions from the revision history, from the end of the
;; branch up to but not including REV, including removing the changes
;; made by those revisions to the working tree. If there are
;; uncommitted changes the implementation should discard them.
;;
;; - uncommit-revisions-from-end (rev)
;;
;; Delete revisions from the revision history, from the end of the
;; branch up to but not including REV, but without removing the
;; changes made by those revisions from the working tree.
;; I.e., the working tree contents should not change.
;; HISTORY FUNCTIONS
;;