Commit Graph

24349 Commits

Author SHA1 Message Date
Siddharth Agarwal
5c1db53305 dirstate.walk: use the file foldmap to normalize
Computing the set of directories in the dirstate is expensive. It turns out
that it isn't necessary for operations like 'hg status' at all.

Why? Consider the file 'foo/bar' on disk, which is represented in the dirstate
as 'FOO/BAR'.

On 'hg status', we'd walk down the directory tree, coming across 'foo' first.

Before: we'd normalize 'foo' to 'FOO', then add 'FOO' to our visited stack.
We'd then visit 'FOO', finding the file 'bar'. We'd normalize 'FOO/bar' to
'FOO/BAR', then add it to the results dict.

After: we wouldn't normalize 'foo' at all. We'd add it to our visited stack,
then visit 'foo', finding the file 'bar'. We'd normalize 'foo/bar' to
'FOO/BAR', then add it to the results dict.

So whether we normalize intermediate directories or not actually makes no
difference in most cases.

The only case where normalization matters at all is if a file is replaced with
a directory with the same case-folded name. In that case we can do a relatively
cheap file normalization instead and still get away with not computing the set
of directories.

This is a nice boost in status performance. On OS X with case-insensitive HFS+,
for a large repo with over 200,000 files, this brings down 'hg status' from
4.00 seconds to 3.62.
2015-03-29 19:47:16 -07:00
Siddharth Agarwal
efae199860 dirstate: split the foldmap into separate ones for files and directories
Computing the set of directories in the dirstate can be pretty expensive. For
'hg status' without arguments, it turns out we actually never need to figure
out the right case for directories in the foldmap. (An upcoming patch explains
why.)

This patch splits up the directory and file maps into separate ones, allowing
for the subsequent optimization in status.
2015-03-29 19:42:49 -07:00
Siddharth Agarwal
15b2067928 dirstate: introduce function to normalize just filenames
This will be used in upcoming patches to stop generating the set of directories
in many common cases.
2015-03-28 18:53:54 -07:00
Siddharth Agarwal
28d1a1fb85 dirstate: factor out code to discover normalized path
In upcoming patches we're going to reuse this code. The storemap is currently
always the foldmap, but will vary in future patches.
2015-03-29 19:23:05 -07:00
Matt Harbison
37984876f0 color: fix crash in cmd.exe
When 'term' is None because it isn't in the environment, don't iterate over it.
Unfortunately, unsetting $TERM or exporting it as '' doesn't work in the tests,
so there's no way to simulate cmd.exe in the test suite.
2015-03-31 14:27:45 -04:00
Martin von Zweigbergk
3e235a01ca log: prefer 'wctx' over 'pctx' for working context 2015-03-18 21:44:25 -07:00
Matt Mackall
c2e689e49d merge with stable 2015-03-31 08:31:42 -05:00
Matt Mackall
1dee8dda3b tags: remove scary message about corrupt tags cache
Caches should be transparent. If a cache is damaged, it should
silently be rebuilt, much like if it were invalid. No one seems to
have ever hit this in the wild.
2015-03-31 08:04:42 -05:00
Andrew Shadura
d79f0dfc20 hgk: use switch instead of a less efficient if/elseif/if 2015-03-29 19:15:04 +02:00
Andrew Shadura
a5a999d5cb hgk: set distinct fill and outline colour for non-public and obsolete changesets 2015-03-29 19:12:08 +02:00
Andrew Shadura
e8540303c1 hgk: show secret changesets differently (shape and label) 2015-03-29 18:44:53 +02:00
Yuya Nishihara
4a691471f2 templates: fix "log -q" output of phases style
It had the same problem as be4dab229c78, name conflicts of {node} keyword.
2015-03-28 20:22:03 +09:00
Martin von Zweigbergk
7dfcb254e9 manifestv2: implement slow readdelta() without revdiff
For manifest v2, revlog.revdiff() usually does not provide enough
information to produce a manifest. As a simple workaround, implement
readdelta() by reading both the old and the new manifest and use
manifest.diff() to find the difference. This is several times slower
than the current readdelta() for v1 manifests, but there seems to be
no other simple option, and this is still much faster than returning
the full manifest (at least for verify).
2015-03-27 20:41:30 -07:00
Martin von Zweigbergk
b7bfa722d1 manifestv2: disable fastdelta optimization
We may add support for the fastdelta optimization for manifest v2 at a
later point, but let's disable it for now, so we don't have to
implement it right away.
2015-03-27 17:07:24 -07:00
Martin von Zweigbergk
16d87fc88d manifestv2: add (unused) config option
With tree manifests, hashes will change anyway, so now is a good time
to also take up the old plans of a new manifest format. While there
should be little or no reason to use tree manifests with the current
manifest format (v1) once the new format (v2) is supported, we'll try
to keep the two dimensions (flat/tree and v1/v2) separate.

