Commit Graph

682 Commits

Author SHA1 Message Date
Gregory Szorc
ab7f7f6a19 changelog: lazy decode user (API)
This appears to show a similar speedup as the previous patch.
2016-02-27 22:34:18 -08:00
Gregory Szorc
6f651cb96b changelog: lazy decode description (API)
Currently, changelog reading decodes read values. This is wasteful
because a lot of times consumers aren't interested in some of these
values.

This patch changes description decoding to occur in changectx as
needed.

revsets reading changelog entries appear to speed up slightly:

revset #7: author(lmoscovicz)
   plain
0) 0.906329
1) 0.872653

revset #8: author(mpm)
   plain
0) 0.903478
1) 0.878037

revset #9: author(lmoscovicz) or author(mpm)
   plain
0) 1.817855
1) 1.778680

revset #10: author(mpm) or author(lmoscovicz)
   plain
0) 1.837052
1) 1.764568
2016-02-27 22:25:14 -08:00
Durham Goode
a6b3658fd5 filectx: replace use of _filerev with _filenode
_filerev depends on the filelog implementation using revlogs and linkrevs.
Alternative implementations, like remotefilelog, do not have rev numbers, so
this call fails. Replacing it with _filenode means it doesn't rely on rev
numbers, and doesn't cost anything extra, since _filerev is using _filenode
under the hood anyway.
2016-02-08 14:17:11 -08:00
Martin von Zweigbergk
c84bb33a89 match: rename "narrowmatcher" to "subdirmatcher" (API)
I keep mistaking "narrowmatcher" for narrowhg's
narrowmatcher. "subdirmatcher" seems more to the point anyway.
2016-02-05 21:09:32 -08:00
Durham Goode
0660375798 memctx: fix memctx manifest file hashes
When memctx is asked for a manifest, it constructs one by merging the p1
manifest, and the changes that are on top. For the changes on top, it was
previously using p1.node() as the file entries parent, which actually returns
the commit node that the p1 linkrev points at! Which is entirely incorrect.

The fix is to use p1.filenode() instead, which returns the parent file node as
desired.

I don't know how to execute this or make it have a visible effect, so I'm not
sure how to test it.  It was noticed because asking for the linkrev is an
expensive operation when using the remotefilelog extension and this was causing
performance regressions with commit.
2016-02-03 17:44:11 -08:00
Martin von Zweigbergk
c04f1844f0 context: back out sneaky code change in documentation change
In a4119550f1e1 (context: clarify why we don't compare file contents
when nodeid differs, 2016-01-12), I also changed "node2 != _newnode"
into "self.rev() is not None". I don't remember why. They are similar,
but the former also catches the case where the file is clean in the
dirstate (so node2 is not _newnode), but different from the "other"
context. This resulted in unnecessary file content comparison a few
lines further down in the code. Let's just back out the code change.

Thanks to Durham Goode for spotting this.
2016-01-25 15:48:35 -08:00
Gregory Szorc
fbab5f0c4c context: don't use util.cachefunc due to cycle creation (issue5043)
util.cachefunc stores all arguments as the cache key. For filectxfn
functions, the arguments include the memctx instance. This creates a
cycle where memctx._filectxfn references self. This causes a memory
leak.

