]> git.eshelyaron.com Git - emacs.git/commitdiff
New revert-files VC backend function for faster mass reverts
authorSean Whitton <spwhitton@spwhitton.name>
Fri, 6 Jun 2025 10:52:32 +0000 (11:52 +0100)
committerEshel Yaron <me@eshelyaron.com>
Sat, 7 Jun 2025 20:01:48 +0000 (22:01 +0200)
* lisp/vc/vc-git.el (vc-git-revert-files):
* lisp/vc/vc-hg.el (vc-hg-revert-files):
* lisp/vc/vc.el (vc-revert-files): New functions.
(vc-revert-files): Incorporate vc-revert's calls to message here
so that the messages are displayed more consistently.
(vc-next-action, vc-default-checkin-patch, vc-revert): Use
vc-revert-files instead of vc-revert-file.

(cherry picked from commit 757f6cb0ac710533d5e18035e8b20a4bc7dcdc7c)

lisp/vc/vc-git.el
lisp/vc/vc-hg.el
lisp/vc/vc.el

index 4409af630416c8577f2d1b19925c118c84e22dff..fe75bd60f88f775ce40061ddf2731e26fe087656 100644 (file)
@@ -1333,12 +1333,17 @@ It is based on `log-edit-mode', and has Git-specific extensions."
   (vc-git-command nil 0 file "checkout" (or rev "HEAD")))
 
 (defun vc-git-revert (file &optional contents-done)
-  "Revert FILE to the version stored in the git repository."
+  "Revert FILE to the version stored in the Git repository."
   (if contents-done
       (vc-git-command nil 0 file "update-index" "--")
     (vc-git-command nil 0 file "reset" "-q" "--")
     (vc-git-command nil nil file "checkout" "-q" "--")))
 
+(defun vc-git-revert-files (files)
+  "Revert FILES to the versions stored in the Git repository."
+  (vc-git-command nil 0 files "reset" "-q" "--")
+  (vc-git-command nil nil files "checkout" "-q" "--"))
+
 (defvar vc-git-error-regexp-alist
   '(("^ \\(.+\\)\\> *|" 1 nil nil 0))
   "Value of `compilation-error-regexp-alist' in *vc-git* buffers.")