In preparation for adding a the new format, let's add configuration
for it and propagate that configuration to the manifest revlog
subclass. The new configuration ("experimental.manifestv2") says in
what format to write the manifest data. We may later add other
configuration to choose how to hash it, either keeping the v1 hash for
BC or hashing the v2 content.

See http://mercurial.selenic.com/wiki/ManifestV2Plan for more details.
2015-03-27 16:19:44 -07:00
Martin von Zweigbergk
a7479ae566 manifest: extract method for creating manifest text
Similar to the previous change, this one extracts a method for
producing a manifest text from an iterator over (path, node, flags)
tuples.
2015-03-27 15:37:46 -07:00
Martin von Zweigbergk
a16ddaed87 manifest: extract method for parsing manifest
By extracting a method that generates (path, node, flags) tuples, we
can reuse the code for parsing a manifest without doing it via a
_lazymanifest like treemanifest currently does. It also prepares for
parsing the new manifest format.

Note that this makes parsing into treemanifest slower, since the
parsing is now always done in pure Python. Since treemanifests will be
expected (or even forced) to be used only with the new manifest
format, parsing via _lazymanifest was not an option anyway.
2015-03-27 15:02:43 -07:00
Siddharth Agarwal
fe84899cf2 dirstate._walkexplicit: don't bother normalizing '.'
The overwhelmingly common case is running commands like 'hg diff' with no
arguments. Therefore the only file that'll be listed is the root directory.
Normalizing that's just a waste of time.

This means that for a plain 'hg diff' we'll never need to construct the
foldmap, saving us a significant chunk of time.

On case-insensitive HFS+ on OS X, for a large repository with over 200,000
files, this brings down 'hg diff' from 2.97 seconds to 2.36.
2015-03-29 18:28:48 -07:00
Siddharth Agarwal
8adc467907 dirstate._walkexplicit: drop normpath calls
The paths the matcher returns are normalized already.
2015-03-29 23:28:30 -07:00
Siddharth Agarwal
0d03b12a57 dirstate._walkexplicit: indicate root as '.', not ''
'.' is the canonical way to represent the root, and it's apparently the only
transformation that normpath makes.
2015-03-29 23:27:25 -07:00
Laurent Charignon
9430b8ddec phases: add killswitch for native implementation 2015-03-30 12:57:55 -07:00
Laurent Charignon
5e18944310 phases: move pure phase computation in a function 2015-03-30 12:48:15 -07:00
Laurent Charignon
dfc226357c revset: add hook after tree parsing
This will be useful to execute actions after the tree is parsed and
before the revset returns a match. Finding symbols in the parse tree
will later allow hashes of hidden revisions to work on the command
line without the --hidden flag.
2015-03-24 14:24:55 -07:00
Augie Fackler
20be0dbf38 hgk: remove unused revlog import 2015-03-30 14:58:42 -04:00
Gregory Szorc
54ee501852 run-tests: obtain replacements inside Test._runcommand
Now that command running is part of Test, we no longer need to pass
a list of replacements down through various call layers.

