Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 18:31:53 -0700] rev 26464
exchange: expose bundle2 capabilities on pulloperation
This adds a cache and makes accessing the capabilities slightly simpler,
as you don't need to directly go through the bundle2 module. This will
also help prevent a function-level import in streamclone.py.
This patch arguably isn't necessary. But I think it makes things
slightly nicer.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Sun, 04 Oct 2015 21:33:29 +0900] rev 26463
keyword: make restrict mode False while updating files for rollback
This is a preparation for using 'repo.rollback()' instead of aborting
a current running transaction for "shelve" and "unshelve".
Before this patch, updating files as a part of 'repo.rollback()'
overridden by keyword extension always follows 'restrict' mode of the
command currently executed.
"merge", "unshelve" and so on should be 'restrict'-ed, because keyword
expansion may cause unexpected conflicts at merging while these
commands.
But, if 'repo.rollback()' is invoked while executing 'restrict'-ed
commands, modified files in the working directory are marked as
"CLEAN" unexpectedly by code path below:
# 'lookup' below is True at updating modified files for rollback
kwcmd = self.restrict and lookup # kwexpand/kwshrink
:
if kwcmd:
self.repo.dirstate.normal(f)
On the other hand, "rollback" command isn't 'restrict'-ed, because
rollbacking itself doesn't imply merging.
Therefore, disabling 'restrict' mode while updating files as a part of
'repo.rollback()' regardless of current 'restrict' mode should be
reasonable.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 11:34:28 -0700] rev 26462
streamclone: rename and document maybeperformstreamclone()
Upcoming patches will introduce bundle2 based streaming clones. Add
"legacy" to the function name and add a docstring clarifying the intent of
the function.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 11:27:10 -0700] rev 26461
streamclone: move applyremotedata() into maybeperformstreamclone()
Future work around stream cloning will be implemented in a bundle2
world. This code will only be used in the legacy code path and
doesn't need to be abstracted or extensible.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 03 Oct 2015 09:53:56 -0700] rev 26460
branchmap: move branch cache code out of streamclone.py
This is low-level branch map and cache manipulation code. It deserves to
live next to similar code in branchmap.py. Moving it also paves the road
for multiple consumers, such as a bundle2 part handler that receives
branch mappings from a remote.
This is largely a mechanical move, with only variable names and
indentation being changed.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 23:08:15 -0700] rev 26459
streamclone: move streamin() into maybeperformstreamclone()
streamin() only had a single consumer. And it always only ever will
because it is strongly coupled with the current,
soon-to-be-superseded-by-bundle2 functionality.
The return value has been dropped because nobody was using it.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 11:20:52 -0700] rev 26458
streamclone: refactor maybeperformstreamclone to take a pullop
Just like all the other pull steps. Consistency is good.
This seems a little excessive right now since maybeperformstreamclone is
such a short function. This will be addressed in a subsequent patch.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 11:17:43 -0700] rev 26457
demandimport: replace more references to _demandmod instances
_demandmod instances may be referenced by multiple importing modules.
Before this patch, the _demandmod instance only maintained a reference
to its first consumer when using the "from X import Y" syntax. This is
because we only created a single _demandmod instance (attached to the
parent X module). If multiple modules A and B performed
"from X import Y", we'd produce a single _demandmod instance
"demandmod" with the following references:
X.Y = <demandmod>
A.Y = <demandmod>
B.Y = <demandmod>
The locals from the first consumer (A) would be stored in <demandmod1>.
When <demandmod1> was loaded, we'd look at the locals for the first
consumer and replace the symbol, if necessary. This resulted in state:
X.Y = <module>
A.Y = <module>
B.Y = <demandmod>
B's reference to Y wasn't updated and was still using the proxy object
because we just didn't record that B had a reference to <demandmod> that
needed updating!
With this patch, we add support for tracking which modules in addition
to the initial importer have a reference to the _demandmod instance and
we replace those references at module load time.
In the case of posix.py, this fixes an issue where the "encoding" module
was being proxied, resulting in hundreds of thousands of
__getattribute__ lookups on the _demandmod instance during dirstate
operations on mozilla-central, speeding up execution by many
milliseconds. There are likely several other operation that benefit from
this change as well.
The new mechanism isn't perfect: references in locals (not globals) may
likely linger. So, if there is an import inside a function and a symbol
from that module is used in a hot loop, we could have unwanted overhead
from proxying through _demandmod. Non-global imports are discouraged
anyway. So hopefully this isn't a big deal in practice. We could
potentially deploy a code checker that bans use of attribute lookups of
function-level-imported modules inside loops.
This deficiency in theory could be avoided by storing the set of globals
and locals dicts to update in the _demandmod instance. However, I tried
this and it didn't work. One reason is that some globals are _demandmod
instances. We could work around this, but it's a bit more work. There
also might be other module import foo at play. The solution as
implemented is better than what we had and IMO is good enough for the
time being.
It's worth noting that this sub-optimal behavior was made worse by the
introduction of absolute_import and its recommended "from . import X"
syntax for importing modules from the "mercurial" package. If we ever
wrote performance tests, measuring the amount of module imports and
__getattribute__ proxy calls through _demandmod instances would be
something I'd have it check.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 04 Oct 2015 10:36:54 -0700] rev 26456
demandimport: refactor processfromitem
This will match the next patch smaller and easier to read.
Gregory Szorc <gregory.szorc@gmail.com> [Sat, 03 Oct 2015 15:30:17 -0700] rev 26455
demandimport: consolidate code for processing items in fromlist
This code was mostly duplicated. An upcoming patch will add more
complexity, making the duplication harder to justify. Consolidate the
code.
Yuya Nishihara <yuya@tcha.org> [Sat, 03 Oct 2015 15:16:33 +0900] rev 26454
pager: recreate stdout to make it line-buffered
We want to see partial command results as soon as possible. But the buffering
mode of stdout (= pager's stdin) was set to fully-buffered because it isn't
associated with a tty. So, this patch recreates new stdout object to force its
buffering mode.
Because two file objects are associated with the same stdout fd and their
destructors will call close(), one of them must be closed carefully. Python
expects that the stdout fd never be closed even after sys.stdout.close() [1],
but newstdout has no such hack. So this patch calls newstdout.close()
immediately before duplicating the original stdout fd to sys.stdout.
operation sys.stdout newstdout fd
--------------------- ---------- --------- --------
newstdout.close() open closed closed
os.dup2(stdoutfd, ..) open closed open
del sys.stdout closed closed open [1]
[1]: https://hg.python.org/cpython/file/v2.7.10/Python/sysmodule.c#l1391
Yuya Nishihara <yuya@tcha.org> [Sat, 03 Oct 2015 18:48:21 +0900] rev 26453
pager: rename variables of backup fds
The next patch will add backup file objects, so the original variable names
would be confusing.
Yuya Nishihara <yuya@tcha.org> [Sat, 03 Oct 2015 15:02:52 +0900] rev 26452
pager: inline _pagersubprocess() into _runpager()
We don't need _pagersubprocess() because the fork version was removed
at 59d794154e8d.
Yuya Nishihara <yuya@tcha.org> [Sat, 03 Oct 2015 23:10:40 +0900] rev 26451
ui: send traceback of devel warning to appropriate output stream
If ui.ferr is a command-server channel, traceback should be written to it.
Yuya Nishihara <yuya@tcha.org> [Sat, 03 Oct 2015 14:57:24 +0900] rev 26450
util.system: compare fileno to see if it needs stdout redirection
Future patches will reopen stdout to be line-buffered, so sys.stdout may
be different object than sys.__stdout__.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 23:04:52 -0700] rev 26449
exchange: move stream clone logic into pull code path
Stream clones are a special case of clones. Clones are a special case of
pull. Most of the logic for deciding what to do at pull time is in
exchange.py. It makes sense for the stream clone determination to live
there as well.
This patch moves the calling of the stream clone code into pull(). The
checks in streamclone.canperformstreamclone() ensure that we don't
perform a stream clone unless it is possible.
A future patch will convert maybeperformstreamclone() to accept a
pullop to make it consistent with everything else in pull(). It will
also grow some functionality (in case you doubted the necessity of a 4
line function).
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 22:16:34 -0700] rev 26448
exchange: teach pull about requested stream clones
An upcoming patch will move the invocation of stream cloning logic to
the normal pull code path (from localrepository.clone). In preparation
for this, we teach pull() and pulloperation about whether a streaming
clone is requested.
The return logic in localrepository.clone() has been reformatted
slightly because of line length issues.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 21:53:25 -0700] rev 26447
streamclone: add explicit check for empty local repo
Stream clone doesn't work with non-empty local repositories. In upcoming
patches, we'll move stream cloning to the regular pull code path. Add an
explicit check on the repository being empty to prevent streaming clones
to non-empty repos.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 22:22:11 -0700] rev 26446
streamclone: refactor code for deciding to stream clone
Having this in a standalone function will eventually enable bundle2 to
share code with the bundle1 code path.
While I was here, I also added some comments to add clarity.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 21:39:04 -0700] rev 26445
streamclone: move streaming clone logic from localrepo
This is the last remnants of streaming clone code in localrepo.py.
This is a mostly mechanical transplant of code to a new file. Only a
rewrite of "self" to "repo" was performed. The code will be
significantly refactored in upcoming patches. So don't scrutinize it too
closely.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 16:24:56 -0700] rev 26444
streamclone: move _allowstream() from wireproto
While we're moving things into streamclone.py...
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 16:05:52 -0700] rev 26443
streamclone: move code out of exchange.py
We bulk move functions from exchange.py related to streaming clones.
Function names were renamed slightly to drop a component redundant with
the module name. Docstrings and comments referencing old names and
locations were updated accordingly.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 15:58:24 -0700] rev 26442
streamclone: move stream_in() from localrepo
Another basic content move. The underscore from the function name was
removed to comply with naming standards.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 15:51:32 -0700] rev 26441
streamclone: move applystreamclone() from localrepo.py
Upcoming patches will modernize the streaming clone code. Streaming
clone data and code kind of lives in its own world. exchange.py is
arguably the most appropriate existing location for it. However, over
a dozen patches from now it became apparent that there was a lot of code
related to streaming clones and that having it contained within its own
module would make it easier to comprehend. So, we establish
streamclone.py.
It's worth noting that streamclone.py existed a long time ago, last seen
in the 1.6 release. It was removed in 04f76a954842.
The function was renamed as part of the move because its old name was
redundant with the new module name. The only other content change was
"self" was renamed to "repo" and minor grammar in the docstring was
updated.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 02 Oct 2015 15:36:00 -0700] rev 26440
exchange: add docstring to pull()
This seems like the kind of important function that should be documented
better.
Siddharth Agarwal <sid0@fb.com> [Fri, 25 Sep 2015 12:28:12 -0700] rev 26439
localrepo: allow creating inherited locks
This is part of a series that will allow locks to be inherited by subprocesses
in limited circumstances.
Siddharth Agarwal <sid0@fb.com> [Fri, 25 Sep 2015 12:56:05 -0700] rev 26438
error: make lock inheritance contract violations a subclass of RuntimeError
This is more appropriate, per Pierre-Yves David.
Yuya Nishihara <yuya@tcha.org> [Sat, 26 Sep 2015 12:19:39 +0900] rev 26437
templatekw: hide help of "branches" by DEPRECATED marker
See 43e872a35f8a for details.
Yuya Nishihara <yuya@tcha.org> [Sat, 26 Sep 2015 12:39:13 +0900] rev 26436
templatekw: remove dockeywords hack
Now all template keywords are defined as real functions.
Yuya Nishihara <yuya@tcha.org> [Sat, 26 Sep 2015 12:38:02 +0900] rev 26435
templatekw: port implementation of showparents() from changeset_templater
It isn't cool, but we can peek at ui flag via repo.ui. So, it is possible
to implement showparents() in templatekw, and therefore we can eliminate the
dockeywords hack.