[PATCH stable V2] filectx: fix cmp() of file starting with '\1\n'

Yuya Nishihara yuya at tcha.org
Wed Jan 11 09:50:12 CST 2012


# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1326296985 -32400
# Branch stable
# Node ID ffdde907e98c5307b0adbcdf2d97a699b6fff239
# Parent  e4fc0f0b4f7e73f6cbfa132cf09b7027a909d08c
filectx: fix cmp() of file starting with '\1\n'

If file data starts with '\1\n', it will be escaped in the revlog to
create an empty metadata block, thus adding four bytes to the size in
the revlog size index. There's no way to detect that this has happened
in filelog.size() faster than decompressing each revision [1].

For filectx.cmp(), we have the size of the file in the working directory
available. If it differs by exactly four bytes, it may be this case, so
do a full comparison.

 [1]: http://markmail.org/message/5akdbmmqx7vq2fsg

diff --git a/mercurial/context.py b/mercurial/context.py
--- a/mercurial/context.py
+++ b/mercurial/context.py
@@ -368,7 +368,11 @@ class filectx(object):
 
         returns True if different than fctx.
         """
-        if (fctx._filerev is None and self._repo._encodefilterpats
+        if (fctx._filerev is None
+            and (self._repo._encodefilterpats
+                 # if file data starts with '\1\n', empty metadata block is
+                 # prepended, which adds 4 bytes to fielog.size().
+                 or self.size() - 4 == fctx.size())
             or self.size() == fctx.size()):
             return self._filelog.cmp(self._filenode, fctx.data())
 
diff --git a/tests/test-status.t b/tests/test-status.t
--- a/tests/test-status.t
+++ b/tests/test-status.t
@@ -272,3 +272,26 @@ hg status -A --change 1:
     modified
   R removed
   C deleted
+
+  $ cd ..
+
+hg status of binary file starting with '\1\n', a separator for metadata:
+
+  $ hg init repo5
+  $ cd repo5
+  $ printf '\1\nfoo' > 010a
+  $ hg ci -q -A -m 'initial checkin'
+  $ hg status -A
+  C 010a
+
+  $ printf '\1\nbar' > 010a
+  $ hg status -A
+  M 010a
+  $ hg ci -q -m 'modify 010a'
+  $ hg status -A --rev 0:1
+  M 010a
+
+  $ touch empty
+  $ hg ci -q -A -m 'add another file'
+  $ hg status -A --rev 1:2 010a
+  C 010a


More information about the Mercurial-devel mailing list