We break the cycle by implementing our own memoizing function that
only uses the path as the cache key. Since each memctx has its own
cache instance, there is no concern about invalid cache hits.
2016-01-17 12:10:30 -08:00
Bryan O'Sullivan
dc202a7844 with: use context manager for wlock in checklookup 2016-01-15 13:14:46 -08:00
Bryan O'Sullivan
c12335032a with: use context manager for wlock in copy 2016-01-15 13:14:46 -08:00
Bryan O'Sullivan
0d3b3841ab with: use context manager for wlock in workingctx.undelete 2016-01-15 13:14:46 -08:00
Bryan O'Sullivan
e93769dccc with: use context manager for wlock in workingctx.forget 2016-01-15 13:14:46 -08:00
Bryan O'Sullivan
521cb71d13 with: use context manager for wlock in workingctx.add 2016-01-15 13:14:46 -08:00
Martin von Zweigbergk
9df2a9ac77 context: check for differing flags a little earlier
This makes it clearer that a unchanged file whose flags have changed
will be reported as a modification. Also test this.
2016-01-12 13:10:31 -08:00
Martin von Zweigbergk
a5a17ed71f context: clarify why we don't compare file contents when nodeid differs
See previous commit for timing information.
2016-01-12 13:09:54 -08:00
Martin von Zweigbergk
a883bc954a status: back out changeset 7e679fd51132
This backs out 7e679fd51132 (status: change + back out == clean (API),
2016-01-04). Although correct, it turned out that it was just too
slow. For example, 'hg status --rev .~1000 --rev .' on the Mozilla
repo went from <1s to >30s on cold disk. So we go back to reporting
reverted changes as modified instead of clean. These are rare anyway,
as suggested by the fact that it had been broken since before
Mercurial 2.0.
2016-01-12 12:43:36 -08:00
Martin von Zweigbergk
452bda4582 status: change + back out == clean (API)
After backing out a change, so the file contents is equal to a
previous revision of itself, we currently report the status between
the two equal revisions as modified. This is because
context._buildstatus() reports any file whose new nodeid is not equal
to _newnode as modified. That magic nodeid is given only to files
added or modified in the working directory, so any file whose nodeid
has changed between two revisions will be reported as modified.

Fix by simply comparing the file contents for all cases where the
nodeid changed, whether they are in the working copy or committed.

Marking with (API) as it subtly changes the semantics of the method.
2016-01-04 10:13:29 -08:00
Martin von Zweigbergk
aba61f81ad status: revert + flag-change == modified
After just changing the flag on a file, plain 'hg status' will report
the file as modified. However, after reverting a file to a previous
revision's state and changing the flag, it will be reported as clean.

Fix by comparing the flags that were previously ignored in
context._buildstatus().
2016-01-04 09:44:58 -08:00
timeless
ebb1d48658 cleanup: remove superfluous space after space after equals (python) 2015-12-31 08:16:59 +00:00
Gregory Szorc
a12b0c85e9 context: use absolute_import 2015-12-21 21:51:31 -08:00
Pierre-Yves David
756a483011 context: use a the nofsauditor when matching file in history (issue4749)
Before this change, asking for file from history (eg: 'hg cat -r 42 foo/bar')
could fail because of the current content of the working copy (eg: current
"foo" being a symlink). As the working copy state have no influence on the
content of the history, we can safely skip these checks.

The working copy context class have a different 'match'
implementation. That implementation still use the repo.auditor will
still catch symlink traversal.

I've audited all stuff calling "match" and they all go through a ctx
in a sensible way. The most unclear case was diff which still seemed
okay. You raised my paranoid level today and I double checked through
tests. They behave properly.

The odds of someone using the wrong (matching with a changectx for
operation that will eventually touch the file system) is non-zero
because you are never sure of what people will do. But I dunno if we
can fight against that. So I would not commit to "never" for "at this
level" and "in the future" if someone write especially bad code.

However, as a last defense, the vfs itself is running path auditor in
all cases outside of .hg/. So I think anything passing the 'matcher'
for buggy reason would growl at the vfs layer.
2015-12-03 13:23:46 -08:00
Andrew Zwicky
2b7b071ce1 extdiff: correctly handle deleted subrepositories (issue3153)
Previously, when extdiff was called on two changesets where
a subrepository had been removed, an unexpected KeyError would
be raised.

Now, the missing subrepository will be ignored.  This behavior
mirrors the behavior in diffordiffstat from cmdutil.py line
~1138-1153.  The KeyError is caught and the revision is
set to None.

try/catch of LookupError around matchmod.narrowmatcher and
sub.status is removed, as LookupError is not raised anywhere
within those methods or deeper calls.
2015-11-17 16:42:52 -06:00
Gregory Szorc
79473d891d context: avoid extra parents lookups
Resolving parents requires reading from the changelog, which is a few
attributes and function calls away. Parents lookup occurs surprisingly
often. Micro optimizing the code to avoid redundant lookups of parents
appears to make `hg log` on my Firefox repo a little faster:

before: 24.91s
after:  23.76s
delta:  -1.15s (95.4% of original)
2015-11-21 19:21:01 -08:00
Gregory Szorc
b65e310257 context: optimize _parents()
This patch avoids some extra attribute lookups and list mutations.

This micro-optimization seems to result in a minor speedup for `hg log`
on my Firefox repo:

