Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Dec 2015 21:25:05 -0800] rev 27225
mercurial: support loading modules from zipimporter
The previous refactor to module importing broke module loading when
mercurial.* modules were loaded from a zipfile (using a zipimporter).
This scenario is likely encountered when using py2exe.
Supporting zipimporter and the traditional importer side-by-side
turns out to be quite a pain. In Python 2.x, the standard, file-based
import mechanism is partially implemented in C. The sys.meta_path
and sys.path_hooks hook points exist to allow custom importers in
Python/userland. zipimport.zipimporter and our "hgimporter" class
from earlier in this patch series are 2 of these.
In a standard Python installation (no matter if running in py2exe
or similar or not), zipimport.zipimporter appears to be registered
in sys.path_hooks. This means that as each sys.path entry is
consulted, it will ask zipimporter if it supports that path and
zipimporter will be used if that entry is a zip file. In a
py2exe environment, sys.path contains an entry with the path to
the zip file containing the Python standard library along with
Mercurial's Python files.
The way the importer mechanism works is the first importer that
declares knowledge of a module (via find_module() returning an
object) gets to load it. Since our "hgimporter" is registered
in sys.meta_path and returns an interest in specific mercurial.*
modules, the zipimporter registered on sys.path_hooks never comes
into play for these modules. So, we need to be zipimporter aware
and call into zipimporter to load modules.
This patch teaches "hgimporter" how to call out into zipimporter
when necessary. We detect the necessity of zipimporter by looking
at the loader for the "mercurial" module. If it is a zipimporter
instance, we load via zipimporter.
The behavior of zipimporter is a bit wonky.
You appear to need separate zipimporter instances for each directory
in the zip file. I'm not sure why this is. I suspect it has
something to do with the low-level importing mechanism (implemented
in C) operating on a per-directory basis. PEP-302 makes some
references to this. I was not able to get a zipimporter to
import modules outside of its immediate directory no matter how
I specified the module name. This is why we use separate
zipimporter instances for the ".zip/mercurial" and
".zip/mercurial/pure" locations.
The zipimporter documentation for Python 2.7 explicitly states that
zipimporter does not import dynamic modules (C extensions). Yet from
a py2exe distribution on Windows - where the .pyd files are *not*
in the zip archive - zipimporter imported these dynamic modules
just fine! I'm not sure if dynamic modules can't be imported from
*inside* the zip archive or whether zipimporter looks for dynamic
modules outside the zip archive. All I know is zipimporter does
manage to import the .pyd files on Windows and this patch makes
our new importer compatible with py2exe.
In the ideal world, We'd probably reimplement or fall back to parts
of the built-in import mechanism instead of handling zipimporter
specially. After all, if we're loading Mercurial modules via
something that isn't the built-in file-based importer or zipimporter,
our custom importer will likely fail because it doesn't know how to
call into it. I'd like to think that we'll never encounter this
in the wild, but you never know. If we do encounter it, we can
come up with another solution.
It's worth nothing that Python 3 has moved a lot of the importing
code from C to Python. Python 3 gives you near total control over
the import mechanism. So in the very distant future when Mercurial
drops Python 2 support, it's likely that our custom importer code
can be refactored to something a bit saner.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 22:21:51 -0800] rev 27224
mercurial: don't load C extensions from PyPy
PyPy isn't compatible with Python C extensions.
With this patch, the module load policy is automatically to "Python
only" when run under PyPy. `hg` and other Python scripts importing
mercurial.* modules will run from the source checkout or any
installation when executed with PyPy. This should enable people to
more easily experiment with PyPy and its potentially significant
performance benefits over CPython!
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 22:50:04 -0800] rev 27223
mercurial: be more strict about loading dual implemented modules
With this change in place, we should have slightly stronger guarantees
about how modules with both Python and C implementations are loaded.
Before, our module loader's default policy looked under both mercurial/*
and mercurial/pure/* and imported whatever it found, C or pure. The fact
it looked in both locations by default was a temporary regression from
the beginning of this series.
This patch does 2 things:
1) Changes the default module load policy to only load C modules
2) Verifies that files loaded from mercurial/* are actually C modules
This 2nd behavior change makes our new module loading mechanism
stricter than from before this series. Before, it was possible to load
a .py-based module from mercurial/*. This could happen if an old
installation orphaned a file and then somehow didn't install the C
version for the new install. We now detect this odd configuration
and fall back to loading the pure Python module, assuming it is
allowed. In the case of a busted installation, we fail fast. While
we could fall back, we explicitly decide not to do this because
we don't want people accidentally not running the C modules and having
slow performance as a result.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Dec 2015 21:48:12 -0800] rev 27222
setup: refactor handling of modules with C/Python implementations
Previously, .py files under mercurial/pure/ were copied to mercurial/*
during installation if we were performing a pure Python installation.
Now that the new import hooks and module load policy are in place, this
hackery from the past is no longer necessary.
With this patch, we stop copying modules from mercurial/pure/* to
mercurial/*. Instead, we preserve the files at their original
hierarchy, mirroring the source repository structure.
In addition, we always install the pure modules. Before, we would only
include the pure modules in the distribution/installation if the
install-time settings requested a pure Python installation. The upside
of this change is that CPython and PyPy can run from the same Mercurial
installation, making packaging and distribution of Mercurial simpler.
The inclusion of pure Python modules in the installation sounds
risky, as it could lead to inadvertent loading of non-C modules.
This shouldn't be a problem. The default module load policy is "C
only" (or at least will be shortly) and the only way to load pure
modules from an installation is if a) pure installation was requested
b) the HGMODULELOADPOLICY overrides the requirement for C modules.
The default module load policy as defined in source is a special string
whose default value from the checkout is equivalent to the "C only"
policy (again, not exactly the state right now). For pure
installations, this default policy is not appropriate and will not
work. This patch adds support for rewriting __init__.py during
installation to reflect the module load policy that should be in
place accoding to the installation settings. For default CPython
installs, the value in the source file will change but there will
be no functional change. For pure installations, the default policy
will be set to "py," allowing them to work without having to set
environment variables.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 22:53:55 -0800] rev 27221
check-seclevel: set module load policy to Python only
If we don't change this, the upcoming change to make the module
loading policy only load C modules will cause this script to fail if
run with CPython against an unbuilt source checkout.
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 03 Dec 2015 21:37:01 -0800] rev 27220
mercurial: implement import hook for handling C/Python modules
There are a handful of modules that have both pure Python and C
extension implementations. Currently, setup.py copies files from
mercurial/pure/*.py to mercurial/ during the install process if C
extensions are not available. This way, "import mercurial.X" will
work whether C extensions are available or not.
This approach has a few drawbacks. First, there aren't run-time checks
verifying the C extensions are loaded when they should be. This could
lead to accidental use of the slower pure Python modules. Second, the
C extensions aren't compatible with PyPy and running Mercurial with
PyPy requires installing Mercurial - you can't run ./hg from a source
checkout. This makes developing while running PyPy somewhat difficult.
This patch implements a PEP-302 import hook for finding and loading the
modules with both C and Python implementations. When a module with dual
implementations is requested for import, its import is handled by our
import hook.
The importer has a mechanism that controls what types of modules we
allow to load. We call this loading behavior the "module load policy."
There are 3 settings:
* Only load C extensions
* Only load pure Python
* Try to load C and fall back to Python
An environment variable allows overriding this policy at run time. This
is mainly useful for developers and for performing actions against the
source checkout (such as installing), which require overriding the
default (strict) policy about requiring C extensions.
The default mode for now is to allow both. This isn't proper and is
technically backwards incompatible. However, it is necessary to
implement a sane patch series that doesn't break the world during
future bisections. The behavior will be corrected in future patch.
We choose the main mercurial/__init__.py module for this code out of
necessity: in a future world, if the custom module importer isn't
registered, we'll fail to find/import certain modules when running
from a pure installation. Without the magical import-time side-effects,
*any* importer of mercurial.* modules would be required to call a
function to register our importer. I'm not a fan of import time side
effects and I initially attempted to do this. However, I was foiled by
our own test harness, which has numerous `python` invoked scripts that
"import mercurial" and fail because the importer isn't registered.
Realizing this problem is probably present in random Python scripts
that have been written over the years, I decided that sacrificing
purity for backwards compatibility is necessary. Plus, if you are
programming Python, "import" should probably "just work."
It's worth noting that now that we have a custom module loader, it
would be possible to hook up demand module proxies at this level
instead of replacing __import__. We leave this work for another time,
if it's even desired.
This patch breaks importing in environments where Mercurial modules
are loaded from a zip file (such as py2exe distributions). This will
be addressed in a subsequent patch.
Augie Fackler <augie@google.com> [Thu, 03 Dec 2015 10:56:05 -0500] rev 27219
changegroup: document manifest linkrev callback some more
Martin and I just got super-confused reading some code here, so I
think it's time for some more documentation.
Augie Fackler <augie@google.com> [Wed, 02 Dec 2015 14:32:17 -0500] rev 27218
changegroup: note during bundle apply if the repo was empty
An upcoming change for exchanging treemanifest data will need to
update the repository capabilities, which we should only do if the
repository was empty before we started applying this changegroup. In
the future we will probably need a strategy for upgrading to
treemanifest in requires during a pull (I'm assuming at some point
we'll make it possible to have a flag day to enable treemanifests on
an existing history.)
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 07:41:35 +0000] rev 27217
histedit: improve missing rule suggestion
include actual suggested text
Yuya Nishihara <yuya@tcha.org> [Sat, 14 Nov 2015 17:25:43 +0900] rev 27216
graphlog: make node symbol templatable by ui.graphnodetemplate option
New ui.graphnodetemplate option allows us to colorize a node symbol by phase
or branch,
[ui]
graphnodetemplate = {label('graphnode.{phase}', graphnode)}
[color]
graphnode.draft = yellow bold
or use a variety of unicode emoji characters, and so on. (You'll need less-481
to display non-BMP unicode character.)
[ui]
graphnodetemplate = {ifeq(obsolete, 'stable', graphnode, '\xf0\x9f\x92\xa9')}
Yuya Nishihara <yuya@tcha.org> [Sat, 14 Nov 2015 17:02:57 +0900] rev 27215
templatekw: avoid slow creation of changectx objects in showgraphnode()
This mitigates the minor perf regression introduced by the previous patch.
% hg log -G -R mozilla-central -l10000 --time > /dev/null
(original) real 2.200 secs
(previous) real 2.590 secs
(this) real 2.280 secs
Yuya Nishihara <yuya@tcha.org> [Sat, 14 Nov 2015 16:58:18 +0900] rev 27214
graphlog: extract "graphnode" template keyword that represents node symbol
This provides a default node symbol. Tests will be added later.
"showparents" variable is renamed to "wpnodes" to avoid confusion with the
existing showparents() function.
Yuya Nishihara <yuya@tcha.org> [Sat, 14 Nov 2015 16:45:15 +0900] rev 27213
graphlog: move creation of workingdir-parent nodes to displaygraph()
Future patches will make a node symbol templatable. Because arguments of a
templatekw function are repo and ctx, "showparents" list will have to be
built from a repo object by that function.
Anton Shestakov <av6@dwimlabs.net> [Wed, 25 Nov 2015 18:07:33 +0800] rev 27212
builddeb: read default distribution and codename from lsb_release
This makes `make deb` place packages into a more appropriately named directory
instead of just "debian-unknown".
Anton Shestakov <av6@dwimlabs.net> [Wed, 25 Nov 2015 15:26:03 +0800] rev 27211
builddeb: remove unused --debbuilddir option
Looks like it was never used and after 7f49efcaa9b4 it can be removed.
Anton Shestakov <av6@dwimlabs.net> [Wed, 25 Nov 2015 15:15:03 +0800] rev 27210
builddeb: add --distid option to specify Distributor ID
This allows builddeb to handle distributions that are not Debian.
Distributor ID is reported by lsb_release --id, and in case of builddeb it's
usually Debian or Ubuntu.
Anton Shestakov <av6@dwimlabs.net> [Wed, 25 Nov 2015 14:59:43 +0800] rev 27209
builddeb: rename --release option to --codename
Debian and Ubuntu releases have both codenames and traditional version numbers.
An entire "branch" of releases is referred to by its codename, and version
numbers (e.g. 8.2, 14.04.3) are used to address individual releases.
Since we use codenames for building .deb packages, let's call the option and
the variable appropriately.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27208
histedit: get rid of state.rules
Now we are using state.actions instead of state.rules everywhere.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27207
histedit: change state.rules uses to state.actions
This change is replacing most of state.rules uses with state.actions
uses. The next change will change histeditstate class to actually
uses state actions.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27206
histedit: add tostate method to histedit action
the format of rules that we store in state file format is different from the rule
format that we present to users. We need a way of dumping action to state file.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27205
histedit: remove makedesc
It's a dead code now.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27204
histedit: use torule instead of makedesc in ruleeditor
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27203
histedit: add torule method to histedit action objects
To make histedit action objects responsible for understanding
the format of their action lines we are adding a torule method
which for a histedit action will return a string which can be
saved in histedit state or shown in text editor when editing the
plan.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27202
histedit: add verify() to histeditaction
This commits splits the parsing of the histedit rule from its semantic analysis.
It's necessary because sometimes we want to do first without doing the former (reading the
histedit state).
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27201
histedit: add addhisteditaction decorator
This decorator will is allowing us to move the registering the action
in actiontable closer to the action code. Also it is storing the
verb inside histedit action so the action is aware of the verb
needed to trigger it.
Mateusz Kwapich <mitrandir@fb.com> [Wed, 02 Dec 2015 12:19:01 -0800] rev 27200
histedit: add actions property to histedit state
I want to refactor histedit to use action objects instead of (verb, rest)
pairs whenever possible. At the end of this series I want the rules to
be translated into action objects when reading state and translated back
when writing state. All histedit internals should use action objects instead
of state rules.
To migrate histedti internals sequentially I'm introducing the state.actions
property to translate rules on the fly so we can use both state.actions and
state.rules until refactoring is done.
Pierre-Yves David <pierre-yves.david@fb.com> [Fri, 06 Nov 2015 17:27:42 -0500] rev 27199
check-commit: remove confusion between summary line and other headers
The pull url header can easily grow over 80 chars. The check-commit script was
confusing this with a too long summary line. We update the regular expression to
not match other header.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:08 +0900] rev 27198
shelve: execute checkunfinished inside wlock scope
Before this patch, "hg shelve" of shelve extension executes
'cmdutil.checkunfinished()' before acquisition of wlock.
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
To avoid this issue, this patch executes 'cmdutil.checkunfinished()'
inside wlock scope of "hg shelve".
This also fixes issue4957, because now 'cmdutil.checkunfinished()'
isn't invoked at "hg shelve" with options below:
--cleanup
--delete
--list
--patch
--stat
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:08 +0900] rev 27197
shelve: widen wlock scope of shelve for consistency while processing
Before this patch, "hg shelve" of shelve extension executes/refers
below before acquisition of wlock:
- 'repo.dirstate.parents()' via 'repo[None].parents()'
- 'repo._activebookmark'
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
This patch widens wlock scope of "hg shelve" of shelve extension for
consistency while processing.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:08 +0900] rev 27196
gpg: make sign acquire wlock before processing
Before this patch, "hg sign" of gpg extension executes/evaluates below
without acquisition of wlock.
- repo.dirstate.parents()
- '.hgsigs' not in repo.dirstate
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
To avoid this issue, this patch makes "hg sign" of gpg extension
acquire wlock before processing.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:08 +0900] rev 27195
commands: execute checkunfinished and bailifchanged inside wlock scope
Before this patch, "hg import" executes below before acquisition of
wlock:
- cmdutil.checkunfinished()
- cmdutil.bailifchanged()
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
To avoid this issue, this patch executes 'cmdutil.checkunfinished()'
and 'cmdutil.bailifchanged()' inside wlock scope of "hg import".
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:07 +0900] rev 27194
commands: widen wlock scope of graft for consitency while processing
Before this patch, "hg graft" executes below before acquisition of
wlock.
- cmdutil.checkunfinished()
- cmdutil.bailifchanged()
- repo.dirstate.parents() via 'repo["."]'
- unlinking '.hg/graftstate'
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
This patch widens wlock scope of "hg graft" for consitency while
processing.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:07 +0900] rev 27193
commands: make backout acquire locks before processing
Before this patch, "hg backout" executes below before acquisition of
wlock.
- cmdutil.checkunfinished()
- cmdutil.bailifchanged()
- repo.dirstate.parents()
It may cause unintentional result, if another command runs parallelly
(see also issue4368).
In addition to it, "hg backout" refers changelog for purposes below
without acquisition of store lock (slock), and it may cause
unintentional result, if store is updated parallelly.
- show and update to the revision by 'repo.changelog.tip()'
- examine for "created new head" by 'repo.branchheads()' and
'cmdutil.commitstatus()'
To avoid this issue, this patch makes "hg backout" acquire wlock and
slock before processing.
FUJIWARA Katsunori <foozy@lares.dti.ne.jp> [Wed, 02 Dec 2015 03:12:07 +0900] rev 27192
commands: make commit acquire locks before processing (issue4368)
Before this patch, "hg commit" (process A) executes steps below:
1. get current branch heads via 'repo.branchheads()'
- cache 'repo.changelog'
2. invoke 'repo.commit()'
3. acquire wlock
- invalidate 'repo.dirstate'
4. access 'repo.dirstate'
- re-read '.hg/dirstate'
- check validity of parent revisions with 'repo.changelog'
5. invoke 'repo.commitctx()'
6. acquire store lock (slock)
- invalidate 'repo.changelog'
7. do committing
8. release slock
9. release wlock
10. check new branch head (via 'cmdutil.commitstatus()')
If acquisition of wlock at (3) above waits for another "hg commit"
(process B) or so running parallelly to release wlock, process A
causes creating orphan revision, because:
- '.hg/dirstate' refers the revision, which is newly added by
process B, as its parent
- but already cached 'repo.changelog' doesn't contain such revision
- therefore, validating parents of '.hg/dirstate' at (4) above
replaces such revision with 'nullid'
Then, process A creates "orphan" revision, of which parent is "null"
revision.
In addition to it, "created new head" may be shown at the end of
process A unintentionally, if store is updated parallelly, because
both getting branch heads (1) and checking new branch head (10) are
executed outside slock scope.
To avoid this issue, this patch makes "hg commit" acquire wlock and
slock before processing.
This patch resolves the issue between "hg commit" processes, but not
one between "hg commit" and other commands. Subsequent patches resolve
the latter.
Even after this patch, there are still corner case problems below:
- filecache may overlook changes of '.hg/dirstate', and it causes
similar issue (see below for detail)
https://bz.mercurial-scm.org/show_bug.cgi?id=4368#c10
- 3rd party extension may cause similar issue, if it directly uses
'repo.commit()' without acquisition of wlock and slock
This can be fixed by acquisition of slock at the beginning of
'repo.commit()', but it seems suitable for "default" branch
In fact, acquisition of slock itself is already introduced at
"default" branch by 4414d500604f, but acquisition is not at the
beginning of 'repo.commit()'.
This patch also changes some tests:
- test-fncache.t needs this tricky wrapping, to release (= forced
failure of) wlock certainly
- order of "hg commit" output is changed by widening scope of locks,
because some hooks are fired after releasing wlock
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 16:15:59 -0800] rev 27191
addrevision: use general delta when the incoming base delta is bad
We unify the delta selection process to be a simple three options process:
- try to use the incoming delta (if lazydeltabase is on)
- try to find a suitable parents to delta against (if gd is on)
- try to delta against the tipmost revision
The first of this option that yield a valid delta will be used.
The test change in 'test-generaldelta.t' show this behavior as we use a delta
against the parent instead of a full delta when the incoming delta is not
suitable.
This as some impact on 'test-bundle.t' because a delta somewhere changes. It
does not seems to change the test semantic and have been ignored.
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 18:11:00 -0800] rev 27190
test: use a bigger manifest in general delta test
The currently used manifest is too small and cannot sustain a chain length
above "1". This make testing the 'lazybasedelta' behavior hard. So we add an
extra file in the manifest to help testing in the next changeset.
The semantic of existing tests have been checked and is not changed.
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 18:45:16 -0800] rev 27189
addrevision: rework generaldelta computation
The old code have multiple explicit tests and code duplications. This makes it
hard to improve the code. We rewrite the logic in a more generic way, not
changing anything of the computed result.
The final goal here is to eventually be able to:
- factor out the default fallback case "try against 'prev'" in a single place
- allow 'lazydeltabase' case to use the smarter general delta code path when
the incoming base does not provide us with a good delta.
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 21:03:48 -0500] rev 27188
bmstore: close file in a finally block in _writerepo
Also rename the variable to file_ to avoid shadowing a builtin.
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 21:01:23 -0500] rev 27187
bmstore: add basic clean-state tracking
I'm about to move active-bookmark management into the bmstore. I'd
like to avoid re-writing the bookmarks data (as distinct from the
active bookmark file) if possible, so let's introduce some
dirty-tracking early.
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 20:45:38 -0500] rev 27186
bookmarks: hoist getbkfile out of bmstore class
It's totally fine that this hook exists, but I don't see a need for it
to live inside the bmstore class.
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 20:43:25 -0500] rev 27185
bookmarks: document getbkfile method
I'm working on bmstore again, and this function gave me a moment's
pause. Document it to save future readers from any undue confusion.
Yuya Nishihara <yuya@tcha.org> [Sat, 31 Oct 2015 22:50:03 +0900] rev 27184
hgweb: load server settings from --web-conf (issue4699)
It copies the ui before loading the webconf and passes the copied ui only
to the service. This way, the hgwebdir app can reload configs cleanly.
Andrew Zwicky <andrew.zwicky@gmail.com> [Tue, 17 Nov 2015 16:42:52 -0600] rev 27183
extdiff: correctly handle deleted subrepositories (issue3153)
Previously, when extdiff was called on two changesets where
a subrepository had been removed, an unexpected KeyError would
be raised.
Now, the missing subrepository will be ignored. This behavior
mirrors the behavior in diffordiffstat from cmdutil.py line
~1138-1153. The KeyError is caught and the revision is
set to None.
try/catch of LookupError around matchmod.narrowmatcher and
sub.status is removed, as LookupError is not raised anywhere
within those methods or deeper calls.
Yuya Nishihara <yuya@tcha.org> [Sat, 21 Nov 2015 13:28:12 +0900] rev 27182
hgweb: make sure command options are set to all ui objects
Before this patch, it was unclear why the httpservice object could read the
server options (e.g. --port) from 'ui'. It just worked because repo.ui is ui.
Yuya Nishihara <yuya@tcha.org> [Sat, 31 Oct 2015 22:26:50 +0900] rev 27181
hgweb: eliminate duck-typing to select hgweb or hgwebdir by command option
Since createservice() was moved to hgweb and hgweb imports both hgweb_mod and
hgwebdir_mod, we no longer have to force hgweb() function to select one of
them by the type of 'o' variable. Let's be explicit!
This patch does not change hgweb() function because it is the interface of
existing WSGI and CGI scripts.
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 16:06:20 -0800] rev 27180
addrevision: only use the incoming base if it is a good delta (issue4975)
Before this change, the 'lazydeltabase' would blindly build a delta using the
base provided by the incoming bundle and try to use it. If that base was far
down the revlog, the delta would be seen as "no good" and we would fall back to
a full text revision.
We now check if the delta is good and fallback to a computing a delta again the
tipmost revision otherwise (as we would do without general delta).
Later changesets will improve the logic to compute the fallback delta using the
general delta logic.
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 16:22:49 -0800] rev 27179
addrevision: handle code path not producing delta
We would like to be able to exit the delta generation block without a valid
delta (for a more flexible control flow). So we make sure we do not expand the
"delta" content unless we actually have a delta.
We can do it one level lower because 'delta' is initialised at None anyway. Not
adding a level to the assignment prevent a line length issue.
Pierre-Yves David <pierre-yves.david@fb.com> [Tue, 01 Dec 2015 15:29:11 -0800] rev 27178
addrevision: rename 'd' to 'delta'
That variable is quite central to the whole function. Giving it a more explicit
name help with code readability.
Christian Delahousse <cdelahousse@fb.com> [Mon, 30 Nov 2015 11:23:15 -0800] rev 27177
strip: add a --keep test related to removing files from dirstate
When strip builds the list of changedfiles to pass into dirstate.rebuild, it adds
files blindly, including those that have been removed. This tests ensures that
rebuild can handle this case.
Christian Delahousse <cdelahousse@fb.com> [Mon, 30 Nov 2015 11:23:15 -0800] rev 27176
dirstate: change debugrebuilddirstate --minimal to use dirstate.rebuild
When debugrebuilddirstate --minimal is called, rebuilding the dirstate was done
outside of the appropriate rebuild function. This patch makes
debugrebuilddirstate use dirstate.rebuild.
This was done to allow our extension to become aware debugrebuilddirstate
--minimal
Christian Delahousse <cdelahousse@fb.com> [Tue, 01 Dec 2015 10:52:36 -0800] rev 27175
debugrebuilddirstate: added tests for --minimal flag
Added tests for debugrebuilddirstate --minimal.
Christian Delahousse <cdelahousse@fb.com> [Tue, 01 Dec 2015 11:17:14 -0800] rev 27174
debugdirstate: add command to rebuildstate test to modify dirstate
Debugging the dirstate helps if you have options to add files for normal lookup
or drop them from the dirstate. This patch adds a convenience command to
test-rebuilddirstate.t to modify the dirstate. It will be used in the next patch
to write proper tests for debugrebuilddirstate --minimal
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 06:33:52 +0000] rev 27173
graft: improve --continue abort message
before, if you ran hg graft --user ... --date ... --log ... revs,
and if it failed, it would suggest "hg graft --continue",
but if you did that, your --user / --date / --log options
were lost, because they were not persisted anywhere...
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 06:31:12 +0000] rev 27172
summary: mention graft
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 08:07:36 +0000] rev 27171
histedit: mention histedit-last-edit.txt on abort
Users may spend a lot of effort writing histedit rules,
getting an abort without being told they can recover their work
is very frustrating.
Avoid that by telling them where to find their work.
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 07:40:42 +0000] rev 27170
histedit: add missing raise keyword to statement
timeless <timeless@mozdev.org> [Wed, 02 Dec 2015 07:39:49 +0000] rev 27169
histedit: improve grammar for _histedit comment
Augie Fackler <augie@google.com> [Tue, 01 Dec 2015 14:44:08 -0500] rev 27168
test-fncache: ensure lock doesn't look held to __del__
This was showing a DeprecationWarning on Python 2.6.
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 20:07:15 -0500] rev 27167
commands: inline definition of localrepo.parents() and drop the method (API)
localrepo.parents() has relatively few users, and most of those were
actually implicitly looking at the wctx, which is now made explicit
via repo[None].
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 20:02:05 -0500] rev 27166
localrepo: document nodebookmarks
Augie Fackler <augie@google.com> [Wed, 11 Nov 2015 19:47:49 -0500] rev 27165
localrepo: remove clone method by hoisting into hg.py
hg.py was the only remaining caller of localrepo.clone(), so it's time
to move some more behavior out of localrepo.
Siddharth Agarwal <sid0@fb.com> [Tue, 01 Dec 2015 09:48:38 -0800] rev 27164
filemerge: default regular prompts to 'leave unresolved' (BC)
It makes far more sense to leave these conflicts unresolved and kick back to
the user than to just assume that the local version be chosen. There are almost
certainly buggy scripts and applications using Mercurial in the wild that do
merges or rebases non-interactively, and then assume that if the operation
succeeded there's nothing the user needs to pay attention to.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 13:43:55 -0800] rev 27163
filemerge: add a 'leave unresolved' option to change/delete prompts
We're going to make this option the default in an upcoming patch.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 11:17:18 -0800] rev 27162
filemerge: add a 'leave unresolved' option to regular prompts
'Regular' here means anything that isn't a change/delete prompt. We'll add this
option to change/delete prompts in a subsequent patch.
Siddharth Agarwal <sid0@fb.com> [Wed, 25 Nov 2015 14:25:26 -0800] rev 27161
filemerge: add debug output for whether this is a change/delete conflict
Just like binary and symlink conflicts, change/delete conflicts influence the
tool picked.
Anton Shestakov <av6@dwimlabs.net> [Sat, 28 Nov 2015 17:06:29 +0800] rev 27160
webcommands: test that fctx is not None in filediff()
A block of code above this one already says "if fctx is not None", and it's
also what this code actually intends to check, so let's be specific as PEP-8
recommends.
Anton Shestakov <av6@dwimlabs.net> [Sat, 28 Nov 2015 16:46:31 +0800] rev 27159
webcommands: stop using ersatz if-else ternary operator for rename variable
6ddc86eedc3b didn't remove it, let's do it now.
Placing the added lines into the already existing "if fctx is not None" block
also makes webcommands.comparison() look a bit more like
webcommands.filediff(), which eases possible future refactoring. And fctx is
not None only when path in ctx, so logically it's equivalent.
Anton Shestakov <av6@dwimlabs.net> [Sat, 28 Nov 2015 16:02:22 +0800] rev 27158
webcommands: get correct parents when comparing a removed file (issue4962)
When comparing a file that was removed at the current revision, parents used to
show grandparents instead, due to how fctx was "shifted" from the current
revision to its p1. Let's not do that.
The fix is pretty much copied from webcommands.filediff().
Laurent Charignon <lcharignon@fb.com> [Mon, 30 Nov 2015 16:38:29 -0800] rev 27157
repair: use bookmarks.recordchange instead of bookmarks.write
Before this patch we were using the deprecated bookmarks.write api. This
patch replaces the call to bookmarks.write by a call to bookmarks.recordchange.
We move the bookmark code above the code removing the undo file because with
bookmarks.recordchange we have to create a transaction that would create an
undo file.
Laurent Charignon <lcharignon@fb.com> [Mon, 30 Nov 2015 16:37:42 -0800] rev 27156
commit: add amend mode for commit -i
When I moved crecord into core, I didn't include the toggleAmend function (to
switch from commit to amend mode). I did it because it would have made it more
difficult to use record and crecord interchangably. This patch reintroduces the
amend mode for commit -i as well as two tests to verify the behavior of the
function.
Laurent Charignon <lcharignon@fb.com> [Mon, 30 Nov 2015 16:35:21 -0800] rev 27155
commit: add a way to return more information from the chunkselector
Before this patch, the chunkselector for record or crecord was used to return
the list of hunks that were selected by the user. The goal of this series is to
reintroduce the toggle amend feature for crecord. To do so, we need to be able
to return more than just the selected hunks from the chunkselector but also
the information: is amend mode toggled. This patch adds a new return value for
chunkselectors that will be used to implement the toggle amend feature in
crecord.
Mykola Nikishov <mn@mn.com.ua> [Sat, 21 Nov 2015 17:40:26 +0200] rev 27154
histedit: edit with custom filename
For instance, Emacs allows to open file with special features enabled
(AKA mode) based on the path/name of the file [1]. For such cases, use
'hg-histedit-XXX.txt' as filename pattern.
[1] https://www.gnu.org/software/emacs/manual/html_node/emacs/Choosing-Modes.html
Mykola Nikishov <mn@mn.com.ua> [Sat, 21 Nov 2015 22:04:09 +0200] rev 27153
ui: allow open editor with custom filename
By default, editor will use temp file named after hard-coded pattern
'hg-editor-XXX.txt' which makes it impossible for extensions to use
another filename if desired.
Now the middle part of the pattern ('editor') can be changed by
setting extra['prefix'].
timeless <timeless@mozdev.org> [Mon, 30 Nov 2015 20:45:07 +0000] rev 27152
help: make help deprecated mention the extension
before this, you got an empty list of extensions, which was unhelpful
timeless <timeless@mozdev.org> [Mon, 30 Nov 2015 20:44:22 +0000] rev 27151
help: make listexts less confusing for deprecated exts
Return an empty array instead of a heading and no items
timeless <timeless@mozdev.org> [Sun, 29 Nov 2015 06:51:23 +0000] rev 27150
patchbomb: rename email function
I see no reason for the function not to be email ...
timeless <timeless@mozdev.org> [Sun, 29 Nov 2015 06:51:23 +0000] rev 27149
graphlog: rename glog function
I see no reason for the function not to be glog ...
Mike Edgar <adgar@google.com> [Sat, 28 Nov 2015 04:11:57 -0500] rev 27148
commit: preserve extra when amending with commit --amend
The new extra propagation needs to be accounted for in cmdutil.amend,
when checking for a no-changes fast-path.
Mike Edgar <adgar@google.com> [Sat, 28 Nov 2015 04:11:38 -0500] rev 27147
graft: copy extra (except branch) when copying changesets
Mike Edgar <adgar@google.com> [Sat, 28 Nov 2015 04:11:14 -0500] rev 27146
rebase: propagate extra dict from rebase source changeset
This corrects extra propagation for the rebase command and the shelve command.
Mathias De Maré <mathias.demare@gmail.com> [Wed, 25 Nov 2015 18:26:48 +0100] rev 27145
histedit: add examples
Mathias De Maré <mathias.demare@gmail.com> [Wed, 25 Nov 2015 18:10:59 +0100] rev 27144
commands: add examples for 'addremove'
Mathias De Maré <mathias.demare@gmail.com> [Wed, 25 Nov 2015 18:10:31 +0100] rev 27143
commands: add example for 'hg add'
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 15:16:25 -0800] rev 27142
extensions: refuse to load extensions if minimum hg version not met
As the author of several 3rd party extensions, I frequently see bug
reports from users attempting to run my extension with an old version
of Mercurial that I no longer support in my extension. Oftentimes, the
extension will import just fine. But as soon as we run extsetup(),
reposetup(), or get into the guts of a wrapped function, we encounter
an exception and abort. Today, Mercurial will print a message about
extensions that don't have a "testedwith" declaring explicit
compatibility with the current version.
The existing mechanism is a good start. But it isn't as robust as I
would like. Specifically, Mercurial assumes compatibility by default.
This means extension authors must perform compatibility checking in
their extsetup() or we wait and see if we encounter an abort at
runtime. And, compatibility checking can involve a lot of code and
lots of error checking. It's a lot of effort for extension authors.
Oftentimes, extension authors know which versions of Mercurial there
extension works on and more importantly where it is broken.
This patch introduces a magic "minimumhgversion" attribute in
extensions. When found, the extension loading mechanism will compare
the declared version against the current Mercurial version. If the
extension explicitly states we require a newer Mercurial version, a
warning is printed and the extension isn't loaded beyond importing
the Python module. This causes a graceful failure while alerting
the user of the compatibility issue.
I would be receptive to the idea of making the failure more fatal.
However, care would need to be taken to not criple every hg command.
e.g. the user may use `hg config` to fix the hgrc and if we aborted
trying to run that, the user would effectively be locked out of `hg`!
A potential future improvement to this functionality would be to catch
ImportError for the extension/module and parse the source code for
"minimumhgversion = 'XXX'" and do similar checking. This way we could
give more information about why the extension failed to load.
timeless <timeless@mozdev.org> [Wed, 25 Nov 2015 00:39:05 +0000] rev 27141
run-tests: add --slowtimeout and use it for slow tests
Yuya Nishihara <yuya@tcha.org> [Sat, 31 Oct 2015 22:17:05 +0900] rev 27140
serve: unify cmdutil.service() calls of commandserver and hgweb
Yuya Nishihara <yuya@tcha.org> [Sat, 31 Oct 2015 22:15:16 +0900] rev 27139
hgweb: extract factory function of httpservice object
The next patch will merge the cmdutil.service() calls of both commandserver
and hgweb. Before doing it, this patch wipes out the code specific to hgweb
from commands.serve().
Yuya Nishihara <yuya@tcha.org> [Sat, 31 Oct 2015 21:57:45 +0900] rev 27138
hgweb: move httpservice object from commands module
This avoids the deep import of hgweb.server at the commands module.
Siddharth Agarwal <sid0@fb.com> [Wed, 25 Nov 2015 14:25:33 -0800] rev 27137
merge: move almost all change/delete conflicts to resolve phase (BC) (API)
We have finally laid all the groundwork to make this happen.
The only change/delete conflicts that haven't been moved are .hgsubstate
conflicts. Those are trickier to deal with and well outside the scope of this
series.
We add comprehensive testing not just for the initial selections but also for
re-resolves and all possible dirstate transitions caused by merge tools. That
testing managed to shake out several bugs in the way we were handling dirstate
transitions.
The other test changes are because we now treat change/delete conflicts as
proper merges, and increment the 'merged' counter rather than the 'updated'
counter. I believe this is the right approach here.
For third-party extensions, if they're interacting with filemerge code they
might have to deal with an absentfilectx rather than a regular filectx.
Still to come:
- add a 'leave unresolved' option to merges
- change the default for non-interactive change/delete conflicts to be 'leave
unresolved'
- add debug output to go alongside debug outputs for binary and symlink file
merges
Siddharth Agarwal <sid0@fb.com> [Wed, 25 Nov 2015 14:26:46 -0800] rev 27136
test-merge-changedelete.t: print out debugmergestate
We're going to use this to verify the merge state in upcoming patches.
Siddharth Agarwal <sid0@fb.com> [Tue, 24 Nov 2015 18:26:21 -0800] rev 27135
debugmergestate: also recognize change/delete conflicts in the merge state
We're going to use this for tests in upcoming patches.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 10:26:37 -0800] rev 27134
debugmergestate: print out null nodes as 'null'
This is so much easier to read than a long string of zeroes, and we're going to
have a lot more of these nodes once change/delete conflicts are part of the
merge state.
Siddharth Agarwal <sid0@fb.com> [Tue, 24 Nov 2015 15:03:00 -0800] rev 27133
test-merge-force.t: check .orig files separately
We're going to soon compare the output of all the non-orig files before and
after a resolve, and this makes that more convenient. The .orig files are
obviously going to differ between the two.
Siddharth Agarwal <sid0@fb.com> [Tue, 24 Nov 2015 15:26:51 -0800] rev 27132
merge.recordupdates: mark 'a' files as added unconditionally
See the previous patch for why we do this.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 10:19:39 -0800] rev 27131
merge: add a new action type representing files to add/mark as modified
This is somewhat different from the currently existing 'a' action, for the
following case:
- dirty working copy, with file 'fa' added and 'fm' modified
- hg merge --force with a rev that neither has 'fa' nor 'fm'
- for the change/delete conflicts we pick 'changed' for both 'fa' and 'fm'.
In this case 'branchmerge' is true, but we need to distinguish between 'fa',
which should ultimately be marked added, and 'fm', which should be marked
modified.
Our current strategy is to just not touch the dirstate at all. That works for
now, but won't work once we move change/delete conflicts to the resolve phase.
In that case we may perform repeated re-resolves, some of which might mark the
file removed or remove the file from the dirstate. We'll need to re-add the
file to the dirstate, and we need to be able to figure out whether we mark the
file added or modified. That is what the new 'am' action lets us do.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 10:03:21 -0800] rev 27130
mergestate: add a cached property accessor for the local context
This is going to be useful in an upcoming patch. We make this a public accessor
because this is also going to be useful for custom merge drivers.
Siddharth Agarwal <sid0@fb.com> [Mon, 30 Nov 2015 10:05:09 -0800] rev 27129
mergestate: raise exception if otherctx is accessed but _other isn't set
We don't want to inadvertently return the workingctx (self._repo[None]).
timeless <timeless@mozdev.org> [Mon, 30 Nov 2015 18:47:33 +0000] rev 27128
pager: improve help for --pager=
try to clarify how to enable/disable the pager
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 21:17:26 -0800] rev 27127
setup: remove unused py_modules argument to setup()
It is never populated and is useless clutter.
Siddharth Agarwal <sid0@fb.com> [Mon, 23 Nov 2015 13:45:56 -0800] rev 27126
test-merge-changedelete.t: add resolve --list output
We're going to move change/delete conflicts to the resolve phase, and the
resolve --list output is one of the things that will be important to test.
Siddharth Agarwal <sid0@fb.com> [Mon, 23 Nov 2015 13:43:14 -0800] rev 27125
test-merge-changedelete.t: add a file with regular merge conflicts
In upcoming patches we're going to move change/delete conflicts to the resolve
phase -- it will be important to see how regular conflicts interact with
change/delete ones.
Siddharth Agarwal <sid0@fb.com> [Tue, 24 Nov 2015 10:58:35 -0800] rev 27124
filemerge: in ':prompt', use ':fail' tool rather than returning directly
The ':fail' tool now knows to write out the changed side for change/delete
conflicts.
This has no impact right now but will make things better when we move
change/delete conflicts in here.
Siddharth Agarwal <sid0@fb.com> [Tue, 24 Nov 2015 10:57:01 -0800] rev 27123
filemerge: in ':fail' tool, write out other side if local side is deleted
We do this because we don't want to modify the dirstate for failures, and don't
just want to leave the file missing from disk. Plus it's more useful for the
user if the changed side is written out -- it is easier to delete a file than
to get it back via hg revert.
Siddharth Agarwal <sid0@fb.com> [Mon, 23 Nov 2015 18:03:25 -0800] rev 27122
mergestate: explicitly forget 'dc' conflicts where the deleted side is picked
Once we move change/delete conflicts into the resolve phase, a 'dc' file might
first be resolved by picking the other side, then later be resolved by picking
the local side. For this transition we want to make sure that the file goes
back to not being in the dirstate.
This has no impact on conflicts during the initial merge.
Siddharth Agarwal <sid0@fb.com> [Mon, 23 Nov 2015 19:06:15 -0800] rev 27121
merge.applyupdates: add all actions returned from merge state
At the moment this is a no-op (the only actions defined are 'r', 'a' and 'g'),
but soon we're going to add other sorts of actions to the dictionary returned
from mergestate.actions().
Mathias De Maré <mathias.demare@gmail.com> [Fri, 27 Nov 2015 20:23:23 +0100] rev 27120
identify: refer to log to be able to view full hashes
Mathias De Maré <mathias.demare@gmail.com> [Fri, 27 Nov 2015 20:23:02 +0100] rev 27119
log: add 'hg log' example for full hashes
Mathias De Maré <mathias.demare@gmail.com> [Fri, 02 Oct 2015 07:48:23 +0200] rev 27118
backout: add examples to clarify basic usage
timeless <timeless@mozdev.org> [Wed, 25 Nov 2015 06:10:54 +0000] rev 27117
gpg: rename sigcheck function
I see no reason for the function not to be sigcheck ...
Augie Fackler <augie@google.com> [Tue, 24 Nov 2015 18:40:16 -0500] rev 27116
extensions: properly mark progress as part of core
This should have been done as part of or as an immediate follow-up to
f5c906878a47, but presumably this feature of extensions.py was
forgotten at that time.
Yuya Nishihara <yuya@tcha.org> [Fri, 27 Nov 2015 23:10:48 +0900] rev 27115
test-help: don't use progress extension for the test of argument parsing
The next patch will remove the progress extension completely, so we have
to pick another extension. The schemes is picked arbitrary.
This test was introduced at 69da16b366ad.
timeless <timeless@mozdev.org> [Tue, 24 Nov 2015 22:31:56 +0000] rev 27114
hghave.py: fix matchoutput documentation
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 14:23:46 -0800] rev 27113
dispatch: use versiontuple()
We have a new generic function for this. Use it.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 14:23:51 -0800] rev 27112
util: add versiontuple() for returning parsed version information
We have similar code in dispatch.py. Another consumer is about to be
created, so establish a generic function in an accessible location.
Bryan O'Sullivan <bos@serpentine.com> [Tue, 24 Nov 2015 16:38:54 -0800] rev 27111
extensions: rename _ignore to _builtin, add descriptive comment
It was previously not at all obvious what this was for.
We also change it to a set to avoid iterating over an admittedly
small list repeatedly at startup time.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 22 Nov 2015 14:44:55 -0800] rev 27110
ui: avoid needless casting to a str
In many cases, we don't need to cast to a str because the object will
be cast when it is eventually written.
As part of testing this, I added some code to raise exceptions when a
non-str was passed in and wasn't able to trigger it. i.e. we're already
passing str into this function everywhere, so the casting isn't
necessary.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 24 Nov 2015 11:23:10 -0800] rev 27109
ui: remove labeled argument from popbuffer
It was moved to pushbuffer and currently does nothing.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 22 Nov 2015 14:18:42 -0800] rev 27108
color: evaluate labels at write time
Previously, we stored 2-tuples of text and label in a list and then
evaluated the labels when the buffer was popped. After this patch,
we evaluate the labels at write time and do a simple join when the
buffer is popped.
This patch appears to have no impact on performance, despite creating
fewer 2-tuples and having fewer strings hanging around in memory.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 22 Nov 2015 14:13:25 -0800] rev 27107
cmdutil: pass labeled=True to pushbuffer()
This doesn't yet change behavior because labeling is still performed
at popbuffer time.
Surprisingly, this is the only in-tree consumer that passes
labeled=True.
Gregory Szorc <gregory.szorc@gmail.com> [Sun, 22 Nov 2015 14:10:48 -0800] rev 27106
ui: track label expansion when creating buffers
As part of profiling `hg log` performance, I noticed a lot of time
is spent in buffered writes to ui instances. This patch starts a series
that refactors buffered writes with the eventual intent to improve
performance.
Currently, labels are expanded when buffers are popped. This means
we have to preserve the original text and the label until we render
the final output. This is avoidable overhead and adds complexity
since we're retaining state.
This patch adds functionality to ui.pushbuffer() to declare whether
label expansion should be active for the buffer. Labels are still
evaluated during buffer pop. This will change in a subsequent
patch.
Since we'll need to access the "expand labels" flag on future write()
operations, we prematurely optimize how the current value is stored
to optimize for rapid retrieval.