If some code tries to query ignored or clean files without first
calling the explicit status() method to query them, it will raise
an exception (indicating a software bug).
workingctx.clean() and memctx.clean() have both been returning ignored files
since their creation. This patch fixes clean() while introducing a method for
querying ignored files. The new status() method can be used to explicitly
override the default (fast) arguments used by the _status property.
This bug happens if the filesystem doesn't support exec-bit, during merges,
for example in 0b01431fee25 on the hg repo.
If f is not in p1, but is in p2 and has the x-bit in p2, since the dirstate is
based on p1, and the FS doesn't support the exec-bit, the dirstate can't
"guess" the right bit.
We instead fix it in workingcontext.flags()/manifest.
On some large repos, copy detection could spend > 10min using
fctx.ancestor() to determine if file revisions were actually related.
Because ancestor must traverse history to the root to determine the
GCA, it was doing a lot more work than necessary. With this
replacement, same status -r a:b takes ~3 seconds.
When there are no renames involved, we shortcut to the changeset
ancestor. This resolves most cases.
Note that Mercurial's rename philosophy elsewhere is that a file's
name is signficant and rename data is only consulted when a file of
the same name is absent.
This allows extensions that modify changeset metadata (e.g.
description) by overriding methods of changectx to get consistent
behavior from all log-like commands, regardless of whether templates
or styles are used. Without this, overriding changectx methods works
if you use styles or templates, but not with default log format.
This meant adding filectx.extra() for consistency with changectx.
workingfilectx() was using the "src" filelog in case the file was renamed in
the working copy.
For consistency, stop special-casing it. This allows us to remove some
duplication between filectx and workingfilectx.
The built-in None object is a singleton and it is therefore safe to
compare memory addresses with is. It is also faster, how much depends
on the object being compared. For a simple type like str I get:
| s = "foo" | s = None
----------+-----------+----------
s == None | 0.25 usec | 0.21 usec
s is None | 0.17 usec | 0.17 usec