before: 25.35s
after:  24.91s
delta:  -0.44s (98% of original)

Not the biggest gain. But every little bit helps.
2015-11-21 19:04:12 -08:00
Matt Mackall
ab46ec3b99 util: drop statmtimesec
We've globablly forced stat to return integer times which agrees with
our extension code, so this is no longer needed.

This speeds up status on mozilla-central substantially:

$ hg perfstatus
! wall 0.190179 comb 0.180000 user 0.120000 sys 0.060000 (best of 53)
$ hg perfstatus
! wall 0.275729 comb 0.270000 user 0.210000 sys 0.060000 (best of 36)
2015-11-19 13:15:17 -06:00
Siddharth Agarwal
8529661292 filectx: add isabsent method
This will indicate whether this filectx represents a file that is *not* in a
changectx. This will be used by merge and filemerge code to know about when a
conflict is a change/delete conflict.

While this is kind of hacky, it is the least bad of all the alternatives. Other
options considered but rejected include:
- isinstance(fctx, ...) -- not very Pythonic, doesn't support duck typing
- fctx.size() is None -- the 'size()' call on workingfilectxes causes a disk stat
- fctx.filenode() == nullid -- the semantics around filenode are incredibly
  confusing. In particular, for workingfilectxes, filenode() is always None no
  matter whether the file is present on disk or in either parent. Having different
  behavior for None versus nullid in the merge code is just asking for pain.

Thanks to Pierre-Yves David for early review feedback here.
2015-11-16 11:27:27 -08:00
Siddharth Agarwal
6a83f7850c filectx: allow custom comparators
We're going to introduce other sorts of filectxes very soon, and we'd like the
cmp method to function properly (i.e. commutatively) for them. The only way to
make that happen is for this cmp method to call into that specialized one if
that defines a custom comparator.
2015-11-13 22:37:51 -08:00
FUJIWARA Katsunori
106983607a dirstate: make dirstate.write() callers pass transaction object to it
Now, 'dirstate.write(tr)' delays writing in-memory changes out, if a
transaction is running.

This may cause treating this revision as "the first bad one" at
bisecting in some cases using external hook process inside transaction
scope, because some external hooks and editor process are still
invoked without HG_PENDING and pending changes aren't visible to them.

'dirstate.write()' callers below in localrepo.py explicitly use 'None'
as 'tr', because they can assume that no transaction is running:

  - just before starting transaction
  - at closing transaction, or
  - at unlocking wlock
2015-10-17 01:15:34 +09:00
Mads Kiilerich
90c21b3c76 context: don't hex encode all unknown 20 char revision specs (issue4890)
af5de4d23fd4 introduced nice hexified display of missing nodes. It did however
also make missing 20 character revision specifications be shown as hex - very
confusing.

Users are often wrong and somehow specify revisions that don't exist. Nodes
will however rarely be missing ... and they will only look like a user provided
revision specification and be all ascii in 1 of 4*10**9.

With this change, missing revisions will only be hexified if they really look
like binary nodes. This change will thus improve the error reporting UI in the
common case and only very rarely make it confusing in the opposite direction of
how it was before.
2015-10-09 01:19:37 +02:00
Pierre-Yves David
30913031d4 error: get Abort from 'error' instead of 'util'
The home of 'Abort' is 'error' not 'util' however, a lot of code seems to be
confused about that and gives all the credit to 'util' instead of the
hardworking 'error'. In a spirit of equity, we break the cycle of injustice and
give back to 'error' the respect it deserves. And screw that 'util' poser.

For great justice.
2015-10-08 12:55:45 -07:00
Yuya Nishihara
ea5724ad42 util: extract stub function to get mtime with second accuracy
This function is trivial but will need a long comment why it can't use
st.st_mtime. See the next patch for details.
2015-10-04 22:25:29 +09:00
Matt Mackall
1f2f7de9a3 merge: make merge.preferancestor type and default consistent
(and mark it)
2015-06-25 17:54:55 -05:00
FUJIWARA Katsunori
1dcc27a649 context: write dirstate out explicitly at the end of markcommitted
To detect change of a file without redundant comparison of file
content, dirstate recognizes a file as certainly clean, if:

  (1) it is already known as "normal",
  (2) dirstate entry for it has valid (= not "-1") timestamp, and
  (3) mode, size and timestamp of it on the filesystem are as same as
      ones expected in dirstate