index 04a85fadd92f2cf19723893c24090b131a7915c2..31506ee649344350d16d40c2425ac8379c634ec2 100644 (file)
@@ -1315,11 +1315,14 @@ REV is the revision to check out into WORKFILE."
 (defun vc-hg-revert (file &optional contents-done)
   (unless contents-done
     (with-temp-buffer
-      (apply #'vc-hg-command
-             t 0 file
-             "revert"
+      (apply #'vc-hg-command t 0 file "revert"
              (append (vc-switches 'hg 'revert))))))
 
+(defun vc-hg-revert-files (files)
+  (with-temp-buffer
+    (apply #'vc-hg-command t 0 files "revert"
+           (append (vc-switches 'hg 'revert)))))
+
 ;;; Hg specific functionality.
 
 (defvar-keymap vc-hg-extra-menu-map)
index 5c61f9b605bf04d1702c9ad48d86e67eb2073396..86eed61f70fcb26b358e33dd7827d93b2f3e19cc 100644 (file)
 ;;   If FILE is in the `added' state it should be returned to the
 ;;   `unregistered' state.
 ;;
+;; - revert-files (files)
+;;
+;;   As revert, except that the first argument is a list of files, all
+;;   of which require reversion, and reversion from version backups is
+;;   not done.  Backends can implement this for faster mass reverts.
+;;
 ;; - merge-file (file &optional rev1 rev2)
 ;;
 ;;   Merge the changes between REV1 and REV2 into the current working
@@ -1542,19 +1548,22 @@ from which to check out the file(s)."
                    (read-only-mode -1)))))))
        ;; Allow user to revert files with no changes
        (save-excursion
-          (dolist (file files)
-            (let ((visited (get-file-buffer file)))
-              ;; For files with locking, if the file does not contain
-              ;; any changes, just let go of the lock, i.e. revert.
-              (when (and (not (eq model 'implicit))
-                        (eq state 'up-to-date)
-                        ;; If buffer is modified, that means the user just
-                        ;; said no to saving it; in that case, don't revert,
-                        ;; because the user might intend to save after
-                        ;; finishing the log entry and committing.
-                        (not (and visited (buffer-modified-p visited))))
-                (vc-revert-file file)
-               (setq ready-for-commit (delete file ready-for-commit))))))
+          (let (to-revert)
+            (dolist (file files)
+              (let ((visited (get-file-buffer file)))
+                ;; For files with locking, if the file does not contain
+                ;; any changes, just let go of the lock, i.e. revert.
+                (when (and (not (eq model 'implicit))
+                          (eq state 'up-to-date)
+                          ;; If buffer is modified, that means the user just
+                          ;; said no to saving it; in that case, don't revert,
+                          ;; because the user might intend to save after
+                          ;; finishing the log entry and committing.
+                          (not (and visited (buffer-modified-p visited))))
+                  (push file to-revert))))
+            (vc-revert-files backend to-revert)
+            (setq ready-for-commit
+                  (cl-nset-difference ready-for-commit to-revert))))
        ;; Remaining files need to be committed
        (if (not ready-for-commit)
            (message "No files remain to be committed")
@@ -1946,9 +1955,11 @@ Runs the normal hooks `vc-before-checkin-hook' and `vc-checkin-hook'."
                  (expand-file-name f tmpdir)))
     (unwind-protect
         (progn
-          (dolist (f files)
-            (with-current-buffer (find-file-noselect f)
-              (vc-revert-file buffer-file-name)))
+          (vc-revert-files backend
+                           (mapcar (lambda (f)
+                                     (with-current-buffer (find-file-noselect f)
+                                       buffer-file-name))
+                                   files))
           (with-temp-buffer
             ;; Trying to support CVS too.  Assuming that vc-diff
             ;; there will usually have diff root in default-directory.
@@ -3350,6 +3361,7 @@ This asks for confirmation if the buffer contents are not identical
 to the working revision (except for keyword expansion)."
   (interactive)
   (let* ((vc-fileset (vc-deduce-fileset))
+         (backend (car vc-fileset))
         (files (cadr vc-fileset))
         (queried nil)
         diff-buffer)
@@ -3392,10 +3404,7 @@ to the working revision (except for keyword expansion)."
            (error "Revert canceled")))
       (when diff-buffer
        (quit-windows-on diff-buffer (eq vc-revert-show-diff 'kill))))
-    (dolist (file files)
-      (message "Reverting %s..." (vc-delistify files))
-      (vc-revert-file file)
-      (message "Reverting %s...done" (vc-delistify files)))))
+    (vc-revert-files backend files)))
 
 ;;;###autoload
 (defun vc-pull (&optional arg)
@@ -3528,6 +3537,23 @@ If FILE is a directory, revert all files inside that directory."
                           (file-attributes file)))))
   (vc-resynch-buffer file t t))
 
+(defun vc-revert-files (backend files)
+  "Revert each of FILES to the repository working version it was based on.
+For entries in FILES that are directories, revert all files inside them."
+  (when files
+    (message "Reverting %s..." (vc-delistify files))
+    (if (not (vc-find-backend-function backend 'revert-files))
+        (mapc #'vc-revert-file files)
+      (with-vc-properties files
+                          (vc-call-backend backend 'revert-files files)
+                          `((vc-state . up-to-date)))
+      (dolist (file files)
+        (vc-file-setprop file 'vc-checkout-time
+                         (file-attribute-modification-time
+                          (file-attributes file)))
+        (vc-resynch-buffer file t t)))
+    (message "Reverting %s...done" (vc-delistify files))))
+
 ;;;###autoload
 (defun vc-change-backend (file backend)
   "Make BACKEND the current version control system for FILE.