The impetus for this change is to fetch replacements after
command execution, not before. This will allow replacements to be
defined as part of test execution.
2015-03-28 14:55:28 -07:00
Andrew Shadura
ff15132c27 hgk: remove no longer needed debug-rev-parse command 2015-03-28 21:33:47 +01:00
Andrew Shadura
48d9f0deb1 hgk: remove no longer needed debug-config command 2015-03-28 21:24:57 +01:00
Andrew Shadura
d0e9f81098 hgk: display obsolete changesets in darkgrey 2015-03-28 20:05:01 +01:00
Andrew Shadura
c509289c81 hgk: pass --hidden switch to hg subprocesses when needed 2015-03-28 19:36:21 +01:00
Andrew Shadura
0b8a3f746b hgk: remove repetitious (and wrong) command syntax descriptions 2015-03-28 19:34:03 +01:00
Gregory Szorc
959709b719 run-tests: separate newline normalization from replacements
Upcoming patches will change how the replacements system works
to make it more flexible. To prepare for this, eliminate the one-off
use of replacements to perform newline normalization on Windows.
2015-03-28 14:28:22 -07:00
Gregory Szorc
779896c562 run-tests: remove arguments from Test._runcommand
Now that runcommand is part of the Test class, arguments that were
previously coming from Test attributes can now be switched to
lookups inline.
2015-03-28 14:12:57 -07:00
Gregory Szorc
681a5f7b0d run-tests: move run into Test class
Future patches will change how replacements work. Since the logic in
run() is strongly tied to the operation of individual tests and since
there is potential to make the implementation simpler by giving the
function access to Test attributes, move it into Test.
2015-03-28 14:08:25 -07:00
Gregory Szorc
918575b5f2 run-tests: wait for test threads after first error
The test runner has the ability to stop on first error.

Tests are executed in new Python threads. The test runner starts new
threads when it has capacity to do so. Before this patch, the "stop on
first error" logic would return immediately from the "run tests"
function, without waiting on test threads to complete. There was thus
a race between the test runner thread doing cleanup work and the test
thread performing activity. For example, the test thread could be in
the middle of executing a test shell script and the test runner
could remove the test's temporary directory. Depending on timing, this
could result in any number of output from the test runner.

This patch eliminates the race condition by having the test runner
explicitly wait for test threads to complete before continuing.

I discovered this issue as I modified the test harness in a subsequent
patch and was reliably able to tickle the race condition.
2015-03-28 19:39:03 -07:00
Gregory Szorc
325c00cc79 run-tests: report code coverage from source directory
As part of testing code coverage output, I noticed some files were
being reported twice: there was an entry for the file in the install
location and for the file in the source tree. I'm not sure why this
is. But it resulted in under-reporting of coverage data since some
lines weren't getting covered in both locations.

I also noticed that files in the source directory and outside the
"mercurial" and "hgext" packages were getting included in the
coverage report. Cosmetically, this seemed odd to me. It's not
difficult to filter paths from the report. But I figure this data
can be useful (we could start reporting run-tests.py coverage,
for example).

This patch switches the coverage API to report code coverage from
the source directory. It registers a path alias so that data from
the install location is merged into data from the source directory.
We now get merged results for files that were being reported in
multiple locations.

Since code coverage reporting now relies on the profiled install
now being in sync with the source tree, an additional check to
disallow code coverage when --with-hg is specified has been added.
This should have been present before, as --local was previously
disallowed for the same reasons.

Merging the paths raises our aggregate line coverage from ~60 to
81%.
2015-03-28 00:21:30 -07:00
Gregory Szorc
34e11242ee run-tests: collect aggregate code coverage
Before this patch, every Python process during a code coverage run was
writing coverage data to the same file. I'm not sure if the coverage
package even tries to obtain a lock on the file. But what I do know is
there was some last write wins leading to loss of code coverage data, at
least with -j > 1.

This patch changes the code coverage mechanism to be multiple process
safe. The mechanism for initializing code coverage via sitecustomize.py
has been tweaked so each Python process will produce a separate coverage
data file on disk. Unless two processes generate the same random value,
there are no race conditions writing to the same file. At the end of the
test run, we combine all written files into an aggregate report.

