Index lookups raise RevlogError when the lookup fails. The previous
implementation was caching a reference to the RevlogError type in a
static variable. This assumed that the "mercurial.error" module was
only loaded once and there was only a single copy of it floating
around in memory. Unfortunately, in some situations - including
certain mod_wsgi configurations - this was not the case: the
"mercurial.error" module could be reloaded. It was possible for a
"RevlogError" reference from the first interpreter to be used by
a second interpreter. While the underlying thing was a
"mercurial.error.RevlogError," the object IDs were different, so
the Python code in revlog.py was failing to catch the exception! This
error has existed since the C index lookup code was implemented in
changeset 1e47437a1ca7, which was first released in Mercurial 2.2 in
2012.
http://emptysqua.re/blog/python-c-extensions-and-mod-wsgi/#static-variables-are-shared
contains more details.
This patch removes the caching of the RevlogError type from the
function.
Since pretty much the entire function was refactored and the return
value of the function wasn't used, I changed the function signature
to not return anything.
For reasons unknown to me, we were calling PyErr_SetObject()
with the type of RevlogError and an instance of RevlogError. This
was equivalent to the Python code "raise RevlogError(RevlogError)".
This seemed wonky and completely unnecessary. The Python code only
cares about the type of the exception, not its contents. So I got
rid of this complexity.
This is my first Python C extension patch. Please give extra scrutiny
to it during review.
The problem was spotted at cd1b50e99ed8, that says "this patch invokes it
with "strtoken='rawstring'" in "_evalifliteral()", because "t" is the result
of "arg" evaluation and it should be "string-escape"-ed if "arg" is "string"
expression." This workaround is no longer valid since 72be08a15d8d introduced
strict parsing of '\{'.
Instead, we should interpret bare token as "string" or "rawstring" template.
This is what buildmap() does at parsing phase.
When moving crecord to core, I did a search an replace to remove all of the
variable with caps letter. Doing so, I unfortunately changed some commands
with capital letter shortcut to their lowercase counterpart. I fixed one
of these cases in bfcbb3995330. This patch fixes all of the remaining cases.
When moving crecord to core, I did a search an replace to remove all of the
variable with caps letter. Doing so, I unfortunately changed the 'F' command
to 'f' leading to two 'f' commands, one never used. This patch fixes this
mistake and re enables the behavior of 'F'.
Previously, if a subrepo parent had 'web.hidden=True' set, neither the parent
nor child had a repository entry. However, the directory entry for the parent
would be listed (it wouldn't have the fancy 'web.name' if configured), and that
link went to the repo's summary page, effectively making it not hidden.
This simply disables the directory processing if a valid repository is present.
Whether or not the subrepo should be hidden is debatable, but this leaves that
behavior unchanged (i.e. it stays hidden).
The previous scheme was:
1) lookup node for all pulled revision,
2) pull said node
3) lookup the node of the checkout target
4) update the repository there.
If the remote repo changes between (1) and (3), the resolved name will be
different and (3) crash. There is actually no need for a remote lookup during
(3), we could just set the value in (1). This prevent the race condition and
save a possible network roundtrip.
Previously, when 'web.name' was set on a subrepo parent and 'web.collapse=True',
the parent repo would show in the list with the configured 'web.name', and a
directory with the parent repo's filesystem name (with a trailing slash) would
also appear. The subrepo(s) would unexpectedly be excluded from the list of
repositories. Clicking the directory entry would go right to the repo page.
Now both the parent and the subrepos show up, without the additional directory
entry.
The configured hgweb paths used '**' for finding the repos in this scenario.
A couple of notes about the tests:
- The area where the subrepo was added has a comment that it tests subrepos,
though none previously existed there. One now does.
- The 'web.descend' option is required for collapse to work. I'm not sure what
the previous expectations were for the test. Nothing changed with it set,
prior to adding the code in this patch. It is however required for this test.
- The only output changes are for the hyperlinks, obviously because of the
'web.name' parameter.
- Without this code change, there would be an additional diff:
--- /usr/local/mercurial/tests/test-hgwebdir.t
+++ /usr/local/mercurial/tests/test-hgwebdir.t.err
@@ -951,7 +951,7 @@
/rcoll/notrepo/e/
/rcoll/notrepo/e/e2/
/rcoll/notrepo/f/
- /rcoll/notrepo/f/f2/
+ /rcoll/notrepo/f/
Test repositories inside intermediate directories
I'm not sure why the fancy name doesn't come out, but it is enough to
demonstrate that the parent is not listed redundantly, and the subrepo isn't
skipped.
Before this patch, template keywords `{file_mods}`, `{file_adds}` and
`{file_dels}` use values gotten by `repo.status(ctx.p1().node(),
ctx.node())`.
But this doesn't work as expected if `ctx` is `memctx` or
`workingcommitctx`. Typical case of templating with these contexts is
customization of the text shown in the commit message editor by
`[committemplate]` configuration.
In this case, `ctx.node()` returns None and it causes comparison
between `ctx.p1()` and `workingctx`. `workingctx` lists up all changed
files in the working directory even at selective committing.
BTW, `{files}` uses `ctx.files()` and it works as expected.
To compare target context and its parent exactly, this patch passes
`ctx.p1()` and `ctx` without `node()`-nize. This avoids unexpected
comparison with `workingctx`.
This patch uses a little redundant template configurations in
`test-commit.t`, but they are needed to avoid regression around
problems fixed by 17e2fda16f58 and 2b999bc2d89a: accessing on `ctx`
may break `ctx._status` field.
This makes _includeroots more like _fileroots and gives visitdir() a
nice symmetry in the two.
I'm hoping to later combine the two (_fileroots and _includeroots),
and having them treated similarly should make that step easier to
follow.
It seems unlikely that the optimization to avoid calling util.finddirs
twice will be noticeable, so let's drop it. This makes the two
conditions for includes and regular patterns more similar.
The repo root is nothing special when it comes to what directories to
visit: patterns like '-X relglob:*.py' should not exclude the top
directory, while '-X path:.' should (pointless as such a pattern may
be). The explicit removal of '.' from the set of excluded roots was
probably there to avoid removing the the root directory when any
patterns had been given, but since a619025a07b5 (treemanifest: visit
directory 'foo' when given e.g. '-X foo/ba?', 2015-05-27), we only
exclude directories that should be completely excluded, so we no
longer need to special-case the root directory.
'repo' is a very confusing name to use for 'self', especially when
it's not a repo. Also drop repo.ui member (a.k.a. self.ui) now that
'self' doesn't shadow outer 'repo' variable.
This code is already used in a couple of places, and will need to be used in
others where wdir() support is needed. Trying to get the wdir() revision stored
in self._substate[1] when creating the object in subrepo.subrepo() resulted in
breaking various status and diff tests. This is a far less invasive change.
Context: the result of computehidden, used to compute the 'visible' revisions
is cached. Its output can change when:
1) new obsolete commits are created
2) new bookmarks are created or deleted
3) new tags are created or deleted
4) the parents of the working copy change
We currently correctly invalidate the cache only in the case 1).
This patch fixes the second case (bookmarks) by invalidating the cache once
a bookmark is added or removed.
There were consistent test failures in test-bad-extension.t, because Windows
buffers stderr when redirected to a file (per the comment in ui.write_err()).
That resulted in failures like this:
--- c:/Users/Matt/Projects/hg/tests/test-bad-extension.t
+++ c:/Users/Matt/Projects/hg/tests/test-bad-extension.t.err
@@ -23,11 +23,11 @@
Traceback (most recent call last):
Exception: bit bucket overflow
*** failed to import extension badext2: No module named badext2
- Traceback (most recent call last):
- ImportError: No module named badext2
hg help [-ec] [TOPIC]
show help for a given topic or a help overview
+ Traceback (most recent call last):
+ ImportError: No module named badext2
show traceback for ImportError of hgext.name if debug is set
(note that --debug option isn't applied yet when loading extensions)
Instead of inserting another flush immediately after the print, to go along with
the one recently added prior to the print (see 3cd72de3be66), funnel the output
through ui.write_err(). The flush prior to printing the traceback only mentions
that stdout needs to be flushed, and only stderr needs to be flushed after
printing the traceback. ui.write_err() does both for us without needing to
redocument the quirky Windows behavior. It will also clear any progress bar.
As stated in the comment, using the smartset 'min' will give more opportunity to
be smart. It give a small but significant boost to the performance. Most of the
time is still spend doing the actual computation but at least we can scrap some
performance when it makes sense.
revset #0: roots(0:tip)
plain
0) 0.046600
1) 0.044109 94%
Python is slow at attributes lookup. No, really, I mean -slow-. prefetching
these three methods give use a measurable performance boost.
revset #0: 0::tip
plain
0) 0.037655
1) 0.034290 91%
The fix in a795188178a1 is actually wrong. We now use the filename to match what
'_addentry'. This whole untested code is quite suspicious. This seems to point
that no one is ever running 'tr.find' for a backup file.
checkcopies was using fctx.rev() which it was expecting would be
equivalent to linkrev() but was triggering the new _adjustlinkrev path.
This was making grafts and merges with large sets of potential copies
very expensive.
Before this patch, hook argument `txnid` isn't passed to `pretxnopen`
hooks, even though `hooks` section of `hg help config` describes so.
``pretxnopen``
Run before any new repository transaction is open. The reason for the
transaction will be in ``$HG_TXNNAME`` and a unique identifier for the
transaction will be in ``HG_TXNID``. A non-zero status will prevent the
transaction from being opened.
Before this patch, transaction ID (TXNID) is calculated from
`transaction` object itself by `id()`, but this prevents TXNID from
being passed to `pretxnopen` hooks, which should be executed before
starting transaction processing (also any preparations for it, like
writing journal files out).
As a preparation for passing TXNID to `pretxnopen` hooks, this patch
separates calculation of TXNID from creation of `transaction` object.
This patch uses "random" library for reasonable unique ID. "uuid"
library can't be used, because it was introduced since Python 2.5 and
isn't suitable for Mercurial 3.4.x stable line.
`%f` formatting for `random.random()` is used with explicit precision
number 40, because default precision for `%f` is 6. 40 should be long
enough, even if 10**9 transactions are executed in a short time (a
second or less).
On the other hand, `time.time()` is used to ensures uniqueness of
TXNID in a long time, for safety.
BTW, platform not providing `/dev/urandom` or so may cause failure of
`import random` itself with some Python versions (see Python
issue15340 for detail http://bugs.python.org/issue15340).
But this patch uses "random" without any workaround, because:
- "random" is already used directly in some code paths,
- such platforms are very rare (e.g. Tru64 and HPUX), and
http://bugs.python.org/issue15340#msg170000
- updating Python runtime can avoid this issue
This fixes the crash caused by "branch(null)" revset. No cache should be
necessary for nullrev because changelog.branchinfo(nullrev) does not involve
IO operation.
Note that the problem of "branch(wdir())" isn't addressed by this patch.
"wdir()" will raise TypeError in many places because of None. This is the
reason why "wdir()" is still experimental.
This patch partially backs out a9a86cbbc5b2 and adds an alternative workaround
to functions that evaluate "null" and "wdir()". Because the new workaround is
incomplete, "first(null)" and "min(null)" don't work as expected. But they were
not usable until 3.4 and "null" isn't commonly used, we can postpone a complete
fix for 3.5.
The issue4682 was caused because "branch(default)" is evaluated to
"<filteredset <fullreposet>>", keeping fullreposet magic. The next patch will
fix crash on "branch(null)", but without this patch, it would make
"null in <branch(default)>" be True, which means "children(branch(default))"
would return all revisions but merge (p2 != null).
I believe the right fix is to stop propagating fullreposet magic on filter(),
but it wouldn't fit to stable release. Also, we should discuss how to handle
"null" and "wdir()" in revset before.
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.
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.
This regressed in 39be809de631, in what looks like an unrelated change.
It seems sufficient to pass 'ignoremissing=True', but the restored try/except
has been there for six years since 3f24f7324cd8, so this seems safer for now.
Note that renaming directories in the filename doesn't appear to work- not sure
if this would end up throwing a different type of error when that is fixed.
This is a copy of 942d64e0a1ee, but applied to the phases template,
which is itself almost a copy of the default template.
Perhaps we should rewrite these templates to use the %include syntax
afforded by config files. This change seems a bit too big for stable,
though.
Until this changeset, we were only able to save output if an error happened
during the 'transaction.close()' phase. If the 'processbundle' call raised an
exception, the 'bundleoperation' object was never returned, so the reply bundle
was never accessible and no output could be salvaged. We introduce a quick (but
not very elegant) fix to gain access to any reply created during the processing.
This conclude this output related series. We should hopefully be able client-side to see the
whole server output, in a proper order.
The code is now complex enough that a refactoring of it would make sense on
default.
We were capturing all output issue during bundle2 processing, and all output
issue during transaction rollback in case of failure. However, the output issue
during transaction commit was still roaming the land freely. It is now put back
in line.
This let the user see output from 'pretxnclose' and 'txnclose' (and related) in
the right order.
External hook used to directly write on stdout and stderr. As a result their
output was not captured by the bundle2 processing. This resulted in confusing
out of order output on the client side. We are now capturing hooks output in
this context.
We want to capture hooks output during bundle2 processing. For this purpose we
introduce a new 'subproc' argument to 'ui.pushbuffer'. When set, the output of
sub process created through 'ui.system' will be captured in the buffer too.
This will be used in the next changeset.
The output from the transaction rollback was not included into the reply bundle.
It was eventually caught by the usual 'unbundle' output capture and sent to the
client but the result was out of order on the client side. We now capture the
output for the transaction release and transmit it the same way as all other
output.
We should probably rethink the whole output capture things but this would not be
appropriate for stable.
The is still multiple cases were output failed to be properly capture, they will
be fixed in later changesets.
Remote output should be silenced by --quiet. The issue was found while running
`test-largefiles-cache.t` so it will get tested once we switch bundle2 by
default.
I tried to fix this issue in the past and had to revert the fix. This is a
second attempt without the regression we found with the first one.
record defines special headers (of file) as headers whose hunk are not shown
to the user for editing, they are used to represent deleted, moved and new
files. Since we want to authorize editing the patch of newly added file we
make the newly added file with some content not special anymore. This entails
that we have to save their content before applying the backup to be able to
revert it if the patch does not apply properly.
We reintroduce the test showing that newly added files can be edited and that
their content is shown to the user.
Before this patch, reverting a file to the revision other than the
parent doesn't update dirstate. This seems to expect that timestamp
and/or size will be changed by reverting.
But if (1) dirstate of file "f" is filled with timestamp before
reverting and (2) size and timestamp of file "f" isn't changed at
reverting, file "f" is recognized as CLEAN unexpectedly.
This patch applies "dirstate.normallookup()" on reverted file, if size
isn't changed.
Making "localrepository.wwrite()" return length of written data is
needed to avoid additional (and redundant) "lstat(2)" on the reverted
file. "filectx.size()" can't be used to know it, because data may be
decoded at being written out.
BTW, interactive reverting may cause similar problem, too. But this
patch doesn't focus on fixing it, because (1) interactive (maybe slow)
reverting changes one (or both) of size/timestamp of reverted files in
many usecases, and (2) changes to fix it seems not suitable for stable
branch.
'hg revert -I foo' currently fails with
abort: no files or directories specified
(use --all to revert all files, or 'hg update 1' to update)
It doesn't seem intentional that -I/-X without other paths or
--all/--interactive should fail, and it doesn't seem that harmful to
allow it either, so let's just do that.
We are using record and crecord in different context, not just for commiting
changes but also reverting and shelving changes. This diff changes the wording
from commiting to confirming changes to avoid confusing the users with what
they are doing.
Since Python 2.7.9, "os.path.join(path, '')" doesn't add "os.sep" at
the end of UNC path (see issue4557 for detail).
This makes unionrepo incorrectly work, if:
1. cwd is the root of UNC share (e.g. "\host\share"), and
2. mainreporoot is near cwd (e.g. "\host\sharefoo\repo")
- host of UNC path is same as one of cwd
- share of UNC path starts with one of cwd
3. "repopath" isn't specified in URI (e.g. "union:path/to/repo2")
For example:
$ hg --cwd \host\share -R \host\sharefoo\repo incoming union:path\to\repo2
In this case:
- os.path.join(r"\host\share", "") returns r"\host\share",
- r"\host\sharefoo\repo".startswith(r"\host\share") returns True, then
- r"foo\repo" is treated as repopath of unionrepo instead of
r"\host\sharefoo\repo"
This causes failure of combining "\host\sharefoo\repo" and another
repository: in addition to it, "\host\share\foo\repo" may be combined
with another repository, if it accidentally exists.
This patch uses "pathutil.normasprefix()" to ensure "os.sep" at the
end of cwd safely, even with some problematic encodings, which use
0x5c (= "os.sep" on Windows) as the tail byte of some multi-byte
characters.
BTW, normalization before "pathutil.normasprefix()" isn't needed in
this case, because "os.getcwd()" always returns normalized one.
Since Python 2.7.9, "os.path.join(path, '')" doesn't add "os.sep" at
the end of UNC path (see issue4557 for detail).
This makes bundlerepo incorrectly work, if:
1. cwd is the root of UNC share (e.g. "\host\share"), and
2. mainreporoot is near cwd (e.g. "\host\sharefoo\repo")
- host of UNC path is same as one of cwd
- share of UNC path starts with one of cwd
3. "repopath" isn't specified in bundle URI
(e.g. "bundle:bundlefile" or just "bundlefile")
For example:
$ hg --cwd \host\share -R \host\sharefoo\repo incoming bundle
In this case:
- os.path.join(r"\host\share", "") returns r"\host\share",
- r"\host\sharefoo\repo".startswith(r"\host\share") returns True, then
- r"foo\repo" is treated as repopath of bundlerepo instead of
r"\host\sharefoo\repo"
This causes failure of combining "\host\sharefoo\repo" and bundle
file: in addition to it, "\host\share\foo\repo" may be combined with
bundle file, if it accidentally exists.
This patch uses "pathutil.normasprefix()" to ensure "os.sep" at the
end of cwd safely, even with some problematic encodings, which use
0x5c (= "os.sep" on Windows) as the tail byte of some multi-byte
characters.
BTW, normalization before "pathutil.normasprefix()" isn't needed in
this case, because "os.getcwd()" always returns normalized one.
419498227287 replaced "os.path.join(root, '')" by
"root.endswith(os.sep)" examination, because Python 2.7.9 changes
behavior of "os.path.join(path, '')" on UNC path.
But some problematic encodings use 0x5c (= "os.sep" on Windows) as the
tail byte of some multi-byte characters, and replacement above
prevents Mercurial from working on the repository, of which root path
ends with such multi-byte character, regardless of enabling win32mbcs.
This patch uses "pathutil.normasprefix()" instead of
"root.endswith(os.sep)" examination, to ensure "os.sep" at the end of
"dirstate._rootdir" even with problematic encodings.
"root" of dirstate can be passed to "pathutil.normasprefix()" without
normalization, because it is always given from "repo.root" =
"repo.wvfs.base", which is normalized by "os.path.realpath()".
Using "util.endswithsep()" instead of "str.endswith(os.sep)" also
fixes this problem, but this patch chooses "pathutil.normasprefix()"
to centralize "adding os.sep if endswith(os.sep)" logic into it.
The pre-pushkey hook will likely validate the pushkey based on element
previously changed in the same transaction. We need to make theses data
available for the hook.
When pushkey is called during a transaction, we include its 'hookargs' when
running the pre-pushkey hooks. Having more data cannot hurt, especially the
transaction ID.
Since transaction are used for more than just changesets, it is possible
to have a transaction without new changesets at all. In this case no
''00changelog.i.a' are written. In all cases the 'changelog.readpending'
method is called if the repository has any pending data. The 'revlog' logic
provides empty content if the file is missing, so the whole operation
resulted in an empty changelog.
We now skip reading the pending file if it is missing.
If 'wlock' is taken, we should add 'afterlock' callback to the 'wlock' instead.
Otherwise, running post transaction hook after 'lock' is release but 'wlock' is
still taken lead to a deadlock (eg: 'hg update' during a hook).
This situation is much more common since: b7067abc16c0
push: acquire local 'wlock' if "pushback" is expected (BC) (issue4596)
Just like 111a38b83cb8 (diff: pass the diff matcher to the copy logic,
2015-04-16) sped up 'hg diff --git $path', let's speed up 'hg st -C
$path'. On the Firefox repo, this speeds up
hg st --rev tip~40000 --rev tip -C python
from 16s to 1.8s. Those two revisions differ in 100k files, out of
which 1k is in python/.
_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
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.
This series tries to fix wrong ancestry information on annotating working
directory. This change should slightly improves the readability of the next
patch.
LockHeld wasn't enough to suppress error during acquiring lock. If .hg directory
is read-only, LockUnavailable will be raised.
$ chmod ugo-w .hg
$ hg identify
abort: could not lock working directory of ...: Permission denied
In case of errors, output parts salvaged from the reply bundle need to be
processed for outputting their content. This concludes our quest for fixing
issue4594.
We are going to add output related logic in this function. We do the
indentation first to help next changeset readability. We need a new try except
because we want to handle output on any exception, including PushRaced ones.
In case of errors, output parts salvaged from the reply bundle are re-injected
into the bundle carrying the exception.
We still need to fix the situation for non-wireprotocol push.