This works as expected in many cases, but doesn't in the corner case
that changing a file keeps mode, size and timestamp of it on the
filesystem.

The timetable below shows steps in one of typical such situations:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
   *                                             ***    ***
       - 'hg transplant REV1 REV2 ...'
         - transplanting REV1
           ....
   N
           - change "f", but keep size                   N
             (via 'patch.patch()')
           - 'dirstate.normal("f")'          N   ***
             (via 'repo.commit()')

         - transplanting REV2
           - change "f", but keep size                   N
             (via 'patch.patch()')
           - aborted while patching
  N+1
         - release wlock
           - 'dirstate.write()'              N    N      N

       - 'hg status' shows "r1" as "clean"   N    N      N
  ---- ----------------------------------- ---- ----- -----

The most important point is that 'dirstate.write()' is executed at N+1
or later. This causes writing dirstate timestamp N of "f" out
successfully. If it is executed at N, 'parsers.pack_dirstate()'
replaces timestamp N with "-1" before actual writing dirstate out.

This issue can occur when 'hg transplant' satisfies conditions below:

  - multiple revisions to be transplanted change the same file
  - those revisions don't change mode and size of the file, and
  - the 2nd or later revision of them fails after changing the file

The root cause of this issue is that files are changed without
flushing in-memory dirstate changes via 'repo.commit()' (even though
omitting 'dirstate.normallookup()' on files changed by 'patch.patch()'
for efficiency also causes this issue).

To detect changes of files correctly, this patch writes in-memory
dirstate changes out explicitly after marking files as clean in
'committablectx.markcommitted()', which is invoked via
'repo.commit()'.

After this change, timetable is changed as below:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
   *                                             ***    ***
       - 'hg transplant REV1 REV2 ...'
         - transplanting REV1
           ....
   N
           - change "f", but keep size                   N
             (via 'patch.patch()')
           - 'dirstate.normal("f")'          N    ***
             (via 'repo.commit()')
       ----------------------------------- ---- ----- -----
           - 'dirsttate.write()'            -1    -1
       ----------------------------------- ---- ----- -----
         - transplanting REV2
           - change "f", but keep size                   N
             (via 'patch.patch()')
           - aborted while patching
  N+1
         - release wlock
           - 'dirstate.write()'              -1   -1     N

       - 'hg status' shows "r1" as "clean"   -1   -1     N
  ---- ----------------------------------- ---- ----- -----

To reproduce this issue in tests certainly, this patch emulates some
timing critical actions as below:

  - change "f" at N

    'patch.patch()' with 'fakepatchtime.py' explicitly changes mtime
    of patched files to "2000-01-01 00:00" (= N).

  - 'dirstate.write()' via 'repo.commit()' at N

    'fakedirstatewritetime.py' forces 'pack_dirstate()' to use
    "2000-01-01 00:00" as "now", only if 'pack_dirstate()' is invoked
    via 'committablectx.markcommitted()'.

  - 'dirstate.write()' via releasing wlock at N+1 (or "not at N")

    'pack_dirstate()' via releasing wlock uses actual timestamp at
    runtime as "now", and it should be different from the "2000-01-01
    00:00" of "f".

BTW, this patch doesn't test cases below, even though 'patch.patch()'
is used similarly in these cases:

  1. failure of 'hg import' or 'hg qpush'

  2. success of 'hg import', 'hg qpush' or 'hg transplant'

Case (1) above doesn't cause this kind of issue, because:

  - if patching is aborted by conflicts, changed files are committed

    changed files are marked as CLEAN, even though they are partially
    patched.

  - otherwise, dirstate are fully restored by 'dirstateguard'

    For example in timetable above, timestamp of "f" in .hg/dirstate
    is restored to -1 (or less than N), and subsequent 'hg status' can
    detect changes correctly.

Case (2) always causes 'repo.status()' invocation via 'repo.commit()'
just after changing files inside same wlock scope.

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              ***   ***
       - make file "f" clean                            N

       - execute 'hg foobar'
         ....
         - 'dirstate.normal("f")'           N    ***
           (e.g. via dirty check
            or previous 'repo.commit()')

         - change "f", but keep size                    N
         - 'repo.status()' (*1)
           (via 'repo.commit()')
  ---- ----------------------------------- ---- ----- -----