On my machine, running the full test suite produces a little over
20,000 coverage files consuming ~350 MB. As you can imagine, it takes
several seconds to load and merge these coverage files. But when it is
done, you have an accurate picture of the aggregate code coverage for the
entire test suite, which is ~60% line coverage.
2015-03-28 00:47:58 -07:00
Gregory Szorc
a8bfabf2e6 run-tests: obtain code coverage via Python API
Before, we were invoking the "coverage" program provided by the
"coverage" module. This patch changes the code to go through the
Python API. This makes the next patch a little bit easier to reason
about.

A side effect of this patch is that writing code coverage reports
will be slightly faster, as we won't have to redundantly load
coverage data.
2015-03-27 23:17:19 -07:00
Gregory Szorc
7ba88d1a50 commands.debugrevlog: report max chain length
This is sometimes useful to know. Report it.
2015-03-28 12:58:44 -07:00
Martin von Zweigbergk
35cf546efe _lazymanifest: drop unnecessary call to sorted()
The entries returned from _lazymanifest.iterentries() are already
sorted.
2015-03-27 20:55:54 -07:00
Matt Harbison
2625472c94 test-git-export: add globs the test runner wants on Windows
The only difference for the first two was to add the globs, but the third line
of output on Windows was '..\dir2\copy'.  I'm not sure why 'copy' is output on
Windows instead of '*'.
2015-03-29 00:00:14 -04:00
Gregory Szorc
01447cbf3e run-tests: explicitly handle unicode when writing xunit file
The xunit writer was passing a str to a minidom API. An implicit
.decode('ascii') was performed somewhere, causing UnicodeDecodeError
if test output contained non-ascii sequences.

This patch converts test output to utf-8 before passing it to minidom.
We use the "replace" strategy to ensure invalid utf-8 sequences get
munged into �.
2015-03-29 10:41:23 -07:00
André Sintzoff
aadf1ad8aa parsers.c: avoid implicit conversion loses integer warnings
These warnings are raised by Apple LLVM version 6.0 (clang-600.0.57)
(based on LLVM 3.5svn) and were introduced in 37171a30314d
2015-03-29 19:06:23 +02:00
Matt Harbison
e0846fc2d8 test-annotate: conditionalize error output for Windows
It seems better to leave the actual output in place instead of globbing
everything but 'abort:', in case it starts aborting for other reasons.

It isn't clear the purpose for reversing the file name position, but that
originates in windows.posixfile.
2015-03-29 00:20:56 -04:00
Matt Harbison
46014de55c test-diffstat: add a glob the test runner wants on Windows
The test gets a '~' status without it.
2015-03-28 23:57:16 -04:00
Mathias De Maré
6a032dab5a tests: add testing for diff.showfunc
The diff.showfunc config knob did not have coverage before.
2015-03-24 21:36:38 +01:00
Drew Gottlieb
d2ab66f723 manifest: make manifest.intersectfiles() internal
manifest.intersectfiles() is just a utility used by manifest.matches(), and
a future commit removes intersectfiles for treemanifest for optimization
purposes.

This commit makes the intersectfiles methods on manifestdict and treemanifest
internal, and converts its test to a more generic testMatches(), which has the
exact same coverage.
2015-03-30 10:43:52 -07:00
Adrian Buehlmann
fa1861d8ff win32: add comment about WinError
Prevent reintroducing the bug that was added in a9badcbcfb79 (and fixed with
77bbc180dbf8).
2015-03-28 11:19:34 +01:00
Laurent Charignon
ff5c5b9b22 record_curses: fix ui bug for newly added file
With record's curses interface toggling and untoggling a newly added
file would lead to a confusing UI (the header was marked as partial
and the hunks as unselected). Tested additionally using the curses
interface with newly added, removed and modified files in a test repo.
2015-03-27 14:11:13 -07:00
Matt Mackall
526b5a1fd1 import-checker: rotatecycle is actually the canonical cycle key
So refactor to drop cyclekey().
2015-03-28 00:08:26 -05:00
Matt Mackall
99e8245cd5 import-checker: make search algorithm non-recursive breadth-first
Breadth-first allows finding the shortest cycle including the starting
module. This lets us terminate our search early when we've discovered
shorter paths already. This gives a tremendous speed-up to the
cycle-finding portion of the test, dropping total runtime from 39s to
3s.
2015-03-27 23:52:23 -05:00