tl;dr: This is another step towards a (previously unstated) goal of
eliminating match.files() in conditions.
There are four types of matchers:
* always: Matches everything, checked with always(), files() is empty
* exact: Matches exact set of files, checked with isexact(), files()
contains the files to match
* patterns: Matches more complex patterns, checked with anypats(),
files() contains roots of the matched patterns
* prefix: Matches simple 'path:' patterns as prefixes ('foo' matches
both 'foo' and 'foo/bar'), no single method to check, files()
contains the prefixes to match
For completeness, it would be nice to have a method for checking for
the "prefix" type of matcher as well, so let's add that, making it
return True simply when none of the others do.
The larger goal here is to eliminate uses of match.files() in
conditions (i.e. bool(match.files())). The reason for this is that
there are scenarios when you would like to create a "prefix" matcher
that happens to match no files. One example is for 'hg files -I foo
bar'. The narrowmatcher also restricts the set of files given and it
would not surprise me if have bugs caused by that already. Note that
'if m.files() and not m.anypats()' and similar is sometimes used to
catch the "exact" and "prefix" cases above.
The ability to "skip" a chain of empty directories in hgweb was added in
5c045b277096, but monoblue style wasn't updated.
This block is copied from gitweb/map file and just works.
match.visitdir() used to only look at the match's primary pattern roots to
decide if a treemanifest traverser should descend into a particular directory.
This change logically makes visitdir also consider the match's include and
exclude pattern roots (if applicable) to make this decision.
This is especially important for situations like using narrowhg with multiple
treemanifest revlogs.
This width property comes from the beginning of the monoblue theme itself, and
was used to stop the action header ("summary", "shortlog", "changelog", etc)
from clashing with the search form. But it still was happening (on smaller
screens, and with more actions added to hgweb over time).
Effectively, the hardcoded width was preventing the header from fitting into
the available screen space, since it always tried to be 900px wide, even if
that meant horizontal scroll on smaller screens and having the actions on two
lines where one should've been enough. For example,
http://selenic.com/hg/log?style=monoblue has the last two actions ("gz" and
"help") in the header on the second line, even when there seems to be enough
space on the first.
This patch makes the form float, which prevents it from overlaying/clashing
with the action header, and allows the latter to resize itself in the best
possible way.
This prevents immediate string `dirstate` from multiplying. This is also
a preparation for making dirstate aware of PENDING mechanism in
subsequent patches.
The files command supports naming directories to limit the output to children of
that directory, and it also supports -S to force recursion into a subrepo. But
previously, using -S and naming a subrepo caused nothing to be output. The
reason was narrowmatcher() strips the current subrepo path off of each file,
which would leave an empty list if only the subrepo was named.
When matching on workingctx, dirstate.matches() would see the submatcher is not
always(), so it returned the list of files in dmap for each file in the matcher-
namely, an empty list. If a directory in a subrepo was named, the output was as
expected, so this was inconsistent.
The 'not anypats()' check is enforced by an existing test around line 140:
$ hg remove -I 're:.*.txt' sub1
Without the check, this removed all of the files in the subrepo.
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.
I just discovered that we are not displaying ssh server output in real time
anymore. So we can just fall back to the bundle2 output capture for now. This
fix the race condition issue we where seeing in tests. Re-instating real time
output for ssh would fix the issue too but lets get the test to pass first.
Since e902e55c3d0b, column headers are wrapped by <thead> element, so the first
and only <tbody> contains changelog data. I got the following error without
this patch:
Uncaught TypeError: Cannot read property 'lastElementChild' of null
scrollHandler @ mercurial.js:375
It was reported that enabling pager without color could cause a hang.
Inserting print statements revealed that the callbacks in
extensions._aftercallbacks were being invoked twice.
extensions.loadall can be called multiple times. If entries in
extensions._aftercallbacks linger between calls, this could result
in double execution of the callbacks. This can lead to unwanted
behavior.
The reproduce steps in the bug seem to only occur when the output of
a command is less than the size of the current screen. This is not
something that can easily be tested. I verified the test case works
with this patch and that pager and color interaction continues to
work. Since we have no existing automated tests for pager, this sadly
appears to be the best testing I can do.
Because double backslashes are processed as a string escape sequence, '\\{'
should start the template syntax. On the other hand, r'' disables any sort
of \-escapes, so r'\{' can go either way, never start the template syntax
or always start it. I simply chose the latter, which means r'\{' is the same
as '\\{'.
This patch brings back pre-2.8.1 behavior.
The result of parsestring() is stored in templater's cache, t.cache, and then
it is parsed as a template string by compiletemplate(). So t.cache should keep
an unparsed string no matter if it is sourced from config value. Otherwise
backslashes would be processed twice.
The test vector is borrowed from 83ff877959a6.
The previous behavior when archiving a subrepo 's' on Windows was to internally
name the file under it 's\file', due to the use of vfs.reljoin(). When printing
the file list from the archive on Windows or Linux, the file was named
's\\file'. The archive extracted OK on Windows, but if the archive was brought
to a Linux system, it created a file named 's\file' instead of a directory 's'
containing 'file'.
*.zip format achives seemed not to have the problem, but this was definitely an
issue with *.tgz archives.
Largefiles actually got this right, but a test is added to keep this from
regressing. The subrepo-deep-nested-change.t test was repurposed to archive to
a file, since there are several subsequent tests that archive to a directory.
The output change is losing the filesystem prefix '../archive_lf' and not
listing the directories 'sub1' and 'sub1/sub2'.
The patch solves two issues:
1. id(unknown_full_hash) aborts, but id(unknown_short_hash) doesn't
2. id(40byte_tag_or_bookmark) returns tagged/bookmarked revision,
but id(non-40byte_tag_or_bookmark) doesn't
After the patch:
1. id(unknown_full_hash) doesn't abort
2. id(40byte_tag_or_bookmark) returns empty set
One case where that would happen is while trying to resolve a subrepo, if the
path to the subrepo was actually a broken symlink. This bug was exposed by an
hg-git test.
The editor launches without expanding the path with commits because the shell
does that for us.
If the path isn't an executable, the expanded path is displayed, which is
probably more useful than the unexpanded path. For example, in cmd.exe, '~'
expands to C:\Users\$user. But it expands to C:/mingw/msys/1.0/home/$user in
MinGW.
The '~' in the bug report is being expanded to a path with Windows style slashes
before being passed to shellquote() via util.shellquote(). But shlex.split()
strips '\' out of the string, leaving an invalid path in dispatch.aliasargs().
This regressed in 72640182118e.
For now, the tests need to be conditionalized for Windows (because those paths
are quoted). In the future, a more complex regex could probably skip the quotes
if all component separators are double '\'. I opted to glob away the quotes in
test-rename-merge2.t and test-up-local-change.t (which only exist on Windows),
because they are in very large blocks of output and there are way too many diffs
to conditionalize with #if directives. Maybe the entire path should be globbed
away like the following paths in each changed line. Or, letting #if directives
sit in the middle of the output as was mentioned a few months back would work
too.
Unfortunately, I couldn't figure out how to test the specific bug. All of the
'hg serve' tests have a #require serve declaration, causing them to be skipped
on Windows. Adding an alias for 'expandtest = outgoing ~/bogusrepo' prints the
repo as '$TESTTMP/bogusrepo', so the test runner must be changing the
environment somehow.
ui.plain() is supposed to disable config options that change the UI to the
detriment of scripts. As the test demonstrates, revset aliases can actually
override builtin ones, just like command aliases. Therefore I believe this is a
bugfix and appropriate for stable.
This avoids the following error that happened if base revision of bundle file
was hidden. bundlerevlog needs it to construct revision texts from bundle
content as revlog.revision() does.
File "mercurial/context.py", line 485, in _changeset
return self._repo.changelog.read(self.rev())
File "mercurial/changelog.py", line 319, in read
text = self.revision(node)
File "mercurial/bundlerepo.py", line 124, in revision
text = self.baserevision(iterrev)
File "mercurial/bundlerepo.py", line 160, in baserevision
return changelog.changelog.revision(self, nodeorrev)
File "mercurial/revlog.py", line 1041, in revision
node = self.node(rev)
File "mercurial/changelog.py", line 211, in node
raise error.FilteredIndexError(rev)
mercurial.error.FilteredIndexError: 1
There were 2 test failures in 3.4-rc when running test-hook.t with the
largefiles extension enabled. For context, the first is a commit hook:
@@ -618,9 +621,9 @@
$ echo 'update = hg id' >> .hg/hgrc
$ echo bb > a
$ hg ci -ma
- 223eafe2750c tip
+ d3354c4310ed+
$ hg up 0
- cb9a9f314b8b
+ 223eafe2750c+ tip
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
In both cases, largefiles acquires the wlock before calling into core, which
also acquires the wlock. The first case was fixed in 4100e338a886 by ensuring
the hook only runs after the lock has been fully released. The full release is
important, because that is what writes dirstate to the disk, allowing external
hooks to see the result of the update. This simply changes how the update hook
is called, so that it too is deferred until the lock is finally released.
There are many uses of mergemod.update(), but in terms of commands, it looks
like the following commands take wlock while calling mergemod.update(), and
therefore will now have their hook fired at a later time:
backout, fetch, histedit, qpush, rebase, shelve, transplant
Unlike the others, fetch immediately unlocks after calling update(), so for all
intents and purposes, its hook invocation is not deferred (but the external hook
still sees the proper state).
If v = -INT_MAX - 1, -v would exceed INT_MAX. I don't think this would cause
problems such as issue4627, but we can't blame it as a compiler bug because
signed integer overflow is undefined in C.
The current bundle2 processing was capturing all output. This is nice as it
provide better meta data about what output what, but this was changing two
things:
1) adding a prefix "remote: " to "other" output during local push (issue4613)
2) local and ssh push does not provide real time output anymore (issue4615)
As we are unsure about what form should be used in (1) and how to solve (2) we
disable output capture in this two cases. Output capture can be forced using an
experimental option.
Most operations on treemanifests already visit only relevant
submanifests. Notable examples include __getitem__, __contains__,
walk/matches with matcher, diff. By making submanifests lazily loaded,
we speed up all these operations.
The lazy loading is achieved by adding a _load() method that gets
defined where we currently eagerly parse the manifest. We make sure to
call it before any access to _dirs, _files or _flags.
Some timings on the Mozilla repo (with flat manifest timings for
reference):
hg cat -r . README.txt: 1.644s -> 0.096s (0.255s)
hg diff -r .^ -r . : 1.746s -> 0.137s (0.431s)
hg files -r . python : 1.508s -> 0.146s (0.335s)
hg files -r . : 2.125s -> 2.203s (0.712s)
We currently avoid saving a treemanifest revision if it's the same as
one of it's parents. This is checked by comparing the generated text
for all three versions. Let's avoid that when possible by comparing
the nodeids for clean (not dirty) nodes.
On the Mozilla repo, this speeds up commit from 2.836s to 2.343s.
Since tree manifests have a nodeid per directory, we can avoid diffing
entire directories if they have the same nodeid. The comparison is
only valid for unmodified treemanifest instances, of course, so we
need to keep track of which have been modified. Therefore, let's add a
dirty flag to treemanifest indicating whether its nodeid can be
trusted. We set it when _files or _dirs is modified, and make diff(),
and its cousin filesnotin(), not descend into subdirectories that are
the same on both sides.
On the Mozilla repo, this speeds up 'hg diff -r .^ -r .' from 1.990s
to 1.762s. The improvement will be much larger when we start lazily
loading subdirectory manifests.
With many commands accepting a '-S' or an explicit path to trigger recursing
into subrepos, it seems that --hidden needs to be propagated too.
Unfortunately, many of the subrepo layer methods discard the options map, so
passing the option along explicitly isn't currently an option. It also isn't
clear if other filtered views need to be propagated, so changing all of those
commands may be insufficient anyway.
The specific jam I got into was amending an ancestor of qbase in a subrepo, and
then evolving. The patch ended up being hidden, and outgoing said it would only
push one unrelated commit. But push aborted with an 'unknown revision' that I
traced back to the patch. (Odd it didn't say 'filtered revision'.) A push with
--hidden worked from the subrepo, but that wasn't possible from the parent repo
before this.
Since the underlying problem doesn't actually require a subrepo, there's
probably more to investigate here in the discovery area. Yes, evolve + mq is
not exactly sane, but I don't know what is seeing the hidden revision.
In lieu of creating a test for the above situation (evolving mq should probably
be blocked), the test here is a marginally useful case where --hidden is needed
in a subrepo: cat'ing a file in a hidden revision. Without this change, cat
aborts with:
$ hg --hidden cat subrepo/a
skipping missing subrepository: subrepo
[1]
When passing a --rev, 'hg incoming -S' previously suffered from the same output
truncation or abort that was fixed for 'hg outgoing -S' in the previous patch,
for the same reasons.
Unlike push, subrepos are currently only pulled when the outer repo is updated,
not when the outer repo is pulled. That makes matching 'hg pull' behavior
impossible. Listing all incoming csets in the subrepo seems like the most
useful behavior, and is consistent with 'hg outgoing -S'.
The previous behavior didn't reflect what would actually be pushed- push will
ignore --rev and --branch in the subrepo and push everything. Therefore,
'push -r {rev}' would not list everything, unless {rev} was also the revision of
the subrepo's tip. Worse, if a hash was passed in, the command would abort
because that hash would either not be in the outer repo or not in the subrepo.
While fixing issue4304: "record: allow editing new files" we introduced
changes in record/crecord. These changes need to be matched with changes in any
command using record. Revert is one of these commands and the changes have
not been made for this release. Therefore, revert -i should be an experimental
feature for this release.
In my latest change on record (edit newly added file), I forgot the
repo.wjoin() so that record was not computing the paths properly to delete
the backups and was crashing.
This wrapping seems meaningless, because:
- there is no "_()" invocation to prepare for extracting phase names
to be translated
"make update-pot" doesn't extract msgids for phase names
- phase names are kine of reserved keywords like as branch name "default"
String concatenation by "+" operator causes failure of extracting
messages to be translated.
Python automatically concatenates strings separated by whitespaces
into one string.
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
Before this patch, doc string of each web commands isn't extracted as
translatable one, even though web commands are listed up in "hg help
hgweb".
This patch adds "mercurial/hgweb/webcommands.py" on to arguments of
"i18n/hggettext". "i18nfunctions" added into "webcommands.py" is used
by "i18n/hggettext" to get the list of functions having translatable
doc string.
The '' that is used to represent the state of a not-yet-committed
subrepo cannot be written to the file, because the code that parses
the file splits on ' ' and expects two parts.
Given that the .hgsubstate file is automatically rewritten on commit, it seems
a little strange that the file is written out during a merge.