--- emacs-23.1/lisp/net/tramp.el~	2009-08-02 18:26:42.000000000 +1200
+++ emacs-23.1/lisp/net/tramp.el	2009-08-02 18:29:46.000000000 +1200
@@ -1768,6 +1768,85 @@
 Escape sequence %s is replaced with name of Perl binary.
 This string is passed to `format', so percent characters need to be doubled.")
 
+
+(defconst tramp-bash-vc-files
+  "dir=\"$1\"
+parentdir=\`dirname \"$1\"\`
+base=\`basename \"$1\"\`
+
+echo \"(\"
+
+for tldir in \"$parentdir\" \"$parentdir/\"; do
+
+   echo -n '(\"'\"$tldir\"'\" '
+   if [ -e \"$tldir\" ]; then
+      echo -n \"t \"
+   else
+      echo -n \"nil \"
+   fi
+   if [ -r \"$tldir\" ]; then
+      echo -n \"t \"
+   else
+      echo -n \"nil \"
+   fi
+   if [ -d \"$tldir\" ]; then
+      echo -n \"t \"
+   else
+      echo -n \"nil \"
+   fi
+   if [ -x \"$tldir\" ]; then
+      echo \"t)\"
+   else
+      echo \"nil)\"
+   fi
+   done
+
+for sub in \"RCS/$base\" \"RCS/$base,v\" \"$base,v\" \"CVS/Entries\" \".svn/entries\" \"SCCS/s.$base\" \"s.$base\"; do
+    file=\"$parentdir/$sub\"
+    echo -n '(\"'\"$file\"'\" '
+    if [ -e \"$file\" ]; then
+        echo \"t \"
+    else
+        echo \"nil \"
+    fi
+    if [ -r \"$file\" ]; then
+        echo \"t)\"
+    else
+        echo \"nil)\"
+    fi
+done
+
+while true; do
+    for sub in \"_MTN/format\" \".hg\" \".git\" \".bzr/checkout/format\" \"{arch}/=tagging-method\"; do
+        if [[ \"$dir\" == \"/\" ]]; then
+            file=\"/$sub\"
+        else
+            file=\"$dir/$sub\"
+        fi
+        echo -n '(\"'\"$file\"'\" '
+        if [ -e \"$file\" ]; then
+            echo -n \"t \"
+        else
+            echo -n \"nil \"
+        fi
+        if [ -r \"$file\" ]; then
+            echo \"t)\"
+        else
+            echo \"nil)\"
+        fi
+    done
+    if [[ \"$dir\" == \"/\" ]]; then
+        break
+    fi
+    dir=\`dirname $dir\`
+done
+
+echo \")\""
+  "Bash script to check existance and permissions on files
+  anticipated to be checked by vc backends.  Used by
+  tramp-handle-vc-registered to avoid having to perform
+  individual remote checks.")
+
 (defconst tramp-file-mode-type-map
   '((0  . "-")  ; Normal file (SVID-v2 and XPG2)
     (1  . "p")  ; fifo
@@ -4551,12 +4630,44 @@
 	  (tramp-message v 0 "Wrote %s" filename))
 	(run-hooks 'tramp-handle-write-region-hook)))))
 
+(defun tramp-vc-file-name-handler (operation &rest args)
+  "Try satisfying file-exists-p requests from tramp-bash-vc-files cache"
+  (car (or (and (eq 'file-exists-p operation)
+                (cdr (with-parsed-tramp-file-name (car args) nil 
+                       (assoc localname tramp-handle-vc-cache))))
+           (and (eq 'file-readable-p operation)
+                (cddr (with-parsed-tramp-file-name (car args) nil 
+                       (assoc localname tramp-handle-vc-cache))))
+           (and (eq 'file-directory-p operation)
+                (cdddr (with-parsed-tramp-file-name (car args) nil 
+                         (assoc localname tramp-handle-vc-cache))))
+           (and (eq 'file-executable-p operation)
+                (cddddr (with-parsed-tramp-file-name (car args) nil 
+                          (assoc localname tramp-handle-vc-cache))))
+           (cons (apply 'tramp-file-name-handler operation args) nil))))
+
 (defun tramp-handle-vc-registered (file)
   "Like `vc-registered' for Tramp files."
   ;; There could be new files, created by the vc backend.  We disable
   ;; the cache therefore, by providing a temporary one.
-  (let ((tramp-cache-data (make-hash-table :test 'equal)))
-    (tramp-run-real-handler 'vc-registered (list file))))
+  ;;
+  ;; Also, checking for various version control files can cause a
+  ;; large number of file-exists-p operations.  We anticipate a number
+  ;; of common checks and perform them all in one go using
+  ;; tramp-bash-vc-files, in a single remote operation.  Then
+  ;; file-exists-p use that cache instead.
+  (with-parsed-tramp-file-name file nil
+    (tramp-maybe-send-script v tramp-bash-vc-files
+                             "tramp_bash_vc_files")
+    (let ((tramp-cache-data (make-hash-table :test 'equal))
+          (tramp-handle-vc-cache
+           (tramp-send-command-and-read
+            v (format "tramp_bash_vc_files %s" localname)))
+          (file-name-handler-alist
+           (cons (cons tramp-file-name-regexp
+                       'tramp-vc-file-name-handler)
+                 file-name-handler-alist)))
+      (tramp-run-real-handler 'vc-registered (list file)))))
 
 ;;;###autoload
 (progn (defun tramp-run-real-handler (operation args)
@@ -4565,6 +4676,7 @@
 pass to the OPERATION."
   (let* ((inhibit-file-name-handlers
 	  `(tramp-file-name-handler
+            tramp-vc-file-name-handler
 	    tramp-completion-file-name-handler
 	    cygwin-mount-name-hook-function
 	    cygwin-mount-map-drive-hook-function
