2007-12-26 Eric S. Raymond <esr@snark.thyrsus.com>
* log-view.el: Add Subversion and Mercurial log format samples.
+ * vc-bzr.el, vc-cvs.el, vc.el, vc-mcvs.el, vc-svn.el: Significantly
+ speed up (vc-dired-hook) by arranging for it to call the backend
+ dir-state hook (if it exists) exactly *once*, rather than once per
+ each subdirectory (with dired-state-info calls on all toplevel files
+ slowing it down even further). For this to work, backend dir-state
+ methods have to recurse to subdirectories. Most of them already
+ did anyway; a few needed *non*-recursion switches removed. This
+ change mostly removed code that was perversely bad and should have
+ been shot through the head years ago.
2007-12-26 Andreas Schwab <schwab@suse.de>
;; and implement a command to run ediff and `bzr resolve' once the
;; changes have been merged.
(defun vc-bzr-dir-state (dir &optional localp)
- "Find the VC state of all files in DIR.
+ "Find the VC state of all files in DIR and its subdirectories.
Optional argument LOCALP is always ignored."
(let ((bzr-root-directory (vc-bzr-root dir))
(at-start t)
;; evidence of the contrary.
(setq at-start t)
(with-temp-buffer
- (vc-bzr-command "ls" t 0 nil "--versioned" "--non-recursive")
+ (vc-bzr-command "ls" t 0 nil "--versioned")
(goto-char (point-min))
(while (or at-start
(eq 0 (forward-line)))
'edited)))
(defun vc-cvs-dir-state (dir)
- "Find the CVS state of all files in DIR."
+ "Find the CVS state of all files in DIR and subdirectories."
;; if DIR is not under CVS control, don't do anything.
(when (file-readable-p (expand-file-name "CVS/Entries" dir))
(if (vc-stay-local-p dir)
;; Don't specify DIR in this command, the default-directory is
;; enough. Otherwise it might fail with remote repositories.
(with-temp-buffer
- (vc-cvs-command t 0 nil "status" "-l")
+ (vc-cvs-command t 0 nil "status")
(goto-char (point-min))
(while (re-search-forward "^=+\n\\([^=\n].*\n\\|\n\\)+" nil t)
(narrow-to-region (match-beginning 0) (match-end 0))
(defalias 'vc-mcvs-state-heuristic 'vc-cvs-state-heuristic)
(defun vc-mcvs-dir-state (dir)
- "Find the Meta-CVS state of all files in DIR."
+ "Find the Meta-CVS state of all files in DIR and subdirectories."
;; if DIR is not under Meta-CVS control, don't do anything.
(when (file-readable-p (expand-file-name "MCVS/CVS/Entries" dir))
(if (vc-stay-local-p dir)
;; enough. Otherwise it might fail with remote repositories.
(with-temp-buffer
(setq default-directory (vc-mcvs-root dir))
- (vc-mcvs-command t 0 nil "status" "-l")
+ (vc-mcvs-command t 0 nil "status")
(goto-char (point-min))
(while (re-search-forward "^=+\n\\([^=\n].*\n\\|\n\\)+" nil t)
(narrow-to-region (match-beginning 0) (match-end 0))
;; Sync'd with Subversion's vc-svn.el as of revision 5801. but this version
;; has been extensively modified since to handle filesets.
-;;; Bugs:
-
-;; - VC-dired is (really) slow.
-
;;; Code:
(eval-when-compile
(vc-svn-state file 'local))
(defun vc-svn-dir-state (dir &optional localp)
- "Find the SVN state of all files in DIR."
+ "Find the SVN state of all files in DIR and its subdirectories."
(setq localp (or localp (vc-stay-local-p dir)))
(let ((default-directory dir))
;; Don't specify DIR in this command, the default-directory is
;; - dir-state (dir)
;;
;; If provided, this function is used to find the version control state
-;; of all files in DIR in a fast way. The function should not return
-;; anything, but rather store the files' states into the corresponding
-;; `vc-state' properties.
+;; of all files in DIR, and all subdirecties of DIR, in a fast way.
+;; The function should not return anything, but rather store the files'
+;; states into the corresponding `vc-state' properties. (Note: in
+;; older versions this method was not required to recurse into
+;; subdirectories.)
;;
;; * working-revision (file)
;;
"Reformat the listing according to version control.
Called by dired after any portion of a vc-dired buffer has been read in."
(message "Getting version information... ")
- (let (subdir filename (inhibit-read-only t))
+ ;; if the backend supports it, get the state
+ ;; of all files in this directory at once
+ (let ((backend (vc-responsible-backend default-directory)))
+ ;; check `backend' can really handle `default-directory'.
+ (if (and (vc-call-backend backend 'responsible-p default-directory)
+ (vc-find-backend-function backend 'dir-state))
+ (vc-call-backend backend 'dir-state default-directory)))
+ (let (filename (inhibit-read-only t))
(goto-char (point-min))
(while (not (eobp))
(cond
;; subdir header line
- ((setq subdir (dired-get-subdir))
- ;; if the backend supports it, get the state
- ;; of all files in this directory at once
- (let ((backend (vc-responsible-backend subdir)))
- ;; check `backend' can really handle `subdir'.
- (if (and (vc-call-backend backend 'responsible-p subdir)
- (vc-find-backend-function backend 'dir-state))
- (vc-call-backend backend 'dir-state subdir)))
+ ((dired-get-subdir)
(forward-line 1)
;; erase (but don't remove) the "total" line
(delete-region (point) (line-end-position))