Subject: bug#2652: 23.0.91; wacky behavior of "v" command in *vc-dir* buffer

From: Dan Nicolaescu <[email-masked]>
Date: Mon, 13 Apr 2009 10:02:35 -0700 (PDT)

Stefan Monnier <[email-masked]> writes:

  > > But I don't really want to check it in at this point without an explicit
  > > request from Stefan.
  > 
  > Removing calls to determine the backend (and replace them with backend
  > info propagated from elsewhere) is generally a good thing.  I think your
  > patch looks good.

Here's another patch of the same kind: it removes vc-backend calls for
vc-stay-local-p.

OK or 23.2? 

Index: vc-cvs.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-cvs.el,v
retrieving revision 1.163
diff -u -3 -p -r1.163 vc-cvs.el
--- vc-cvs.el	5 Jan 2009 03:19:51 -0000	1.163
+++ vc-cvs.el	13 Apr 2009 16:43:24 -0000
@@ -216,7 +216,7 @@ See also variable `vc-cvs-sticky-date-fo
 
 (defun vc-cvs-state (file)
   "CVS-specific version of `vc-state'."
-  (if (vc-stay-local-p file)
+  (if (vc-stay-local-p file 'CVS)
       (let ((state (vc-file-getprop file 'vc-state)))
         ;; If we should stay local, use the heuristic but only if
         ;; we don't have a more precise state already available.
@@ -496,7 +496,7 @@ Will fail unless you have administrative
   ;; It's just the catenation of the individual logs.
   (vc-cvs-command
    buffer
-   (if (vc-stay-local-p files) 'async 0)
+   (if (vc-stay-local-p files 'CVS) 'async 0)
    files "log"))
 
 (defun vc-cvs-comment-history (file)
@@ -506,7 +506,7 @@ Will fail unless you have administrative
 (defun vc-cvs-diff (files &optional oldvers newvers buffer)
   "Get a difference report using CVS between two revisions of FILE."
   (let* ((async (and (not vc-disable-async-diff)
-		     (vc-stay-local-p files)))
+		     (vc-stay-local-p files 'CVS)))
 	 (invoke-cvs-diff-list nil)
 	 status)
     ;; Look through the file list and see if any files have backups
@@ -559,7 +559,7 @@ Will fail unless you have administrative
   "Execute \"cvs annotate\" on FILE, inserting the contents in BUFFER.
 Optional arg REVISION is a revision to annotate from."
   (vc-cvs-command buffer
-                  (if (vc-stay-local-p file)
+                  (if (vc-stay-local-p file 'CVS)
 		      'async 0)
                   file "annotate"
                   (if revision (concat "-r" revision)))
@@ -681,8 +681,9 @@ If UPDATE is non-nil, then update (resyn
 ;;; Miscellaneous
 ;;;
 
-(defalias 'vc-cvs-make-version-backups-p 'vc-stay-local-p
-  "Return non-nil if version backups should be made for FILE.")
+(defun vc-cvs-make-version-backups-p (file)
+  "Return non-nil if version backups should be made for FILE."
+  (vc-stay-local-p file 'CVS))
 
 (defun vc-cvs-check-headers ()
   "Check if the current file has any headers in it."
@@ -706,7 +707,8 @@ and that it passes `vc-cvs-global-switch
            (append vc-cvs-global-switches
                    flags))))
 
-(defalias 'vc-cvs-stay-local-p 'vc-stay-local-p)  ;Back-compatibility.
+(defun vc-cvs-stay-local-p (file)
+  (vc-stay-local-p file 'CVS))
 
 (defun vc-cvs-repository-hostname (dirname)
   "Hostname of the CVS server associated to workarea DIRNAME."
@@ -965,7 +967,7 @@ state."
 (defun vc-cvs-dir-status (dir update-function)
   "Create a list of conses (file . state) for DIR."
   ;; FIXME check all files in DIR instead?
-  (let ((local (vc-stay-local-p dir)))
+  (let ((local (vc-stay-local-p dir 'CVS)))
     (if (and local (not (eq local 'only-file)))
 	(vc-cvs-dir-status-heuristic dir update-function)
       (vc-cvs-command (current-buffer) 'async dir "-f" "status")
Index: vc-hooks.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-hooks.el,v
retrieving revision 1.277
diff -u -3 -p -r1.277 vc-hooks.el
--- vc-hooks.el	1 Apr 2009 15:42:12 -0000	1.277
+++ vc-hooks.el	13 Apr 2009 16:43:24 -0000
@@ -168,15 +168,15 @@ by these regular expressions."
   :version "23.1"
   :group 'vc)
 
-(defun vc-stay-local-p (file)
+(defun vc-stay-local-p (file &optional backend)
   "Return non-nil if VC should stay local when handling FILE.
 This uses the `repository-hostname' backend operation.
 If FILE is a list of files, return non-nil if any of them
 individually should stay local."
   (if (listp file)
-      (delq nil (mapcar 'vc-stay-local-p file))
-    (let* ((backend (vc-backend file))
-	   (sym (vc-make-backend-sym backend 'stay-local))
+      (delq nil (mapcar (lambda (arg) (vc-stay-local-p arg backend)) file))
+    (setq backend (or backend (vc-backend file)))
+    (let* ((sym (vc-make-backend-sym backend 'stay-local))
 	   (stay-local (if (boundp sym) (symbol-value sym) vc-stay-local)))
       (if (symbolp stay-local) stay-local
 	(let ((dirname (if (file-directory-p file)
Index: vc-svn.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/vc-svn.el,v
retrieving revision 1.112
diff -u -3 -p -r1.112 vc-svn.el
--- vc-svn.el	10 Feb 2009 05:59:14 -0000	1.112
+++ vc-svn.el	13 Apr 2009 16:43:25 -0000
@@ -142,7 +142,7 @@ want to force an empty list of arguments
 
 (defun vc-svn-state (file &optional localp)
   "SVN-specific version of `vc-state'."
-  (setq localp (or localp (vc-stay-local-p file)))
+  (setq localp (or localp (vc-stay-local-p file 'SVN)))
   (with-temp-buffer
     (cd (file-name-directory file))
     (vc-svn-command t 0 file "status" (if localp "-v" "-u"))
@@ -176,7 +176,7 @@ want to force an empty list of arguments
 	     ;; FIXME are there other possible combinations?
 	     (cond ((eq state 'edited) (setq state 'needs-merge))
 		   ((not state) (setq state 'needs-update))))
-       (when state
+       (when (and state (not (string= "." filename)))
          (setq result (cons (list filename state) result)))))
     (funcall callback result)))
 
@@ -189,7 +189,7 @@ RESULT is a list of conses (FILE . STATE
   ;; calling synchronously (vc-svn-registered DIR) => calling svn status -v DIR
   ;; which is VERY SLOW for big trees and it makes emacs
   ;; completely unresponsive during that time.
-  (let* ((local (and nil (vc-stay-local-p dir)))
+  (let* ((local (and nil (vc-stay-local-p dir 'SVN)))
 	 (remote (or t (not local) (eq local 'only-file))))
     (vc-svn-command (current-buffer) 'async nil "status"
 		    (if remote "-u"))
@@ -470,7 +470,7 @@ or svn+ssh://."
 		  (vc-svn-command
 		   buffer
 		   'async
-		   ;; (if (and (= (length files) 1) (vc-stay-local-p file)) 'async 0)
+		   ;; (if (and (= (length files) 1) (vc-stay-local-p file 'SVN)) 'async 0)
 		   (list file)
 		   "log"
 		   ;; By default Subversion only shows the log up to the
@@ -502,7 +502,7 @@ or svn+ssh://."
 	      (list "--diff-cmd=diff" "-x"
 		    (mapconcat 'identity (vc-switches nil 'diff) " "))))
 	   (async (and (not vc-disable-async-diff)
-                       (vc-stay-local-p files)
+                       (vc-stay-local-p files 'SVN)
 		       (or oldvers newvers)))) ; Svn diffs those locally.
       (apply 'vc-svn-command buffer
 	     (if async 'async 0)
@@ -543,8 +543,9 @@ NAME is assumed to be a URL."
 ;;;
 
 ;; Subversion makes backups for us, so don't bother.
-;; (defalias 'vc-svn-make-version-backups-p 'vc-stay-local-p
-;;   "Return non-nil if version backups should be made for FILE.")
+;; (defun vc-svn-make-version-backups-p (file)
+;;   "Return non-nil if version backups should be made for FILE."
+;;  (vc-stay-local-p file 'SVN))
 
 (defun vc-svn-check-headers ()
   "Check if the current file has any headers in it."