Commit Graph

30806 Commits

Author SHA1 Message Date
Dr Rainer Woitok
d0ce8b6088 tests: make test suite more immune to environment variables
Plenty of tests break when "make tests" is run while environment
variables "HGPLAIN" or "HGPLAINEXCEPT" are set (test "test-obsolete-
checkheads.t" is just a single example).

This patch causes script "run-tests.py" to also remove these two
variables from the environment the tests are executed in.
2017-02-20 18:27:29 +01:00
Augie Fackler
2370f84a66 version: enable pager if --verbose is specified
`hg version` output is very short without --verbose, but with
--verbose it tends to scroll off the user's screen.
2017-02-06 23:08:49 -05:00
Augie Fackler
fde1794204 tags: enable pager 2017-02-06 23:07:16 -05:00
Augie Fackler
c5a4c5d201 summary: enable pager 2017-02-06 23:06:59 -05:00
Augie Fackler
2d27058975 status: enable pager 2017-02-06 23:06:32 -05:00
Augie Fackler
209ab0d249 resolve: enable pager 2017-02-06 23:06:10 -05:00
Augie Fackler
985790e307 paths: enable pager 2017-02-06 23:06:01 -05:00
Augie Fackler
7b68f2b1da outgoing: enable pager
The structure here is similar to incoming, and requires similar treatment.
2017-02-06 23:04:44 -05:00
Augie Fackler
9d43fd6ddc manifest: enable pager 2017-02-06 23:04:26 -05:00
Augie Fackler
01454df49d locate: enable pager 2017-02-06 23:04:10 -05:00
Augie Fackler
9db50905cf incoming: enable pager
The design of incoming means we have to activate the pager in several
places, depending on which codepath gets chosen.
2017-02-06 23:03:48 -05:00
Augie Fackler
046fd9f790 help: enable pager 2017-02-06 23:09:21 -05:00
Augie Fackler
d2ebbe816e grep: enable pager 2017-02-06 23:09:15 -05:00
Augie Fackler
8163007f6e files: enable pager 2017-02-06 23:02:48 -05:00
Augie Fackler
bc44ae0cf0 config: activate pager if not starting an editor
This demonstrates the power of the non-attend-based pager API.
2017-02-06 23:01:42 -05:00
Augie Fackler
bcf9ea0406 qdiff: migrate to modern pager API
This results in the default pager-attend list being empty. Sadly, we
can't let the code be that way, because some legacy extensions depend
on hooking the pager's attend list at import time (and we'd like to
not break them), and if the list is actually *empty* that triggers
magic behavior in the extension that attends everything. Instead, we
put a long, improbable command name as the only entry in the attend
list.
2017-02-06 23:57:21 -05:00
Augie Fackler
31938f0650 log: migrate to modern pager API 2017-02-06 22:59:25 -05:00
Augie Fackler
776882e795 export: migrate to modern pager API 2017-02-06 22:58:54 -05:00
Augie Fackler
a057b6046c diff: migrate to modern pager API 2017-02-06 22:58:26 -05:00
Augie Fackler
4452f8a320 cat: migrate to modern pager API 2017-02-06 22:57:52 -05:00
Augie Fackler
7488e11fe2 annotate: start pager after we're sure we wont abort
This avoids needlessly putting a short error message into the pager.
2017-02-19 15:09:41 -05:00
Augie Fackler
4357a98af3 dispatch: consolidate pager flag handling to a single place
This makes a little more sense, thanks to Martin for suggesting it.
2017-02-19 20:16:11 -05:00
Augie Fackler
7dca05b0fd ui: rename neverpager to disablepager
I agree this is a clearer name for this method.
2017-02-19 20:12:52 -05:00
Yuya Nishihara
8e1d6228ac scmutil: proxy revrange() through repo to break import cycles
This was one of the hardest import cycles as scmutil is widely used and
revset functions are likely to depend on a variety of modules.