At a glance, 'repo.status()' at (*1) seems to cause similar issue (=
"changed files are treated as clean"), but actually doesn't.

'dirstate._lastnormaltime' should be N at (*1) above, because
'dirstate.normal()' via dirty check is finished at N.

Therefore, "f" changed at N (= 'dirstate._lastnormaltime') is forcibly
treated as "unsure" at (*1), and changes are detected as expected (see
'dirstate.status()' for detail).

If 'hg import' is executed with '--no-commit', 'repo.status()' isn't
invoked just after changing files inside same wlock scope.

But preceding 'dirstate.normal()' is invoked inside another wlock
scope via 'cmdutil.bailifchanged()', and in-memory changes should be
flushed at the end of that scope.

Therefore, timestamp N of clean "f" should be replaced by -1, if
'dirstate.write()' is invoked at N. It means that condition of this
issue isn't satisfied.
2015-07-08 17:01:09 +09:00
FUJIWARA Katsunori
51754ba82b context: write dirstate out explicitly after marking files as clean
To detect change of a file without redundant comparison of file
content, dirstate recognizes a file as certainly clean, if:

  (1) it is already known as "normal",
  (2) dirstate entry for it has valid (= not "-1") timestamp, and
  (3) mode, size and timestamp of it on the filesystem are as same as
      ones expected in dirstate

This works as expected in many cases, but doesn't in the corner case
that changing a file keeps mode, size and timestamp of it on the
filesystem.

The timetable below shows steps in one of typical such situations:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              -1    ***
       - make file "f" clean                            N

       - execute 'hg foobar'
         - instantiate 'dirstate'           -1   -1
         - 'dirstate.normal("f")'           N    -1
           (e.g. via dirty check)
         - change "f", but keep size                    N
  N+1
         - release wlock
           - 'dirstate.write()'             N    N

       - 'hg status' shows "f" as "clean"   N    N      N
  ---- ----------------------------------- ---- ----- -----

The most important point is that 'dirstate.write()' is executed at N+1
or later. This causes writing dirstate timestamp N of "f" out
successfully. If it is executed at N, 'parsers.pack_dirstate()'
replaces timestamp N with "-1" before actual writing dirstate out.

Occasional test failure for unexpected file status is typical example
of this corner case. Batch execution with small working directory is
finished in no time, and rarely satisfies condition (2) above.

This issue can occur in cases below;

  - 'hg revert --rev REV' for revisions other than the parent
  - failure of 'merge.update()' before 'merge.recordupdates()'

The root cause of this issue is that files are changed without
flushing in-memory dirstate changes via 'repo.commit()' (even though
omitting 'dirstate.normallookup()' on changed files also causes this
issue).

To detect changes of files correctly, this patch writes in-memory
dirstate changes out explicitly after marking files as clean in
'workingctx._checklookup()', which is invoked via 'repo.status()'.

After this change, timetable is changed as below:

  ---- ----------------------------------- ----------------
                                           timestamp of "f"
                                           ----------------
                                           dirstate   file-
  time          action                     mem  file  system
  ---- ----------------------------------- ---- ----- -----
  N                                              -1    ***
       - make file "f" clean                            N

       - execute 'hg foobar'
         - instantiate 'dirstate'           -1   -1
         - 'dirstate.normal("f")'           N    -1
           (e.g. via dirty check)
       ----------------------------------- ---- ----- -----
         - 'dirsttate.write()'              -1   -1
       ----------------------------------- ---- ----- -----
         - change "f", but keep size                    N
  N+1
         - release wlock
           - 'dirstate.write()'             -1   -1

       - 'hg status'                        -1   -1      N
  ---- ----------------------------------- ---- ----- -----

To reproduce this issue in tests certainly, this patch emulates some
timing critical actions as below:

  - timestamp of "f" in '.hg/dirstate' is -1 at the beginning

    'hg debugrebuildstate' before command invocation ensures it.

  - make file "f" clean at N
  - change "f" at N

    'touch -t 200001010000' before and after command invocation
    changes mtime of "f" to "2000-01-01 00:00" (= N).

  - invoke 'dirstate.write()' via 'repo.status()' at N

    'fakedirstatewritetime.py' forces 'pack_dirstate()' to use
    "2000-01-01 00:00" as "now", only if 'pack_dirstate()' is invoked
    via 'workingctx._checklookup()'.

  - invoke 'dirstate.write()' via releasing wlock at N+1 (or "not at N")

    'pack_dirstate()' via releasing wlock uses actual timestamp at
    runtime as "now", and it should be different from the "2000-01-01
    00:00" of "f".

