phases: rework the logic of _pushdiscoveryphase to bound complexity
This rework the various graph traversal in _pushdiscoveryphase to keep the
complexity in check.
This is done though a couple of things:
- first, limiting the space we have to explore, for example, if we are not in
publishing push, we don't need to consider remote draft roots that are also
draft locally, as there is nothing to be moved there.
- avoid unbounded descendant computation, and use the faster "rev between"
computation.
This provide a massive boost to performance when exchanging with repository with
a massive amount of draft, like mozilla-try:
### data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog
# benchmark.name = hg.command.push
# bin-env-vars.hg.flavor = default
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.explicit-rev = all-out-heads
# benchmark.variants.issue6528 = disabled
# benchmark.variants.protocol = ssh
# benchmark.variants.reuse-external-delta-parent = default
## benchmark.variants.revs = any-1-extra-rev
before: 20.346590 seconds
after: 11.232059 seconds (-38.15%, -7.48 seconds)
## benchmark.variants.revs = any-100-extra-rev
before: 24.752051 seconds
after: 15.367412 seconds (-37.91%, -9.38 seconds)
After this changes, the push operation is still quite too slow. Some of this
can be attributed to general phases slowness (reading all the roots from disk
for example) and other know slowness (not using persistent-nodemap, branchmap,
tags, etc. We are also working on them, but with this series, phase discovery
during push no longer showing up in profile and this is a pretty nice and bit
low-hanging fruit out of the way.
### (same case as the above)
# benchmark.variants.revs = any-1-extra-rev
pre-%ln-change: 44.235070
this-changeset: 11.232059 seconds (-74.61%, -33.00 seconds)
# benchmark.variants.revs = any-100-extra-rev
pre-%ln-change: 49.234697
this-changeset: 15.367412 seconds (-68.79%, -33.87 seconds)
Note that with this change, the `hg push` performance is now much closer to the
`hg pull` performance, even it still lagging behind a bit. (and the overall
performance are still too slow).
### data-env-vars.name = mozilla-try-2023-03-22-ds2-pnm
# benchmark.variants.explicit-rev = all-out-heads
# benchmark.variants.issue6528 = disabled
# benchmark.variants.protocol = ssh
# benchmark.variants.pulled-delta-reuse-policy = default
# bin-env-vars.hg.flavor = rust
## benchmark.variants.revs = any-1-extra-rev
hg.command.pull: 6.517450
hg.command.push: 11.219888
## benchmark.variants.revs = any-100-extra-rev
hg.command.pull: 10.160991
hg.command.push: 14.251107
### data-env-vars.name = mozilla-try-2023-03-22-zstd-sparse-revlog
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.explicit-rev = all-out-heads
# benchmark.variants.issue6528 = disabled
# benchmark.variants.protocol = ssh
# benchmark.variants.pulled-delta-reuse-policy = default
## bin-env-vars.hg.flavor = default
## benchmark.variants.revs = any-1-extra-rev
hg.command.pull: 8.577772
hg.command.push: 11.232059
## bin-env-vars.hg.flavor = default
## benchmark.variants.revs = any-100-extra-rev
hg.command.pull: 13.152976
hg.command.push: 15.367412
## bin-env-vars.hg.flavor = rust
## benchmark.variants.revs = any-1-extra-rev
hg.command.pull: 8.731982
hg.command.push: 11.178751
## bin-env-vars.hg.flavor = rust
## benchmark.variants.revs = any-100-extra-rev
hg.command.pull: 13.184236
hg.command.push: 15.620843
= Mercurial 6.0.3 =
* Fix an infinite loop in edge cases of the pure Python dirstate-v2 packer
* Fix a small race condition with deleted files in Rust-augmented status
* Small improvement to Python 3.11 compatibility
* Fixed some typos in help messages that caused missing sections
* Centos -> Rockylinux packaging
= Mercurial 6.0.2 =
* Fix `hg incoming` and `hg outgoing` with remote subrepos on Windows
* Fix Rust build on MacOS
* Fix a (15 year old?) bug where some data loss could happen in a very tight race window (f38ae2d7390e + ccd9cb73125c)
* Remove support for running `hg unamend` on merge changesets at it was never actually implemented
* Fix stream-clone requirements filtering which caused some stream-clones to be unusable from an older version of Mercurial
* Rename dirstate-v2 configuration name from `exp-rc-dirstate-v2` to `use-dirstate-v2`. This was overlooked in `6.0`, the old name will be kept as an alias for compatibility.
* Fix a bug where the branchmap could point to uncommitted data
= Mercurial 6.0.1 =
* Improve documentation around Rust (see hg help rust) and rust-related actions
* Improve upgrade/downgrade edge cases for dirstate-v2
* Make the test suite nicer to big-endian platforms
* Make the test suite nicer to NetBSD
* Fix a performance regression on fsmonitor (issue6612)
* Add fixes for Python 3.10
* Fix a deadlock when using sparse and share-safe together
= Mercurial 6.0 =
== New Features ==
* `debugrebuildfncache` now has an option to rebuild only the index files
* a new `bookmarks.mode` path option have been introduced to control the
bookmark update strategy during exchange with a peer. See `hg help paths` for
details.
* a new `bookmarks.mirror` option has been introduced. See `hg help bookmarks`
for details.
* more commands support detailed exit codes when config `ui.detailed-exit-codes` is enabled
== Default Format Change ==
== New Experimental Features ==
* '''Major feature''': version 2 of the dirstate is available (the first version is as old as Mercurial itself). It allows for much faster working copy inspection (status, diff, commit, update, etc.) and richer information (symlink and exec info on Windows, etc.). The format has been frozen with room for some future evolution and the current implementations (Python, Python + C, Python + Rust or pure Rust) should be compatible with any future change or optimization that the format allows. You can get more information [[https://www.mercurial-scm.org/repo/hg/file/tip/mercurial/helptext/internals/dirstate-v2.txt | in the internal documentation]]
* Added a new `web.full-garbage-collection-rate` to control performance. See
de2e04fe4897a554b9ef433167f11ea4feb2e09c for more information
* Added a new `histedit.later-commits-first` option to affect the ordering of commits in `chistedit` to match the order in `hg log -G`. It will affect the text-based version before graduating from experimental.
== Bug Fixes ==
* `hg fix --working-dir` now correctly works when in an uncommitted merge state
* Unintentional duplicated calls to `hg fix`'s internals were removed, making it potentially much faster
* `rhg cat` can be called without a revision
* `rhg cat` can be called with the `.` revision
* `rhg cat` is more robust than before with regards to edge cases. Some still remain like a tag or bookmark that is ambiguous with a nodeid prefix, only nodeids (prefixed or not) are supported as of now.
* `rhg cat` is even faster
* `rhg` (Rust fast-path for `hg`) now supports the full config list syntax
* `rhg` now parses some corner-cases for revsets correctly
* Fixed an `fsmonitor` on Python 3 during exception handling
* Lots of Windows fixes
* Lots of miscellaneous other fixes
* Removed a CPython-specific compatibility hack to improve support for alternative Python implementations
== Backwards Compatibility Changes ==
== Internal API Changes ==
The following functions have been removed:
* `dirstate.normal`
* `dirstate.normallookup`
* `dirstate.otherparent`
* `dirstate.add`
* `dirstate.addfile`
* `dirstate.remove`
* `dirstate.drop`
* `dirstate.dropfile`
* `dirstate.__getitem__`
* `dirstatemap.nonnormalentries`
* `dirstatemap.nonnormalset`
* `dirstatemap.otherparentset`
* `dirstatemap.non_normal_or_other_parent_paths`
* `dirstateitem.dm_nonnormal`
* `dirstateitem.dm_otherparent`
* `dirstateitem.merged_removed`
* `dirstateitem.from_p2`
* `dirstateitem.merged`
* `dirstateitem.new_merged`
* `dirstateitem.new_added`
* `dirstateitem.new_from_p2`
* `dirstateitem.new_possibly_dirty`
* `dirstateitem.new_normal`
* `dirstateitem.from_p2_removed`
Miscellaneous:
* `wireprotov1peer`'s `batchable` is now a simple function and not a generator
anymore
* The Rust extensions (and by extension the experimental `rhg status`) only use a tree-based dirstate in-memory, even when using dirstate-v1. See bf8837e3d7cec40fe649c47163a3154dda03fa16 for more details
* The Rust minimum supported version is now 1.48.0 in accordance with out policy of keeping up with Debian stable
* The test harness plays nicer with the NixOS sandbox