New repo.anyrevs() does not expand user aliases by default to copy the
behavior of the existing repo.revs(). I don't want to add new function to
localrepository, but this function is quite similar to repo.revs() so it
won't increase the complexity of the localrepository class so much.
2017-02-19 20:00:18 +09:00
Yuya Nishihara
b2229f5117 revset: split language services to revsetlang module (API)
New revsetlang module hosts parser, tokenizer, and miscellaneous functions
working on parsed tree. It does not include functions for evaluation such as
getset() and match().

  2288 mercurial/revset.py
   684 mercurial/revsetlang.py
  2972 total

get*() functions are aliased since they are common in revset.py.
2017-02-19 18:19:33 +09:00
Yuya Nishihara
d63d83be69 revset: import set classes directly from smartset module
Follows up 97d0be4019ac.
2017-02-19 18:16:09 +09:00
Yuya Nishihara
f5002345c5 help: add pointer how to narrow list of resolved/unresolved files (issue5469) 2017-02-18 18:00:01 +09:00
liscju
f5ef66440e shelve: add -n/--name option to unshelve (issue5475)
This makes using shelve/unshelve more consistent because
shelving can be done using name option and unshelving as
well. Author of the idea of this improvement and solution is
joshgold.
2017-02-19 10:56:08 +01:00
Jun Wu
8b91946180 smartset: use native set operations as fast paths
For set operations like "&" and "-", where we know both basesets have their
sets ready, and the first set is sorted, use the native Python set
operations as a fast path.

Note: "+" is not optimized as that will break the ordering.

This leads to noticeable improvements on performance:

  revset                                | before | after | delta
  ----------------------------------------------------------------
  draft() & draft() & draft() & draft() |    776 |   477 | -39%
  draft() + draft() + draft() + draft() |   2849 |  2864 |
  draft() - draft() + draft() - draft() |    943 |   240 | -75%
  draft() - draft() - draft() - draft() |    557 |   197 | -64%

  (time measured in microseconds)
2017-02-18 17:23:43 -08:00
Jun Wu
5b7a815bb7 smartset: add some doctests
Add doctests explaining the set / list behavior. This will make the
following changes more confident.
2017-02-18 16:30:07 -08:00
Jun Wu
4a76b6f405 obsolete: avoid using revset language to compute the obsolete revset
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py. See previous patches for the motivation.

Now we have APIs in phasecache to get the non-public set efficiently, let's
use it directly instead of going through the "not public()" revset language
in "obsolete()" computation.

This patch was meaured using:

  for i in 'public()' 'not public()' 'draft()' 'not draft()'; do
      hg perfrevset "$i"; hg perfrevset "$i" --hidden;
  done

and no noticeable (> 1%) performance difference was observed.
2017-02-18 00:55:20 -08:00
Jun Wu
bc5a0cb908 revset: use phasecache.getrevset
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py. See the previous patch for motivation.

This patch changes revset code to use phasecache.getrevset so it no longer
accesses the private field: _phasecache._phasesets directly.

For performance impact, this patch was tested using the following query, on
my hg-committed repo:

    for i in 'public()' 'not public()' 'draft()' 'not draft()'; do
        echo $i;
        hg perfrevset "$i";
        hg perfrevset "$i" --hidden;
    done

For the CPython implementation, most operations are unchanged (within
+/- 1%), while "not public()" and "draft()" is noticeably faster on an
unfiltered repo. It may be because the new code avoids a set copy if
filteredrevs is empty.

  revset  | public()      | not public() | draft()    | not draft()
  hidden  |  yes  |  no   |   yes |  no  | yes |  no  | yes  |  no
  ------------------------------------------------------------------
  before  | 19006 | 17352 |   239 |  286 | 180 |  228 | 7690 | 5745
  after   | 19137 | 17231 |   240 |  207 | 182 |  150 | 7687 | 5658
  delta   |                       | -38% |     | -52% |

  (timed in microseconds)

For the pure Python implementation, some operations are faster while "not
draft()" is noticeably slower:

  revset  | public()      | not public()  | draft()       | not draft()
  hidden  |  yes  |  no   |   yes |  no   | yes   |  no   | yes   |  no
  ------------------------------------------------------------------------
  before  | 18852 | 17183 | 17758 | 15921 | 17505 | 15973 | 41521 | 39822
  after   | 18924 | 17380 | 17558 | 14545 | 16727 | 13593 | 48356 | 43992
  delta   |                       |   -9% |   -5% |  -15% |  +16% |  +10%

