Augie Fackler <augie@google.com> [Mon, 03 Feb 2020 11:56:02 -0500] rev 44278
resourceutil: blacken
Martin von Zweigbergk <martinvonz@google.com> [Fri, 24 Jan 2020 14:11:43 -0800] rev 44277
clean: delete obsolete unlinking of .hg/graftstate
The responsibility for clearing it is now in
`cmdutil.clearunfinished()`, so we shouldn't have to unlink it in
`hg.clean()`.
Differential Revision: https://phab.mercurial-scm.org/D7992
Martin von Zweigbergk <martinvonz@google.com> [Tue, 04 Feb 2020 10:16:30 -0800] rev 44276
copies: avoid filtering by short-circuit dirstate-only copies earlier
The call to `y.ancestor(x)` triggered repo filtering, which we'd like
to avoid in the simple `hg status --copies` case.
Differential Revision: https://phab.mercurial-scm.org/D8071
Martin von Zweigbergk <martinvonz@google.com> [Tue, 04 Feb 2020 10:14:44 -0800] rev 44275
tests: add test showing that repo filter is calculated for `hg st --copies`
Differential Revision: https://phab.mercurial-scm.org/D8070
Matt Harbison <matt_harbison@yahoo.com> [Tue, 21 Jan 2020 11:40:15 -0500] rev 44274
lfs: enable workers by default
With the stall issue seemingly fixed, there's no reason not to use workers. The
setting is left for now to keep the test output deterministic, and in case other
issues come up. If none do, this can be converted to a developer setting for
usage with the tests.
Differential Revision: https://phab.mercurial-scm.org/D7963
Matt Harbison <matt_harbison@yahoo.com> [Tue, 21 Jan 2020 11:32:33 -0500] rev 44273
lfs: fix the stall and corruption issue when concurrently uploading blobs
We've avoided the issue up to this point by gating worker usage with an
experimental config. See
10e62d5efa73, and the thread linked there for some of
the initial diagnosis, but essentially some data was being read from the blob
before an error occurred and `keepalive` retried, but didn't rewind the file
pointer. So the leading data was lost from the blob on the server, and the
connection stalled, trying to send more data than available.
In trying to recreate this, I was unable to do so uploading from Windows to
CentOS 7. But it reproduced every time going from CentOS 7 to another CentOS 7
over https.
I found recent fixes in the FaceBook repo to address this[1][2]. The commit
message for the first is:
The KeepAlive HTTP implementation is bugged in it's retry logic, it supports
reading from a file pointer, but doesn't support rewinding of the seek cursor
when it performs a retry. So it can happen that an upload fails for whatever
reason and will then 'hang' on the retry event.
The sequence of events that get triggered are:
- Upload file A, goes OK. Keep-Alive caches connection.
- Upload file B, fails due to (for example) failing Keep-Alive, but LFS file
pointer has been consumed for the upload and fd has been closed.
- Retry for file B starts, sets the Content-Length properly to the expected
file size, but since file pointer has been consumed no data will be uploaded,
causing the server to wait for the uploaded data until either client or
server reaches a timeout, making it seem as our mercurial process hangs.
This is just a stop-gap measure to prevent this behavior from blocking Mercurial
(LFS has retry logic). A proper solutions need to be build on top of this
stop-gap measure: for upload from file pointers, we should support fseek() on
the interface. Since we expect to consume the whole file always anyways, this
should be safe. This way we can seek back to the beginning on a retry.
I ported those two patches, and it works. But I see that `url._sendfile()` does
a rewind on `httpsendfile` objects[3], so maybe it's better to keep this all in
one place and avoid a second seek. We may still want the first FaceBook patch
as extra protection for this problem in general. The other two uses of
`httpsendfile` are in the wire protocol to upload bundles, and to upload
largefiles. Neither of these appear to use a worker, and I'm not sure why
workers seem to trigger this, or if this could have happened without a worker.
Since `httpsendfile` already has a `close()` method, that is dropped. That
class also explicitly says there's no `__len__` attribute, so that is removed
too. The override for `read()` is necessary to avoid the progressbar usage per
file.
[1] https://github.com/facebookexperimental/eden/commit/
c350d6536d90c044c837abdd3675185644481469
[2] https://github.com/facebookexperimental/eden/commit/
77f0d3fd0415e81b63e317e457af9c55c46103ee
[3] https://www.mercurial-scm.org/repo/hg/file/5.2.2/mercurial/url.py#l176
Differential Revision: https://phab.mercurial-scm.org/D7962
Matt Harbison <matt_harbison@yahoo.com> [Tue, 21 Jan 2020 10:34:15 -0500] rev 44272
lfs: add a method to the local blobstore to convert OIDs to file paths
This is less ugly than passing an open callback to the `httpsendfile`
constuctor.
Differential Revision: https://phab.mercurial-scm.org/D7961
Martin von Zweigbergk <martinvonz@google.com> [Wed, 15 Jan 2020 14:47:38 -0800] rev 44271
merge: introduce a revert_to() for that use-case
In the same vein as the previous patch.
Differential Revision: https://phab.mercurial-scm.org/D7901
Martin von Zweigbergk <martinvonz@google.com> [Wed, 15 Jan 2020 15:30:25 -0800] rev 44270
merge: introduce a clean_update() for that use-case
I find it hard to understand what value to pass for all the arguments
to `merge.update()`. I would like to introduce functions that are more
specific to each use-case. We already have `graft()`. This patch
introduces a `clean_update()` and uses it in some places to show that
it works.
Differential Revision: https://phab.mercurial-scm.org/D7902
Augie Fackler <augie@google.com> [Wed, 05 Feb 2020 16:16:15 -0500] rev 44269
manifest: fix _very_ subtle bug with exact matchers passed to walk()
Prior to this fix, manifestdict.walk() with an exact matcher would blindly
list the files in the matcher, even if they weren't in the manifest. This was
exposed by my next patch where I rewrite filesnotin() to use walk() instead of
matches().
Differential Revision: https://phab.mercurial-scm.org/D8081
Raphaël Gomès <rgomes@octobus.net> [Tue, 14 Jan 2020 17:08:45 +0100] rev 44268
rust-utils: add `Escaped` trait
This will be used as a general interface for displaying things to the user.
The upcoming `IncludeMatcher` will use it to store its patterns in a
user-displayable string.
Differential Revision: https://phab.mercurial-scm.org/D7870
Raphaël Gomès <rgomes@octobus.net> [Tue, 14 Jan 2020 17:04:32 +0100] rev 44267
rust-dirs-multiset: add `DirsChildrenMultiset`
In a future patch, this structure will be needed to store information needed by
the (also upcoming) `IgnoreMatcher`.
Differential Revision: https://phab.mercurial-scm.org/D7869
Raphaël Gomès <rgomes@octobus.net> [Tue, 14 Jan 2020 16:50:35 +0100] rev 44266
rust-hg-path: add useful methods to `HgPath`
This changeset introduces the use of the `pretty_assertions` crate for easier
to read test output.
Differential Revision: https://phab.mercurial-scm.org/D7867
Raphaël Gomès <rgomes@octobus.net> [Wed, 05 Feb 2020 17:05:37 +0100] rev 44265
rust-pathauditor: add Rust implementation of the `pathauditor`
It does not offer the same flexibility as the Python implementation, but
should check incoming paths just as well.
Differential Revision: https://phab.mercurial-scm.org/D7866
Pulkit Goyal <7895pulkit@gmail.com> [Wed, 22 Jan 2020 03:17:06 +0530] rev 44264
py3: catch AttributeError too with ImportError
Looks like py3 raises AttributeError instead of ImportError. This is caught on
windows.
Differential Revision: https://phab.mercurial-scm.org/D7965
Augie Fackler <augie@google.com> [Wed, 05 Feb 2020 15:15:18 -0500] rev 44263
context: use manifest.walk() instead of manifest.match() to get file list
The former doesn't create a whole extra manifest in order to produce the
matching file list, which is all we actually cared about here. Sigh.
Differential Revision: https://phab.mercurial-scm.org/D8080
Augie Fackler <augie@google.com> [Wed, 05 Feb 2020 15:01:22 -0500] rev 44262
manifest: remove `.new()` from the interface
Nothing used it.
Differential Revision: https://phab.mercurial-scm.org/D8079
Kyle Lippincott <spectral@google.com> [Wed, 29 Jan 2020 13:39:50 -0800] rev 44261
chg: force-set LC_CTYPE on server start to actual value from the environment
Python 3.7+ will "coerce" the LC_CTYPE variable in many instances, and this can
cause issues with chg being able to start up. D7550 attempted to fix this, but a
combination of a misreading of the way that python3.7 does the coercion and an
untested state (LC_CTYPE being set to an invalid value) meant that this was
still not quite working.
This change will cause differences between chg and hg: hg will have the LC_CTYPE
environment variable coerced, while chg will not. This is unlikely to cause any
detectable behavior differences in what Mercurial itself outputs, but it does
have two known effects:
- When using hg, the coerced LC_CTYPE will be passed to subprocesses, even
non-python ones. Using chg will remove the coercion, and this will not
happen. This is arguably more correct behavior on chg's part.
- On macOS, if you set your region to Brazil but your language to English,
this isn't representable in locale strings, so macOS sets LC_CTYPE=UTF-8. If
this value is passed along when ssh'ing to a non-macOS machine, some
functions (such as locale.setlocale()) may raise an exception due to an
unsupported locale setting. This is most easily encountered when doing an
interactive commit/split/etc. when using ui.interface=curses.
Differential Revision: https://phab.mercurial-scm.org/D8039
Pierre-Yves David <pierre-yves.david@octobus.net> [Mon, 03 Feb 2020 09:00:05 +0100] rev 44260
perf: fix list formatting in perfindex documentation
Differential Revision: https://phab.mercurial-scm.org/D8067
Pierre-Yves David <pierre-yves.david@octobus.net> [Sat, 01 Feb 2020 09:14:36 +0100] rev 44259
test: simplify test-amend.t to avoid race condition
Insted on relying on sleep, we could simply have the editor do the file change.
This remove the reliance on "sleep" and avoid test failing on heavy load
machine.
To test this, I reverted the code change in
5558e3437872 and the test started
failing again.
Differential Revision: https://phab.mercurial-scm.org/D8065
Pierre-Yves David <pierre-yves.david@octobus.net> [Fri, 13 Dec 2019 11:32:36 +0100] rev 44258
test: document test-copy-move-merge.t
Differential Revision: https://phab.mercurial-scm.org/D8077
Augie Fackler <augie@google.com> [Mon, 03 Feb 2020 22:16:36 -0500] rev 44257
manifest: remove optional default= argument on flags(path)
It had only one caller inside manifest.py, and treemanifest was
actually incorrectly implemented. treemanifest is still missing the
fastdelta() method from the interface (and so doesn't yet conform),
but this is at least progress.
Differential Revision: https://phab.mercurial-scm.org/D8069
Kyle Lippincott <spectral@google.com> [Thu, 06 Feb 2020 15:46:55 -0800] rev 44256
py3: fully fix bundlepart.__repr__ to return str not bytes
My previous fix did not fully fix the issue: it would attempt to use
%-formatting to combine two strs into a bytes, which won't work. Let's just
switch the entire function to operating in strs. This can cause a small output
difference that will likely not be noticed since no one noticed that the method
wasn't working at all before: if `id` or `type` are not-None, they'll be shown
as `b'val'` instead of `val`. Since this is a debugging aid and these strings
shouldn't be shown to the user, slightly rough output is most likely fine and
it's likely not worthwhile to add the necessary conditionals to marginally
improve it.
Differential Revision: https://phab.mercurial-scm.org/D8091
Pierre-Yves David <pierre-yves.david@octobus.net> [Sun, 17 Nov 2019 01:18:14 +0100] rev 44255
heptapod-ci: add a job to test the rust version of Mercurial
The rust version of Mercurial is not currently tested by anything else. So it
get quite important that developer runs it.
Differential Revision: https://phab.mercurial-scm.org/D8017
Pierre-Yves David <pierre-yves.david@octobus.net> [Sat, 16 Nov 2019 12:26:54 +0100] rev 44254
heptapod-ci: run the --pure test too
These are usually rarely run by individual developper because they are slow.
However it is important that they stay happy.
Differential Revision: https://phab.mercurial-scm.org/D8016
Pierre-Yves David <pierre-yves.david@octobus.net> [Sat, 25 Jan 2020 14:56:36 +0100] rev 44253
heptapod-ci: run the normal test suite
The usual tests should be run too. We skip the "tests-check*.t" one because
their are already covered by another Ci step.
Differential Revision: https://phab.mercurial-scm.org/D8015
Pierre-Yves David <pierre-yves.david@octobus.net> [Mon, 18 Nov 2019 09:38:40 +0100] rev 44252
heptapod-ci: also run the dedicated rust test for the rust code
The Rust code has various standard rust test that are fast to run. So let's run them.
Differential Revision: https://phab.mercurial-scm.org/D8014
Pierre-Yves David <pierre-yves.david@octobus.net> [Sat, 16 Nov 2019 12:25:53 +0100] rev 44251
heptapod-ci: run test with python3 too
Python3 is the future^W present, it is important to run tests with it too.
Differential Revision: https://phab.mercurial-scm.org/D8013
Pierre-Yves David <pierre-yves.david@octobus.net> [Fri, 24 Jan 2020 23:22:29 +0100] rev 44250
heptapod-ci: colorize output
The run result are nicer to read with color.
Differential Revision: https://phab.mercurial-scm.org/D8012
Pierre-Yves David <pierre-yves.david@octobus.net> [Sat, 25 Jan 2020 17:57:40 +0100] rev 44249
heptapod-ci: add a basic file to be able to run tests with heptapod
Having this yaml file somewhere in the main mercurial repository makes it
trivial for contributors using heptapod to run CI on their in-progress work.
There are alot of different combination (python2/python3 pure/cext/rust/pypy)
to be tested and making sure all of them are covered manually is cumbersome.
Automatic CI runnig on draft really helps in that matters. We start small bu
later changesets will add more step testing more of the variants.
The series is targetted on stable to make it available to the widest amount of contribution possible.
The definition of the docker files used for this are available here:
https://dev.heptapod.net/octobus/ci-dockerfiles
Differential Revision: https://phab.mercurial-scm.org/D8011
Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> [Tue, 04 Feb 2020 22:07:36 +0100] rev 44248
worker: manually buffer reads from pickle stream
My previous fix (D8051,
cb52e619c99e, which added Python's built-in buffering
to the pickle stream) has the problem that the selector will ignore the buffer.
When multiple pickled objects are read from the pipe into the buffer at once,
only one object will be loaded.
This can repeat until the buffer is full and delays the processing of completed
items until the worker exits, at which point the pipe is always considered
readable and all remaining items are processed.
This changeset reverts D8051, removing the buffer again. Instead, on Python 3
only, we use a wrapper to modify the "read" provided to the Unpickler to behave
more like a buffered read. We never read more bytes from the pipe than the
Unpickler requests, so the selector behaves as expected.
Also add a test case for "pickle data was truncated" issue.
https://phab.mercurial-scm.org/D8051#119193
Differential Revision: https://phab.mercurial-scm.org/D8076
Kyle Lippincott <spectral@google.com> [Thu, 02 Jan 2020 11:04:18 -0800] rev 44247
py3: __repr__ needs to return str, not bytes
Differential Revision: https://phab.mercurial-scm.org/D8089
Pierre-Yves David <pierre-yves.david@octobus.net> [Tue, 04 Feb 2020 12:07:37 +0100] rev 44246
config: also respect HGRCSKIPREPO in the zeroconf extension
Differential Revision: https://phab.mercurial-scm.org/D8075
Pierre-Yves David <pierre-yves.david@octobus.net> [Tue, 04 Feb 2020 12:07:42 +0100] rev 44245
config: also respect HGRCSKIPREPO in hgwebdir_mod
Differential Revision: https://phab.mercurial-scm.org/D8074
Pierre-Yves David <pierre-yves.david@octobus.net> [Mon, 03 Feb 2020 20:41:11 +0100] rev 44244
config: also respect HGRCSKIPREPO in `dispatch._getlocal`
For some reason, we are also reading the local config in that function.
Differential Revision: https://phab.mercurial-scm.org/D8073
Pierre-Yves David <pierre-yves.david@octobus.net> [Tue, 04 Feb 2020 12:31:19 +0100] rev 44243
config: add a function in `rcutil` to abstract HGRCSKIPREPO
We wil need to respect this environment variable in more place.
Differential Revision: https://phab.mercurial-scm.org/D8072
Matt Harbison <matt_harbison@yahoo.com> [Mon, 03 Feb 2020 20:12:47 -0500] rev 44242
packaging: make the path to Win32 requirements absolute when building WiX
Otherwise this broke automation when not launched from `contrib/packaging`.
Differential Revision: https://phab.mercurial-scm.org/D8068
Augie Fackler <augie@google.com> [Mon, 03 Feb 2020 11:56:02 -0500] rev 44241
resourceutil: blacken
Augie Fackler <augie@google.com> [Mon, 03 Feb 2020 11:51:52 -0500] rev 44240
merge with stable
Martin von Zweigbergk <martinvonz@google.com> [Fri, 31 Jan 2020 10:53:50 -0800] rev 44239
rebase: abort if the user tries to rebase the working copy
I think it's more correct to treat `hg rebase -r 'wdir()' -d foo`
as `hg co -m foo`, but I'm instead making it error out. That's partly
because it's probably what the user wanted (in the case I heard from a
user, they had done `hg rebase -s f` where `f` resolved to `wdir()`)
and partly because I don't want to think about more complicated cases
where the user specifies the working copy together with other commits.
Differential Revision: https://phab.mercurial-scm.org/D8057
Martin von Zweigbergk <martinvonz@google.com> [Fri, 31 Jan 2020 10:41:50 -0800] rev 44238
tests: add tests for rebasing wdir() revision
Differential Revision: https://phab.mercurial-scm.org/D8056
Martin von Zweigbergk <martinvonz@google.com> [Wed, 22 Jan 2020 13:29:26 -0800] rev 44237
merge: when rename was made on both sides, use ancestor as merge base
When both sides of a merge have renamed a file to the same place, we
would treat that as a "both created" action in merge.py. That means
that we'd use an empty diffbase. It seems better to use the copy
source as diffbase. That can be done by simply dropping code that
prevented us from doing that. I think I did it that way in
57203e0210f8 (copies: calculate mergecopies() based on pathcopies(),
2019-04-11) only to preserve the existing behavior. I also suspect it
was just an accident that it behaved that way before that commit.
Note that until
fa9ad1da2e77 (merge: start using the per-side copy
dicts, 2020-01-23), it was non-deterministic (depending on iteration
order of the `allsources` set in `copies._fullcopytracing()`) which
source was used in the affected test case in test-rename-merge1.t. We
could easily have fixed that by sorting them, but now we can instead
detect the case (the TODO added in the previous patch).
Differential Revision: https://phab.mercurial-scm.org/D7974
Martin von Zweigbergk <martinvonz@google.com> [Fri, 31 Jan 2020 08:47:32 -0800] rev 44236
absorb: graduate -i flag from experimental
The interactive mode seems to work well. I have previously thought
that `-i` should be what `-e` does, but the current behavior matches
what other `-i` flags do (select a subset of the hunks), so I think
that is what we want.
Differential Revision: https://phab.mercurial-scm.org/D8055
Yuya Nishihara <yuya@tcha.org> [Sat, 25 Jan 2020 17:30:24 +0900] rev 44235
rust-cpython: remove PySharedRefCell and its companion structs
Also updates py_shared_iterator!() documentation accordingly.
Yuya Nishihara <yuya@tcha.org> [Sat, 25 Jan 2020 17:26:23 +0900] rev 44234
rust-cpython: switch to upstreamed version of PySharedRefCell
Our PyLeaked is identical to cpython::UnsafePyLeaked. I've renamed it because
it provides mostly unsafe functions.
Yuya Nishihara <yuya@tcha.org> [Sat, 25 Jan 2020 17:21:06 +0900] rev 44233
rust-cpython: rename inner_shared() to inner()
The "shared" accessor will be automatically generated, and will have the
same name as the data itself.
Yuya Nishihara <yuya@tcha.org> [Fri, 31 Jan 2020 00:08:30 +0900] rev 44232
rust-cpython: use PyList.insert() instead of .insert_item()
Silences the deprecated warning.
https://github.com/dgrunwald/rust-cpython/commit/
e8cbe864841714c5555db8c90e057bd11e360c7f
Yuya Nishihara <yuya@tcha.org> [Fri, 31 Jan 2020 00:01:29 +0900] rev 44231
rust-cpython: bump cpython to 0.4 to switch to upstreamed PySharedRef
Yuya Nishihara <yuya@tcha.org> [Thu, 30 Jan 2020 23:57:19 +0900] rev 44230
rust: update dependencies
For no particular reason, but just because I'll bump the rust-cpython version.
Augie Fackler <raf@durin42.com> [Mon, 03 Feb 2020 11:07:34 -0500] rev 44229
Added signature for changeset
7f5410dfc8a6
Augie Fackler <raf@durin42.com> [Mon, 03 Feb 2020 11:07:33 -0500] rev 44228
Added tag 5.3 for changeset
7f5410dfc8a6
Raphaël Gomès <rgomes@octobus.net> [Wed, 29 Jan 2020 11:11:18 +0100] rev 44227
rust-dirstatemap: add missing @propertycache
While investigating a regression on `hg update` performance introduced by the
Rust `dirstatemap`, two missing `@propertycache` were identified when comparing
against the Python implementation. This adds back the first one, that has
no observable impact on behavior. The second one (`nonnormalset`) is going to
be more involved, as the caching has to be done from the Rust side of things.
Differential Revision: https://phab.mercurial-scm.org/D8047
Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> [Thu, 30 Jan 2020 19:16:12 +0100] rev 44226
worker: Use buffered input from the pickle stream
On Python 3, "pickle.load" will raise an exception ("_pickle.UnpicklingError:
pickle data was truncated") when it gets a short read, i.e. it receives fewer
bytes than it requested.
On our build machine, Mercurial seems to frequently hit this problem while
updating a mozilla-central clone iff it gets scheduled in batch mode. It is easy
to trigger with:
#wipe the workdir
rm -rf *
hg update null
chrt -b 0 hg update default
I've also written the following program, which demonstrates the core problem:
from __future__ import print_function
import io
import os
import pickle
import time
obj = {"a": 1, "b": 2}
obj_data = pickle.dumps(obj)
assert len(obj_data) > 10
rfd, wfd = os.pipe()
pid = os.fork()
if pid == 0:
os.close(rfd)
for _ in range(4):
time.sleep(0.5)
print("First write")
os.write(wfd, obj_data[:10])
time.sleep(0.5)
print("Second write")
os.write(wfd, obj_data[10:])
os._exit(0)
try:
os.close(wfd)
rfile = os.fdopen(rfd, "rb", 0)
print("Reading")
while True:
try:
obj_copy = pickle.load(rfile)
assert obj == obj_copy
except EOFError:
break
print("Success")
finally:
os.kill(pid, 15)
The program reliably fails with Python 3.8 and succeeds with Python 2.7.
Providing the unpickler with a buffered reader fixes the issue, so let
"os.fdopen" create one.
https://bugzilla.mozilla.org/show_bug.cgi?id=1604486
Differential Revision: https://phab.mercurial-scm.org/D8051
Matt Harbison <matt_harbison@yahoo.com> [Sat, 01 Feb 2020 01:32:28 -0500] rev 44225
packaging: lowercase the `contrib` and `templates` directories with Inno
I have no idea why these (and `contrib/vim`) were leading with uppercase with
Inno, but not WiX. It probably doesn't matter too much, but might be a problem
with `templates` if the user enabled case sensitivity on NTFS.
Differential Revision: https://phab.mercurial-scm.org/D8063
Matt Harbison <matt_harbison@yahoo.com> [Sun, 02 Feb 2020 00:56:40 -0500] rev 44224
packaging: merge the requirements.txt files for WiX and Inno
Now that the content is common, there's no need to have separate files. The
content still differs from the non-Windows platforms though.
Differential Revision: https://phab.mercurial-scm.org/D8066
Matt Harbison <matt_harbison@yahoo.com> [Sat, 01 Feb 2020 00:58:34 -0500] rev 44223
packaging: bundle dulwich, keyring, and pywin32-ctypes with WiX too
TortoiseHg installs these, which is possibly where they originated (though I
would have thought it more likely to be in the WiX installer, given its
heritage). When I was working on the TortoiseHg app for Mac (which uses the
similar `py2app`), it wasn't possible to use the keyring extension (even
externally) without bundling this keyring package into the app. Assuming the
same principle applies here, these would enable some common extensions. One of
the things that the TortoiseHg packager on macOS does now is it adds the user's
local `site-packages` directory to `sys.path`. That would allow the user to
install these critical modules in cases like this. But that can probably wait
for py3 packaging.
The only difference in the installed packages that I see now is WiX also bundles
distutils for some reason. I suppose that's not harming anything, so I'm not
touching it.
The only orphans in the install directories when comparing WiX and Inno now is
the Copying.txt vs COPYING.rtf, the two uninstaller files for Inno, and a
`Mercurial.url` file in Inno. I have no idea what that is, and it has *.ini
syntax with a single field pointing to the Mercurial homepage.
Differential Revision: https://phab.mercurial-scm.org/D8062