BTW, this patch also changes 'test-largefiles-misc.t', because adding
'dirstate.write()' makes recent dirstate changes visible to external
process.
2015-07-08 17:01:09 +09:00
Yuya Nishihara
0340e6a83e workingctx: use node.wdirid constant 2015-06-22 22:05:10 +09:00
Matt Harbison
9f8b7aa09e workingctx: don't report the tags for its parents
This fixes the bad distance calculation for '{latesttagdistance}' mentioned in
the previous patch.
2015-06-28 13:38:03 -04:00
Gregory Szorc
5380dea2a7 global: mass rewrite to use modern exception syntax
Python 2.6 introduced the "except type as instance" syntax, replacing
the "except type, instance" syntax that came before. Python 3 dropped
support for the latter syntax. Since we no longer support Python 2.4 or
2.5, we have no need to continue supporting the "except type, instance".

This patch mass rewrites the exception syntax to be Python 2.6+ and
Python 3 compatible.

This patch was produced by running `2to3 -f except -w -n .`.
2015-06-23 22:20:08 -07:00
Matt Harbison
ba46b0e533 subrepo: allow a representation of the working directory subrepo
Some code cannot handle a subrepo based on the working directory (e.g.
sub.dirty()), so the caller must opt in.  This will be useful for archive, and
perhaps some other commands.  The git and svn methods where this is used may
need to be fixed up on a case by case basis.
2015-06-16 23:03:36 -04:00
Matt Harbison
a1b56b9f59 context: override workingctx.hex() to avoid a crash
Since node is None for workingctx, it can't use the base class
implementation of 'hex(self.node())'.

It doesn't appear that there are any current callers of this, but there will be
when archive supports 'wdir()'.  My first thought was to use "{p1node}+", but
that would cause headaches elsewhere [1].