That may be the different performance characters of generatorset vs.
filteredset. The "not draft()" query could be optimized in this case where
both "public" and "secret" are passed to "getrevsets" so it won't iterate
the whole repo twice.
2017-02-18 00:39:31 -08:00
Jun Wu
e24ce907e3 phases: add a getrevset method to phasecache
This is part of a refactoring that moves some phase query optimization from
revset.py to phases.py.

The motivation behind this was chg repo preloading - to make the obsstore
depend on less things (like the revset language). The refactoring also looks
good by itself - phasecache does not expose its private field "_phasesets"
via public methods and revset.py is accessing it in a hacky way.

This patch adds a "getrevset" method, which takes multiple phases and
returns a revset in an best-effort efficient way - for "public" phase, it
returns a lazy generatorset; for "draft" and "secret", it returns efficient
"baseset".
2017-02-17 22:49:05 -08:00
Jun Wu
e5340d9f4b smartset: convert set to list lazily
If the caller only wants to construct a baseset via a set, and then do
"__contains__" tests. It's unnecessary to initialize the list.

Testing on my unfiltered hg-committed repo where len(draft()) is 2600, this
patch shows about 6% improvement on set intensive queries:

Before:

  $ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
  ! wall 0.001196 comb 0.000000 user 0.000000 sys 0.000000 (best of 2011)
  ! wall 0.001191 comb 0.000000 user 0.000000 sys 0.000000 (best of 2099)
  ! wall 0.001186 comb 0.010000 user 0.010000 sys 0.000000 (best of 1953)
  ! wall 0.001182 comb 0.000000 user 0.000000 sys 0.000000 (best of 2135)
  ! wall 0.001193 comb 0.000000 user 0.000000 sys 0.000000 (best of 2177)

After:

  $ for i in `seq 5`; hg perfrevset 'draft() & draft() & draft() & draft()'
  ! wall 0.001128 comb 0.000000 user 0.000000 sys 0.000000 (best of 2247)
  ! wall 0.001119 comb 0.000000 user 0.000000 sys 0.000000 (best of 2317)
  ! wall 0.001115 comb 0.000000 user 0.000000 sys 0.000000 (best of 2244)
  ! wall 0.001131 comb 0.000000 user 0.000000 sys 0.000000 (best of 2093)
  ! wall 0.001124 comb 0.000000 user 0.000000 sys 0.000000 (best of 2134)

It could have bigger impact on larger sets in theory.
2017-02-17 20:59:29 -08:00
Augie Fackler
5edbfee26e ui: construct _keepalnum list in a python3-friendly way
It'll be more expensive, but it preserves the behavior.
2017-02-16 11:34:50 -05:00
Rodrigo Damazio Bovendorp
0bd84ceb64 match: making visitdir() deal with non-recursive entries
Primarily as an optimization to avoid recursing into directories that will
never have a match inside, this classifies each matcher pattern's root as
recursive or non-recursive (erring on the side of keeping it recursive,
which may lead to wasteful directory or manifest walks that yield no matches).

I measured the performance of "rootfilesin" in two repos:
- The Firefox repo with tree manifests, with
  "hg files -r . -I rootfilesin:browser".
  The browser directory contains about 3K files across 249 subdirectories.
- A specific Google-internal directory which contains 75K files across 19K
  subdirectories, with "hg files -r . -I rootfilesin:REDACTED".

I tested with both cold and warm disk caches. Cold cache was produced by
running "sync; echo 3 > /proc/sys/vm/drop_caches". Warm cache was produced
by re-running the same command a few times.

These were the results:

               Cold cache           Warm cache
             Before   After      Before   After
firefox      0m5.1s   0m2.18s   0m0.22s  0m0.14s
google3 dir  2m3.9s   0m1.57s   0m8.12s  0m0.16s

