Subject: Re: bug#5298: file VC state not updated after a directory check in

From: Dan Nicolaescu <[email-masked]>
Date: Mon, 4 Jan 2010 18:55:34 -0800 (PST)

Dan Nicolaescu <[email-masked]> writes:

  > mkdir /tmp/test
  > cd /tmp/test
  > bzr init
  > echo blah > foo
  > bzr add foo
  > 
  > emacs -Q 
  > C-x C-f /tmp/test/foo RET
  > C-x v d /tmp/test RET
  > 
  > Move point to "./" 
  > 
  > C-x v v
  > write something in the log-edit buffer.  
  > C-c C-c
  > 
  > now see that in the *vc-dir* the state for "foo" has changed to `up-to-date'
  > 
  > but the mode-line for the "foo" buffer does not show that the buffer is
  > up to date.
  > (vc-state "/tmp/test/foo") returns `added'.
  > 
  > The buffer content has been reverted as expected (this can be verified
  > by using a VCS that does keyword expansion and adding a "$Id$" in
  > "foo").
  > 
  > If the point is on the "foo" line instead of "./" everything works as
  > expected, the VC state is updated.  The problem only happens when
  > checking in directories.
  > 
  > "bzr" is just used as an example above, the problem happens with all VC backends.

This can be solved by extending `with-vc-properties' to actually do
something when passed a directory argument: apply the properties to all
buffers in that directory.

Stefan, WDYT?

--- vc.el.~1.746.~	2009-12-07 03:49:17.000000000 -0800
+++ vc.el	2010-01-04 18:51:46.000000000 -0800
@@ -791,13 +791,23 @@ in their implementation of vc-BACKEND-di
 
 (defmacro with-vc-properties (files form settings)
   "Execute FORM, then maybe set per-file properties for FILES.
+If any of FILES is actually a directory, then do the same for all
+buffers for files in that directory.
 SETTINGS is an association list of property/value pairs.  After
 executing FORM, set those properties from SETTINGS that have not yet
 been updated to their corresponding values."
   (declare (debug t))
-  `(let ((vc-touched-properties (list t)))
-     ,form
+  `(let ((vc-touched-properties (list t))
+	 (flist nil))
      (dolist (file ,files)
+       (if (file-directory-p file)
+	   (dolist (buffer (buffer-list))
+	     (let ((fname (buffer-file-name buffer)))
+	       (when (and fname (vc-string-prefix-p file fname))
+		 (push fname flist))))
+	 (push file flist)))
+     ,form
+     (dolist (file flist)
        (dolist (setting ,settings)
          (let ((property (car setting)))
            (unless (memq property vc-touched-properties)