Matt Harbison <matt_harbison@yahoo.com> [Sat, 18 Aug 2018 13:27:33 -0400] rev 39188
test-absorb: stabilize for no-execbit platforms
Matt Harbison <matt_harbison@yahoo.com> [Sat, 18 Aug 2018 12:35:47 -0400] rev 39187
test-graft: add a missing output line for Windows
Matt Harbison <matt_harbison@yahoo.com> [Sat, 18 Aug 2018 01:07:43 -0400] rev 39186
share: allow more than one level of directories to be created
Matt Harbison <matt_harbison@yahoo.com> [Sat, 18 Aug 2018 00:51:26 -0400] rev 39185
clone: allow local cloning to create more than one level of directories
I figure cloning a remote repository is more common, thus it's more likely that
some people might be relying on the less restrictive behavior. Additionally,
`hg init` will also create more than one level of missing directories.
I also have a use case for reading the subrepos from .hgsub, and sharing them
into the normal nested location on the server. SCM Manager doesn't host
subrepos in the normal nested location, which is nice for deduplicating the
repository data, but confuses `hg verify`. Some of the subrepos are in the root
of the repositories, while others are one or two directories deep. So not
having to build up the parent path first is desirable.
Matt Harbison <matt_harbison@yahoo.com> [Fri, 17 Aug 2018 23:28:37 -0400] rev 39184
tests: demonstrate an inconsistency when cloning to a missing directory tree
I noticed that `hg share` is unable to create more than one missing directory on
the path, and thought it was inconsistent with clone. It turns out that the
path for copying/linking the remote store has the same limitation, but cloning
from a remote repo doesn't.
Matt Harbison <matt_harbison@yahoo.com> [Sat, 18 Aug 2018 23:39:26 -0400] rev 39183
tests: stabilize test-merge-tools.t on Windows
More fun with `hg import --bypass` to work around Windows limitations. The
diffs were generated on Linux, and had a tab to terminate the `+++b/...` lines.
But check-code complained about trailing whitespace, and it seems to run without
them.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 21:26:34 +0000] rev 39182
dagutil: remove module
The previous commit removed the last consumer of this module.
.. api:: dagutil module has been removed
Some functionality has been moved to the dagop module. Other
functionality can be accomplished via revsets.
Differential Revision: https://phab.mercurial-scm.org/D4330
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 21:21:50 +0000] rev 39181
dagop: port revlogdag.linearize() to standalone function
The code should functionally be identical.
We also port the one consumer in changegroup to use the new
standalone function.
After this commit, dagutil is no longer used!
Differential Revision: https://phab.mercurial-scm.org/D4329
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 19:48:52 +0000] rev 39180
dagutil: use revlog.parentrevs() for resolving parent revisions
And remove parents() since it is no longer used.
revlog.parentrevs() is almost the same as parents(). The main
difference is that parentrevs() can return nullrev. dagop.headrevs()
already handles nullrev. We add an inline check for nullrev in the
other call site to account for the difference.
.. api:: parents() removed from dagutil classes
Use parentrevs() on the storage object instead.
Differential Revision: https://phab.mercurial-scm.org/D4328
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 19:45:13 +0000] rev 39179
dagop: extract headsetofconnecteds() from dagutil
The functionality for resolving the set of DAG heads from a
subset simply requires a function to resolve parent revisions.
Let's establish a function in the dagop module to do this, which
seems to be where generic DAG functionality goes these days.
Differential Revision: https://phab.mercurial-scm.org/D4327
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 19:35:24 +0000] rev 39178
setdiscovery: precompute children revisions to avoid quadratic lookup
Moving away from dagutil a few commits ago introduced quadratic
behavior when resolving children revisions during discovery.
This commit introduces a precompute step of the children revisions
to avoid the bad behavior.
I believe the new code should have near identical performance to
what dagutil was doing before. Behavior is still slightly different
because we take into account filtered revisions. But this change was
made when we moved off dagutil.
I added a comment about multiple invocations of this function
redundantly calculating the children revisions. I believe this
potentially undesirable behavior was present when we used dagutil,
as the call to inverse() previously in this function created a new
object and required computing children on every invocation. I thought
we should document the potential for a performance issue rather than
let it go undocumented.
Differential Revision: https://phab.mercurial-scm.org/D4326
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 19:24:36 +0000] rev 39177
dagutil: remove unused classes
We only directly use revlogdag in changegroup code. We don't need
all this abstraction. So remove various classes and levels
of inheritance.
Differential Revision: https://phab.mercurial-scm.org/D4325
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 18:23:47 +0000] rev 39176
setdiscovery: use revset for resolving DAG heads in a subset
This was the final use of dagutil in setdiscovery!
For reasons I didn't investigate, feeding a set with nullrev
into the heads() revset resulted in a bunch of tests failing.
Filtering out nullrev from the input set fixes things.
Differential Revision: https://phab.mercurial-scm.org/D4324
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 19:12:25 +0000] rev 39175
dagutil: remove ability to invert instances
The previous commit removed the last consumer of this feature.
.. api:: remove inverse() methods from classes in dagutil
Differential Revision: https://phab.mercurial-scm.org/D4323
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 18:22:10 +0000] rev 39174
setdiscovery: don't use dagutil for parent resolution
_updatesample()'s one remaining use of revlogdag is for resolving
the parents of a revision.
In 2 cases, we actually resolve parents. In 1, we operate on the
inverted DAG and resolve children.
This commit teaches _updatesample() to receive an argument defining
the function to resolve "parent" revisions. Call sites pass in
changelog.parentrevs() or a wrapper around changelog.children()
accordingly.
The use of children() is semantically correct. But it is quadratic,
since revlog.children() does a range scan over all revisions starting
at its input and effectively calls parentrevs() to build up the list
of children. So calling it repeatedly in a loop is a recipe for
bad performance. I will be implementing something better in a
subsequent commit. I wanted to get the porting off of dagutil done
in a way that was simple and correct.
Like other patches in this series, this change is potentially impacted
but revlogdag's ignorance of filtered revisions. The new code is
filtering aware, since changelog's revs() (used by children() will
skip filtered revisions and therefore hidden children won't appear.
This is potentially backwards incompatible. But no tests fail and
I think this code should respect visibility.
Differential Revision: https://phab.mercurial-scm.org/D4322
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 18:05:36 +0000] rev 39173
setdiscovery: use revsets for computing a subset's heads and roots
revlogdag.headsetofconnecteds() obtains the set of DAG heads in a
given set of revs.
revlogdag.inverse() inverts the DAG order and makes
headsetofconnecteds() obtain the DAG roots in a given subset.
Both of these can be expressed with a revset.
Like other patches in this series, revlogdag uses revlog.index
and thus doesn't take filtering into account. Revsets do. So there
is a chance for regressions with this change. But no tests fail.
And I think this code should take filtering into account since
hidden changesets shouldn't factor into discovery (unless operating
on the hidden repository).
Differential Revision: https://phab.mercurial-scm.org/D4321
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:59:16 +0000] rev 39172
dagutil: remove heads() and localsubset from revlogdag.__init__
The previous commit removed the last consumer of this API.
I'm not going to mark as API incompatible because I doubt anybody
used this functionality (outside of possibly passing an argument
to revlogdag.__init__). I intend to remove revlogdag later in
this series and its API annotation will cover this one.
Differential Revision: https://phab.mercurial-scm.org/D4320
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:54:10 +0000] rev 39171
setdiscovery: pass head revisions into sample functions
This eliminates the last remaining consumer of heads() and
related functionality in dagutil.
Differential Revision: https://phab.mercurial-scm.org/D4319
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:48:15 +0000] rev 39170
setdiscovery: pass heads into _updatesample()
In preparation for eliminating the use of dagutil. Since
_takefullsample() operates on the inverted DAG, it is easier
to have the caller pass in the relevant set instead of teaching
_updatesample() about when to invert the DAG.
We keep the logic identical for now: future commits will remove
dagutil.
Differential Revision: https://phab.mercurial-scm.org/D4318
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:26:07 +0000] rev 39169
setdiscovery: use a revset for finding DAG heads in a subset
The march towards moving away from dagutil continues.
Like other patches moving us away from dagutil, there is the
potential for regressions to occur because revlogdag's
headsetofconnecteds() uses revlog.index, which doesn't take
filtering into account. The revset layer does. But no tests
fail, so we appear to be in the clear.
Differential Revision: https://phab.mercurial-scm.org/D4317
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:21:11 +0000] rev 39168
setdiscovery: reflect use of revs instead of nodes
This code all operates on revision numbers. Update variable names
and comments accordingly.
Differential Revision: https://phab.mercurial-scm.org/D4316
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:15:09 +0000] rev 39167
dagutil: remove descendantset() and ancestorset()
descendantset() is unused after the previous commit. And
ancestorset() was only used by descendantset(), so it can be removed
as well.
.. api:: descendantset() and ancestorset() removed from dagutil
Use a revset instead when operating on the changelog. Or use
various functionality in the ancestor or dagop modules.
Differential Revision: https://phab.mercurial-scm.org/D4315
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 17:13:26 +0000] rev 39166
setdiscovery: use a revset instead of dagutil.descendantset()
This is the only use of descendantset() in the repo.
Strictly speaking, the revset behaves slightly differently than
dagutil. The reason is that dagutil is using revlog.index for
DAG traversal and this data structure isn't aware of visibility /
filtering. So it can operate on revisions it shouldn't operate on.
But our test coverage of this code is pretty comprehensive and
this change causes no tests to fail. So I think we are good.
Also, the revset parser failed to parse `%ld:: - %ld::`, hence
the use of descendants(). I'm not sure if that is a feature or
a bug.
Differential Revision: https://phab.mercurial-scm.org/D4314
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 20:23:10 +0000] rev 39165
setdiscovery: don't use dagutil to compute heads
This is a relatively trivial operation to perform. We don't
need to use dagutil.
This brings us one step closer to eliminating dagutil.
We still need to populate the heads on revlogdag because later
functionality relies on it.
Differential Revision: https://phab.mercurial-scm.org/D4310
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 20:11:45 +0000] rev 39164
dagutil: remove nodeset()
AFAICT this was unused since the code was introduced by
cb98fed52495
in 2011!
Differential Revision: https://phab.mercurial-scm.org/D4309
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:55:55 +0000] rev 39163
debugcommands: use a revset instead of dagutil
All this code was doing was finding the nodes that are heads
from the ancestors of an input set. This can easily be expressed
with a revset without having to go through dagutil.
This was the last use of ancestorset() outside of dagutil itself.
Differential Revision: https://phab.mercurial-scm.org/D4308
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:51:01 +0000] rev 39162
dagutil: remove internalize() and internalizeall()
The previous commit removed the last consumer.
.. api:: removed internalize() and internalizeall() from dagutil
Use .rev(node) on storage objects to convert nodes to revisions.
Differential Revision: https://phab.mercurial-scm.org/D4307
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:47:30 +0000] rev 39161
setdiscovery: don't use dagutil for node -> rev conversion
The node -> rev conversion is possible using standard storage APIs
and doesn't need to involve the dagutil module.
Differential Revision: https://phab.mercurial-scm.org/D4306
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:40:46 +0000] rev 39160
dagutil: remove externalize() and externalizeall()
They are unused after the previous commit.
.. api:: externalize() and externalizeall() removed from dagutil
Use .node() on a storage primitive to perform revision to node
conversions.
Differential Revision: https://phab.mercurial-scm.org/D4305
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:39:47 +0000] rev 39159
setdiscovery: don't use dagutil for rev -> node conversions
We don't need to use dagutil to perform a simple rev -> node
conversion.
I haven't measured, but the new code is likely faster, as we
avoid extra function calls and avoid some attribute lookups.
Differential Revision: https://phab.mercurial-scm.org/D4304
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 16 Aug 2018 19:23:24 +0000] rev 39158
exchange: don't use dagutil
We were only using it for simple node -> rev and parent revision
lookups. These are exposed via the storage interface and we don't
need to go through dagutil.
Differential Revision: https://phab.mercurial-scm.org/D4303
Paul Morelle <paul.morelle@octobus.net> [Fri, 20 Jul 2018 13:20:01 +0200] rev 39157
revlog: only consider the span of the delta section
Since the number of snapshots is limited we can exclude them from the logic
checking size and number of reads. Limiting the span computation to the delta
section will allow for further optimization.
Boris Feld <boris.feld@octobus.net> [Mon, 23 Jul 2018 16:21:58 +0200] rev 39156
revlog: ensure intermediate snapshot have decreasing size
If the intermediate snapshot is bigger than the previous one, there is likely
a better snapshot to be made at a different level.
Paul Morelle <paul.morelle@octobus.net> [Wed, 07 Mar 2018 12:28:04 +0100] rev 39155
revlog: bound number of snapshots in a chain
To limit the number of snapshot chained, we enforce them to be smaller and
smaller. This guarantee the number of snapshot in a chain will be bounded to a
small number.
Boris Feld <boris.feld@octobus.net> [Fri, 20 Jul 2018 14:32:56 +0200] rev 39154
revlog: compute snapshot depth on delta info
We need the information to be available when choosing delta.
Boris Feld <boris.feld@octobus.net> [Wed, 15 Aug 2018 12:30:30 +0200] rev 39153
debugrevlog: display snapshot details per depth
This help in understanding the final structure of build manifest. All data
about snapshot (full and intermediate) are gathered into a sub-list for
clarity.
Since we do not produce such snapshots yet, the only thing changing in test
output is the way the information is presented.
Boris Feld <boris.feld@octobus.net> [Wed, 15 Aug 2018 12:09:14 +0200] rev 39152
revlog: add a method to retrieve snapshot depth
Some snapshot property (eg: maximum size) will depend on their depth.
Boris Feld <boris.feld@octobus.net> [Fri, 27 Jul 2018 10:52:43 +0200] rev 39151
debugrevlog: include information about intermediate snapshots
As we are about to create intermediate snapshots, we need to have a way to
debug them. We start by adding very simple debug output and more detailed
output will comes in next changesets.
Paul Morelle <paul.morelle@octobus.net> [Fri, 20 Jul 2018 13:34:48 +0200] rev 39150
revlog: also detect intermediate snapshots
Also detect intermediate-snapshot done against another previous snapshot.
Doing an intermediate snapshot instead of a full one can reduce the number of
full snapshots we need. They are especially useful for content with a lot of
churn on the same line (eg: the manifest) where having a delta over multiple
revisions can end up being significantly smaller than the sum of these
revision deltas.
A revlog built using intermediate snapshots can be a bit smaller and reuse
snapshot much more efficiently. This last property is useful combined with
constraints on chain length. Using intermediate snapshot can produce
repository with delta chain ten times shorter without impact on the storage
size. Shorter chain lengths are faster to restore, greatly improving read
performance.
This changesets (and the following ones) focus on getting the core principle
of intermediate snapshots into Mercurial core. Later changeset will introduce
the strategy to create them.
Paul Morelle <paul.morelle@octobus.net> [Fri, 20 Jul 2018 13:32:17 +0200] rev 39149
revlog: add a method to tells whether rev is stored as a snapshot
For now we only have one type of snapshot: full snapshot versus nullrev.
However we are looking into adding intermediate snapshot where a large diff
against another snapshot is performed instead of storing a full new text.
The conditional is a bit strange and is done in order to help readability of a
some later changesets.
Boris Feld <boris.feld@octobus.net> [Wed, 15 Aug 2018 15:20:44 +0200] rev 39148
debugrevlog: fix for non-manifest object
The `filelog` object is no longer an actual revlog. Instead, the actual revlog
is stored in the `_revlog` attribute.
Gregory Szorc <gregory.szorc@gmail.com> [Fri, 17 Aug 2018 16:11:35 -0700] rev 39147
merge with stable
Boris Feld <boris.feld@octobus.net> [Fri, 17 Aug 2018 20:35:52 +0200] rev 39146
remotephase: avoid full changelog iteration (
issue5964)
Changeset
88efb7d6bcb6 introduced a performance regression by triggering a
full ancestors walk.
This changeset reworks this logic so that we no longer walk down the full
changelog. The motivation for
88efb7d6bcb6,
issue5939, is still fixed.
mercurial compared to a draft repository
----------------------------------------
8eeed92475d5: 0.012637 seconds
88efb7d6bcb6: 0.202699 seconds (x16)
46da52f4b820: 0.215551 seconds (+6%)
this code: 0.008397 seconds (-33% from base)
The payload size reduction we see in `test-bookmarks-pushpull.t` comes from a
more aggressive filter of nullid and is harmless.
Kyle Lippincott <spectral@google.com> [Fri, 17 Aug 2018 15:32:38 -0700] rev 39145
nodes: expand/comment the magic nodes so they are more easily searchable
We just encountered `
000000000000modified`, and it was quite annoying to search
for these, even though I knew they existed. For those that don't know that they
exist, this is essentially impossible to search for :)
(Technically we encountered it in its hex form,
3030303030303030303030306d6f646966696564, so I'm adding comments with those
forms in case that's helpful to people in the future).
Differential Revision: https://phab.mercurial-scm.org/D4331
Yuya Nishihara <yuya@tcha.org> [Fri, 17 Aug 2018 13:07:33 +0900] rev 39144
revlog: obtain the first node at the lowest layer while building pure nodemap
Just for clarity. This doesn't matter in practice since changelog.nodemap
is accessed *before* filtered revisions get ready.
Yuya Nishihara <yuya@tcha.org> [Fri, 17 Aug 2018 12:54:50 +0900] rev 39143
revlog: fix pure nodemap to not access missing index entry
This bug was revealed by
a3dacabd476b and
a1f934573c0b.
Yuya Nishihara <yuya@tcha.org> [Fri, 17 Aug 2018 12:48:44 +0900] rev 39142
changelog: remove copy of revlog.nodemap()
It's been there since 2012, "clfilter: introduce `filteredrevs` attribute
on changelog." I don't think we can apply changelog filtering to nodemap at
this level, so this patch removes the nodemap stub completely.
Boris Feld <boris.feld@octobus.net> [Fri, 17 Aug 2018 16:00:32 -0700] rev 39141
remotephase: fast path newheads computation in simple case (
issue5964)
Changeset
88efb7d6bcb6 fixed the logic of `phases.newheads` but greatly
regressed its performance (up to many order of magnitude). The first step to
fix the regression is to exit early when there is no work to do. If there are
no heads to filter or not roots to filter them, we don't have to do any work.
This fixes the regression when talking to an all public changeset. The
performance is even better than before.
pypy, compared to an all public repo
------------------------------------
8eeed92475d5: 0.005758 seconds
88efb7d6bcb6: 0.602517 seconds (x104)
this code: 0.001508 seconds (-74% from base)
mercurial compared to an all public repo
----------------------------------------
8eeed92475d5: 0.000577 seconds
88efb7d6bcb6: 0.185316 seconds (x321)
this code: 0.000150 seconds (-74% from base)
The performance of newheads, when actual computations are required, is fixed
in the next changeset.