emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: State of the repository conversion


From: Óscar Fuentes
Subject: Re: State of the repository conversion
Date: Thu, 20 Mar 2014 16:09:09 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

Stefan <address@hidden> writes:

>> Magit. I experimented with advising the VC functions that update the VC
>> status and the speedup is dramatic (one or two git invocations per Magit
>> operation instead of one per visited file.)
>
> Do post your hack

Below is the patch against an old version of magit.el.

> (as a bug-report requesting a new VC feature), tho better would be a
> proper patch.

This could be generalized to a generic VC feature, but I'm not sure it
is worth the trouble outside of Magit on Windows. Do you know any other
context (VC backend/package/platform) where it would make a difference?

Author: Oscar Fuentes <address@hidden>
Date:   Mon Aug 15 00:15:30 2011 +0200

    Speed-up magit-revert-buffers
    
    Advice some vc-git-* functions and use a cache. 100x faster on Windows
    when there are more than 10 files visited under the working copy.

1 file changed, 65 insertions(+), 14 deletions(-)
 magit.el | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++------------

        Modified   magit.el
diff --git a/magit.el b/magit.el
index 0e6f2b6..8a938c9 100644
--- a/magit.el
+++ b/magit.el
@@ -2210,23 +2210,74 @@ Please see the manual for a complete description of 
Magit.
 (defun magit-string-has-prefix-p (string prefix)
   (eq (compare-strings string nil (length prefix) prefix nil nil) t))
 
+(defvar magit-refresh-needing-buffers nil)
+(defvar magit-refresh-pending nil)
+(defvar magit-cached-vc-state nil)
+(defvar magit-vc-state-cache-buffer-name " *magit-vc-state-cache*")
+
 (defun magit-revert-buffers (dir &optional ignore-modtime)
-  (dolist (buffer (buffer-list))
-    (when (and buffer
-              (buffer-file-name buffer)
-              (magit-string-has-prefix-p (buffer-file-name buffer) dir))
-      (with-current-buffer buffer
-       (or (ignore-errors
-            (and (or ignore-modtime (not (verify-visited-file-modtime buffer)))
-                 (not (buffer-modified-p buffer))
-                 (revert-buffer t t nil)))
-           ;; Update the VC modeline info when revert-buffer failed to execute:
-           (ignore-errors
-            (vc-find-file-hook))))))
+  (let ((magit-cached-vc-state
+        (list (magit-get-current-branch) dir)))
+    (magit-create-vc-state-cache dir)
+    (dolist (buffer (buffer-list))
+      (when (and buffer
+                (buffer-file-name buffer)
+                (magit-string-has-prefix-p (buffer-file-name buffer) dir))
+       (with-current-buffer buffer
+         (or (ignore-errors
+               (and (or ignore-modtime (not (verify-visited-file-modtime 
buffer)))
+                    (not (buffer-modified-p buffer))
+                    (revert-buffer t t nil)))
+             ;; Update the VC modeline info when revert-buffer failed to 
execute:
+             (ignore-errors
+               (vc-find-file-hook)))))))
+  (kill-buffer magit-vc-state-cache-buffer-name)
   (setq magit-revert-buffers-pending nil))
 
-(defvar magit-refresh-needing-buffers nil)
-(defvar magit-refresh-pending nil)
+(defun magit-create-vc-state-cache (dir)
+  (let ((sbuffer (get-buffer-create magit-vc-state-cache-buffer-name)))
+    (with-current-buffer sbuffer
+      (setq default-directory dir)
+      (buffer-disable-undo)
+      (erase-buffer)
+      (call-process vc-git-executable nil sbuffer nil "ls-files" "-tdcm"))))
+
+(defun magit-lookup-vc-state (file)
+  (when (magit-string-has-prefix-p file (nth 1 magit-cached-vc-state))
+    (setq file (substring file (length (nth 1 magit-cached-vc-state)))))
+  (with-current-buffer magit-vc-state-cache-buffer-name
+    (goto-char (point-max))
+    (if (re-search-backward (concat "^. " file "$") nil t)
+       (let ((line (match-string 0)))
+         (if (string-match "^\\(.\\) .+$" line)
+             (magit-vc-git--state-code (match-string 1 line))))
+      'unregistered)))
+
+(defun magit-vc-git--state-code (code)
+  "Convert from a string to a added/deleted/modified state."
+  (case (string-to-char code)
+    (?C 'edited)
+    (?H 'up-to-date)
+    (?R 'removed)
+    (?M 'conflict)
+    (?T 'edited)))
+
+(defadvice vc-git-state (around ad-magit-vc-git-state activate)
+  (if magit-cached-vc-state
+      (setq ad-return-value (magit-lookup-vc-state file))
+    ad-do-it))
+
+(defadvice vc-git-working-revision (around ad-magit-vc-git-working-revision
+                                          activate)
+  (if magit-cached-vc-state
+      (setq ad-return-value (nth 0 magit-cached-vc-state))
+    ad-do-it))
+
+(defadvice vc-git-registered (around ad-magit-vc-git-registered activate)
+  (if magit-cached-vc-state
+      (setq ad-return-value
+           (not (eq 'unregistered (magit-lookup-vc-state file))))
+    ad-do-it))
 
 (defun magit-refresh-wrapper (func)
   (if magit-refresh-pending




reply via email to

[Prev in Thread] Current Thread [Next in Thread]