Certain extensions, notably narrowhg, can depend on this for correctness
(not trying to recurse into directories for which it has no information).
2017-02-13 17:03:14 -08:00
Rodrigo Damazio Bovendorp
8c5ff96dc1 match: adding support for matching files inside a directory
This adds a new "rootfilesin" matcher type which matches files inside a
directory, but not any subdirectories (so it matches non-recursively).
This has the "root" prefix per foozy's plan for other matchers (rootglob,
rootpath, cwdre, etc.).
2017-02-13 15:39:29 -08:00
Jun Wu
49b1ca3043 runtests: add an IPv6 command line flag
Now we have all IPv6 related issues fixed, add a command line flag so people
could actually run tests with IPv6.
2017-02-17 01:21:15 -08:00
Jun Wu
d25b765433 runtests: always set web.ipv6
Previously, we only set web.ipv6 if IPv6 is used, but not on the IPv4 case.

Since we already have set web.address, it makes sense to move "web.ipv6" out
from "extra config options".
2017-02-16 08:43:59 -08:00
Jun Wu
ff1c9b7606 runtests: set web.address to localhost
Previously, "hg serve" will listen on "", which is not clear which interface
it will actually listen on - it could listen on all interfaces (ex. 0.0.0.0
on IPv4).

The run-tests.py script only checks "localhost" for available ports. So
let's make it the same for "hg serve" by explicitly setting "web.address" to
"localhost".

This resolves some IPv6 EADDRINUSE errors.
2017-02-16 00:13:29 -08:00
Jun Wu
7bdcbacb01 tests: use LOCALIP
This patch replaces hardcoded 127.0.0.1 with $LOCALIP in all tests.

Till now, the IPv6 series should make tests pass on common IPv6 systems
where the local device has the address "::1" and the hostname "localhost"
resolves to "::1".
2017-02-16 09:38:52 -08:00
Jun Wu
001fbec734 dummyssh: use LOCALIP
This patch replaces hard-coded 127.0.0.1 with $LOCALIP in dummyssh.
2017-02-15 23:24:03 -08:00
Jun Wu
3279213400 runtests: export LOCALIP
Previously, tests hard-code local IP address as "127.0.0.1". That won't work
for IPv6.

This patch exports the $LOCALIP environment variable, which is set to "::1"
if we decide to use IPv6.
2017-02-16 08:01:19 -08:00
Jun Wu
2e482ea3e3 tinyproxy: use IPv6 if HGIPV6 is set to 1
This patch makes tinyproxy.py work in IPv6 mode if HGIPV6 is set to 1.

This will make test-http-proxy.t pass on IPv6 machines.
2017-02-15 22:53:45 -08:00
Jun Wu
063ecdb2bb dumbhttp: use IPv6 if HGIPV6 is set to 1
This will fix flaky tests using dumbhttp.

The patch was tested on gcc112.fsffrance.org using the following command:

  ./run-tests.py -j 40 --runs-per-test 120 test-bundle2-remote-changegroup.t
2017-02-15 21:09:00 -08:00
Jun Wu
596eb64899 runtests: export HGIPV6 to hint test scripts whether to use IPv6
Previously, run-tests.py only exports HGPORT, and scripts in tests do not
know if IPv6 should be used. And that breaks scripts like dumbhttp.py which
always uses IPv4.

This patch makes run-tests.py export HGIPV6, which can help test scripts
like dumbhttp.py and tinyproxy.py to decide whether to use IPv6 or not.
2017-02-15 21:03:42 -08:00
Jun Wu
c67bb1c41f runtests: prefer IPv4 to IPv6
To make IPv6 work, there are multiple areas that need to fix. Before they
all get fixed, use IPv4 by default.

This should fix tests caused on IPv6 systems.
2017-02-17 00:59:09 -08:00
Rainer Woitok
ee47006291 doc: correct example concerning "hg purge" alias in man page "hgrc.5"
The "hg purge" alias as currently described in "hgrc.5" issues a possibly
confusing error message like

   rm: missing operand
   Try 'rm --help' for more information.

if no files are to be purged at all.

This patch slightly modifies the example by adding a "-f" option to the
"rm" command.
2017-02-17 11:08:36 +01:00
Augie Fackler
31b7bd0214 tests: prove that ignore works 2017-02-06 23:22:04 -05:00
Augie Fackler
c7eae9f3c3 annotate: migrate to modern pager API 2017-02-06 22:52:47 -05:00