[PATCH 2 of 5] localrepo: invoke dirstate.unsureifambig in wwrite for safety

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Wed May 27 12:03:22 CDT 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1432745859 -32400
#      Thu May 28 01:57:39 2015 +0900
# Node ID b82f32b8734b109b84f533dc62dd3f23195d1e0a
# Parent  ab9f120295b59933d1acd72771f01b5fac8d221d
localrepo: invoke dirstate.unsureifambig in wwrite for safety

Modified file may be mis-recognized as clean by dirstate, if mode,
size and timestamp of it on the filesystem aren't changed.

To avoid such ambiguous situation, this patch invokes
`dirstate.unsureifambig()` at the end of `localrepository.wwrite()`.

When file is cleanly reverted or updated, subsequent
`dirstate.lookup()` makes `dirstate.unsureifambig()` a little
redundant. But it is enough cheap for keeping consistency.

diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -927,7 +927,9 @@
             self.wvfs.write(filename, data)
             if 'x' in flags:
                 self.wvfs.setflags(filename, False, True)
-        return len(data)
+        wsize = len(data)
+        self.dirstate.unsureifambig(filename, wsize)
+        return wsize
 
     def wwritedata(self, filename, data):
         return self._filter(self._decodefilterpats, filename, data)
diff --git a/tests/test-merge1.t b/tests/test-merge1.t
--- a/tests/test-merge1.t
+++ b/tests/test-merge1.t
@@ -206,4 +206,60 @@
   $ hg revert -r -2 b
   $ hg up -q -- -2
 
+Test for ambiguity from same size, timestamp and mode
+
+  $ cat > $TESTTMP/abort.py <<EOF
+  > from mercurial import extensions, merge, util
+  > def applyupdates(orig, *args, **kwargs):
+  >     orig(*args, **kwargs)
+  >     # emulate aborting before "recordupdates()"
+  >     # => files are changed without updating dirstate
+  >     raise util.Abort('intentional aborting')
+  > def extsetup(ui):
+  >     extensions.wrapfunction(merge, "applyupdates", applyupdates)
+  > EOF
+
+(file gotten from other revision)
+
+  $ hg update -q -C 2
+  $ echo 'THIS IS FILE B5' > b
+  $ hg commit -m 'commit #5'
+
+  $ hg update -q -C 3
+  $ touch -t 200001010000 b
+  $ hg status -A b
+  C b
+  $ cat b
+  This is file b1
+
+  $ hg --config extensions.abort=$TESTTMP/abort.py merge 5
+  abort: intentional aborting
+  [255]
+  $ touch -t 200001010000 b
+  $ cat b
+  THIS IS FILE B5
+  $ hg status -A b
+  M b
+
+(file merged from other revision)
+
+  $ hg update -q -C 3
+  $ echo 'this is file b6' > b
+  $ hg commit -m 'commit #6'
+  created new head
+  $ touch -t 200001010000 b
+  $ hg status -A b
+  C b
+  $ cat b
+  this is file b6
+
+  $ hg --config extensions.abort=$TESTTMP/abort.py merge --tool internal:other 5
+  abort: intentional aborting
+  [255]
+  $ touch -t 200001010000 b
+  $ cat b
+  THIS IS FILE B5
+  $ hg status -A b
+  M b
+
   $ cd ..


More information about the Mercurial-devel mailing list