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

Matt Mackall mpm at selenic.com
Tue Jan 10 15:14:12 CST 2012


On Wed, 2012-01-11 at 01:46 +0900, Yuya Nishihara wrote:
> # HG changeset patch
> # User Yuya Nishihara <yuya at tcha.org>
> # Date 1326213787 -32400
> # Branch stable
> # Node ID fc9a58eeb4a6d74768fe8a184638e2d247603d3c
> # Parent  e4fc0f0b4f7e73f6cbfa132cf09b7027a909d08c
> filectx: fix cmp() of file starting with '\1\n'
> 
> Because filelog.size() returns size+4 for data starting with '\1\n',
> fctx.cmp(workingfcx) happens to return True wrongly. As the result,
> `hg status` of a file starting with '\1\n' is always M, even if it isn't
> modified.

This took me a while to understand:

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.

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.

> Since there's no cheap way to fix bug of filelog.size() according to [1],
> this patch works around the problem at filectx.cmp().
> 
>  [1]: http://markmail.org/message/5akdbmmqx7vq2fsg
> 
> diff --git a/mercurial/context.py b/mercurial/context.py
> --- a/mercurial/context.py
> +++ b/mercurial/context.py
> @@ -369,7 +369,10 @@ class filectx(object):
>          returns True if different than fctx.
>          """
>          if (fctx._filerev is None and self._repo._encodefilterpats
> -            or self.size() == fctx.size()):
> +            or self.size() == fctx.size()
> +            # filelog.size() may return size+4 if data startswith '\1\n'
> +            or (isinstance(fctx, workingfilectx)
> +                and self.size() - 4 == fctx.size())):

This can be simplified because:

(fctx._filerev is None) == isinstance(fctx, workingfilectx)

-- 
Mathematics is the supreme nostalgia of our time.




More information about the Mercurial-devel mailing list