Spurious 'M' status (was: Re: Mozilla: hg as a collaboration tool)

Alexis S. L. Carvalho alexis at cecm.usp.br
Tue Feb 12 09:56:34 CST 2008


Thus spake Pazu:
> I've run in a situation where two copies of hg in the same machine (native
> win32 and cygwin versions) disagree about modified files. Here's how I can
> reproduce this:

> Then just issue a 'status' using win32 hg:
> 
> C:\users\pazu\tenjin>hg status
> M README
> M Rakefile
> M app\controllers\application.rb
> M app\helpers\application_helper.rb
> M app\models\user.rb
> M config\boot.rb
> [...]
> 
> The same thing happens if I do this the other way around (clone with win32,
> status with cygwin).
> 
> debugstate and manifest seems to agree, using both versions:
> 
> pazu at kombi:~/tenjin$ hg debugstate
> n 644         18 2008-02-12 11:40:40 .hgignore
> n 755       8819 2008-02-12 11:40:40 README
> n 755        307 2008-02-12 11:40:40 Rakefile
> [...]
> 
> C:\users\pazu\tenjin>hg debugstate
> n 644         18 2008-02-12 11:40:40 .hgignore
> n 755       8819 2008-02-12 11:40:40 README
> n 755        307 2008-02-12 11:40:40 Rakefile
> [...]
> 
> pazu at kombi:~/tenjin$ hg manifest --debug
> d13cb68919e096fa9cc1b8674c01a3ed744b232f 644   .hgignore
> a128f3540484a21a1bf13c1a56a8a7e776cf4651 755 * README
> e97feff1b550a1634a19e25639f568bc0b29ee2d 755 * Rakefile
> [...]
> 
> C:\users\pazu\tenjin>hg manifest --debug
> d13cb68919e096fa9cc1b8674c01a3ed744b232f 644   .hgignore
> a128f3540484a21a1bf13c1a56a8a7e776cf4651 755 * README
> e97feff1b550a1634a19e25639f568bc0b29ee2d 755 * Rakefile
> [...]

Are all the affected files supposed to be executable (mode 755 above)?

If so, cygwin is probably doing some trick to simulate unix permissions
that ends up confusing us.

Any chance you can test the following proof-of-concept patch?

diff -r fb259a3572e9 mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -63,6 +63,9 @@ class dirstate(object):
         elif name == '_slash':
             self._slash = self._ui.configbool('ui', 'slash') and os.sep != '/'
             return self._slash
+        elif name == '_checkexec':
+            self._checkexec = util.checkexec(self._root)
+            return self._checkexec
         else:
             raise AttributeError, name
 
@@ -575,8 +578,9 @@ class dirstate(object):
             if type_ == 'n':
                 if not st:
                     st = lstat(_join(fn))
-                if (size >= 0 and (size != st.st_size
-                                   or (mode ^ st.st_mode) & 0100)
+                if (size >= 0 and
+                    (size != st.st_size
+                     or ((mode ^ st.st_mode) & 0100 and self._checkexec))
                     or size == -2
                     or fn in self._copymap):
                     madd(fn)

Alexis


More information about the Mercurial mailing list