We should probably fix up localrepository.__getitem__ to accept this hash for
consistency, as a followup.  This works, if the full hash is specified:

  @@ -480,7 +480,7 @@
           return dirstate.dirstate(self.vfs, self.ui, self.root, validate)

       def __getitem__(self, changeid):
  -        if changeid is None:
  +        if changeid is None or changeid == 'ff' * 20:
               return context.workingctx(self)
           if isinstance(changeid, slice):
               return [context.changectx(self, i)

That differs from null, where it will accept any number of 0s, as long as it
isn't ambiguous.


[1] https://www.selenic.com/pipermail/mercurial-devel/2015-June/071166.html
2015-06-14 22:04:17 -04:00
Matt Harbison
f758dd3fee context: add an optional constructor parameter for a match.bad() override
Most matcher creation is done by way of a context.
2015-06-05 19:01:04 -04:00
Matt Harbison
5159a795ed context: replace match.bad() monkey patching with match.badmatch()
No known issues with the previous code since it restored the original method,
but this is cleaner.
2015-06-04 21:37:59 -04:00
Matt Harbison
23a0164ef3 context: introduce the nullsub() method
Ultimately, this will be used by scmutil.  The subrepo module already imports
it, so it can't import the subrepo module to access the underlying method.
2015-06-03 13:51:27 -04:00
Laurent Charignon
9aa6695e8b patch: add 'extra' argument to makememctx
The uncommit command in evolve needs to create memory context with given
extra parameters. This patch allows us to do that instead of always giving them
an empty value and having to override it afterwards.
2015-05-22 13:06:45 -07:00
Matt Mackall
7e1cf5444c merge with stable 2015-05-19 07:17:57 -05:00
Matt Harbison
dc85d51beb context: don't complain about a matcher's subrepo paths in changectx.walk()
Previously, the first added test printed the following:

  $ hg files -S -r '.^' sub1/sub2/folder
  sub1/sub2/folder: no such file in rev 9bb10eebee29
  sub1/sub2/folder: no such file in rev 9bb10eebee29
  sub1/sub2/folder/test.txt

One warning occured each time a subrepo was crossed into.

The second test ensures that the matcher copy stays in place.  Without the copy,
the bad() function becomes an increasingly longer chain, and no message would be
printed out for a file missing in the subrepo because the predicate would match
in one of the replaced methods.  Manifest doesn't know anything about subrepos,
so it needs help ignoring subrepos when complaining about bad files.
2015-05-17 01:06:10 -04:00
Matt Harbison
9311abf92a match: resolve filesets in subrepos for commands given the '-S' argument
This will work for any command that creates its matcher via scmutil.match(), but
only the files command is tested here (both workingctx and basectx based tests).
The previous behavior was to completely ignore the files in the subrepo, even
though -S was given.

My first attempt was to teach context.walk() to optionally recurse, but once
that was in place and the complete file list was built up, the predicate test
would fail with 'path in nested repo' when a file in a subrepo was accessed
through the parent context.

There are two slightly surprising behaviors with this functionality.  First, any
path provided inside the fileset isn't narrowed when it is passed to the
subrepo.  I dont see any clean way to do that in the matcher.  Fortunately, the
'subrepo()' fileset is the only one to take a path.

The second surprise is that status predicates are resolved against the subrepo,
not the parent like 'hg status -S' is.  I don't see any way to fix that either,
given the path auditor error mentioned above.
2015-05-16 00:36:35 -04:00
Yuya Nishihara
d99ad9e9b8 annotate: always adjust linkrev before walking down to parents (issue4623)
This should avoid the bad performance in the following scenario. Before this
patch, on "hg annotate -r10000", p.rev() would walk changelog from 10000 to 3
because _descendantrev was 10000. With this patch, it walks from 5 to 3.

  1 -- 2 -- 4 -- 5 -- ... -- 10000
    \      'p'  'f'
     - 3   (grafted 3 to 4)
      'p'

repo:    https://hg.mozilla.org/releases/mozilla-beta/#4f80fecda802
command: hg annotate -r b0a57152fd14 browser/app/profile/firefox.js
before:  83.120 secs
after:    3.820 secs

This patch involves extra calls of narrow _adjustlinkrev(), but the cost of
them seems relatively small compared to wide _adjustlinkrev() calls eliminated
by this patch.

repo:    http://selenic.com/repo/hg/#d668bc5b9a06
command: hg annotate mercurial/commands.py
before:  7.380 secs
after:   7.320 secs

repo:    https://hg.mozilla.org/mozilla-central/#f214df6ac75f
command: hg annotate layout/generic/nsTextFrame.cpp
before:  5.070 secs
after:   5.050 secs

repo:    https://hg.mozilla.org/releases/mozilla-beta/#4f80fecda802
command: hg annotate -r 4954faa47dd0 gfx/thebes/gfxWindowsPlatform.cpp
before:  1.600 secs
after:   1.620 secs
2015-04-25 15:38:06 +09:00
Yuya Nishihara
0a37922d8d annotate: prepare ancestry context of workingfilectx
_ancestrycontext is necessary for fast lookup of _changeid. Because we can't
compute the ancestors from wctx, we skip to its parents. 'None' is not needed
to be included in _ancestrycontext because it is used for a membership test
of filelog revisions.

repo:    https://hg.mozilla.org/releases/mozilla-beta/#062e49bcb2da
command: hg annotate -r 'wdir()' gfx/thebes/gfxWindowsPlatform.cpp
before:  51.520 sec
after:    1.780 sec
2015-04-18 15:27:03 +09:00
Yuya Nishihara
5b51ae23c8 committablefilectx: propagate ancestry info to parent to fix annotation
Before this patch, annotating working directory could include wrong revisions
that were hidden or belonged to different branches. This fixes wfctx.parents()
to set _descendantrev so that all ancestors can take advantage of the linkrev
adjustment introduced at a5aaaeedd6cb. _adjustlinkrev() can handle 'None'
revision thanks to bb19d597bbcd.
2015-04-18 14:10:55 +09:00
Yuya Nishihara
d32c454372 filectx: extract function to create parent fctx keeping ancestry info
committablefilectx.parents() should use this to take advantage of the linkrev
adjustment.
2015-04-18 14:03:41 +09:00
Yuya Nishihara
921251cb12 filectx: factor out creation of parent fctx
This series tries to fix wrong ancestry information on annotating working
directory. This change should slightly improves the readability of the next
patch.
2015-04-18 13:46:24 +09:00