Mercurial > evolve
changeset 5468:053f1fc12545 mercurial-4.6
test-compat: merge mercurial-4.7 into mercurial-4.6
author | Anton Shestakov <av6@dwimlabs.net> |
---|---|
date | Fri, 31 Jul 2020 19:19:13 +0800 |
parents | 88f9bbba392d (current diff) d04a9bf34b79 (diff) |
children | b1b00517f352 |
files | .gitlab-ci.yml tests/test-evolve-obshistory-content-divergent.t tests/test-evolve-wdir.t tests/test-evolve.t tests/test-obsolete.t |
diffstat | 27 files changed, 382 insertions(+), 228 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri May 08 22:50:09 2020 +0800 +++ b/.hgtags Fri Jul 31 19:19:13 2020 +0800 @@ -86,3 +86,4 @@ ef41094c34e162eb32ef24bf66d9776d1112751a 9.2.2 583dc6ef3eb21fbf6574021136f32b8a1163506c 9.3.0 8d955635cf457aaa4810d77740721d4275001f74 9.3.1 +27d57ca8686590867e62e3d42c96bad84a5f56ef 10.0.0
--- a/CHANGELOG Fri May 08 22:50:09 2020 +0800 +++ b/CHANGELOG Fri Jul 31 19:19:13 2020 +0800 @@ -1,6 +1,23 @@ Changelog ========= +10.0.1 - in progress +-------------------- + + * compatibility with Mercurial 5.5 + + * evolve: update the template keywords section in `hg help -e evolve` + + * obslog: make obslog --no-origin -f work with multiple successor sets + +topic (0.19.1) + + * compatibility with Mercurial 5.5 + + * topic: hg push --topic does-not-exist now doesn't try to push unrelated + changesets and aborts instead + * topic: hg outgoing/push --topic . will use current topic + 10.0.0 -- 2020-05-09 --------------------
--- a/contrib/check-compat-strings.sh Fri May 08 22:50:09 2020 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -unset GREP_OPTIONS - -# This script finds compatibility-related comments with a node hash specified -# in all files in a given directory (. by default) and looks up the hash in a -# repo (~/hg by default) to determine if each of the comments is correct and, -# if not, it suggests the correct release. This can prevent accidentally -# removing a piece of code that was misattributed to a different (earlier) -# release of core hg. - -# Usage: $0 WDIR HGREPO where WDIR is usually evolve/hgext3rd/ and HGREPO is -# the place with core Mercurial repo (not just checkout). Said repo has to be -# sufficiently up-to-date, otherwise this script may not work correctly. - -workdir=${1:-'.'} -hgdir=${2:-~/hg} -grep -Ern 'hg <= [0-9.]+ \([0-9a-f+]+\)' "$workdir" | while read -r line; do - bashre='hg <= ([0-9.]+) \(([0-9a-f+]+)\)' - if [[ $line =~ $bashre ]]; then - expected=${BASH_REMATCH[1]} - revset=${BASH_REMATCH[2]} - tagrevset="max(tag('re:^[0-9]\\.[0-9]$') - ($revset)::)" - lastrel=$(HGPLAIN=1 hg --cwd "$hgdir" log -r "$tagrevset" -T '{tags}') - if [[ "$lastrel" != "$expected" ]]; then - echo "$line" - echo "actual last major release without $revset is $lastrel" - echo - fi - fi -done
--- a/hgext3rd/evolve/__init__.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/__init__.py Fri Jul 31 19:19:13 2020 +0800 @@ -153,40 +153,33 @@ you create will not cause interference with other clients or servers without the effect flag recording. -Templates -========= +Template keywords +================= + +Evolve provides one template keyword that helps explore obsolescence history: -Evolve ship several templates that you can use to have a better visibility -about your obs history: + - obsorigin, for each changeset display a line summarizing what changed + between the changeset and its predecessors. Depending on the verbosity + level (-q and -v) it displays the users that created the obsmarkers and the + date range of these operations. - - precursors, for each obsolete changeset show the closest visible - precursors. - - successors, for each obsolete changeset show the closest visible - successors. It is useful when your working directory is obsolete to see - what are its successors. This information can also be retrieved with the - obslog command and the --all option. - - obsfate, for each obsolete changeset display a line summarizing what - changed between the changeset and its successors. Depending on the - verbosity level (-q and -v) it display the changeset successors, the users - that created the obsmarkers and the date range of these changes. +Evolve used to provide these template keywords, which since have been included +in core Mercurial (see :hg:`help templates -v`): + + - obsolete + - obsfate (including obsfatedata, see also obsfate* template functions) - The template itself is not complex, the data are basically a list of - successortset. Each successorset is a dict with these fields: +For compatibility, this extension also provides the following aliases to +template keywords from core Mercurial: - - "verb", how did the revision changed, pruned or rewritten for the moment - - "users" a sorted list of users that have create obs marker between current - changeset and one of its successor - - "min_date" the tiniest date of the first obs marker between current - changeset and one of its successor - - "max_date" the biggest date between current changeset and one of its - successor - - "successors" a sorted list of locally know successors node ids - - "markers" the raw list of changesets. + - precursors (deprecated, use predecessors instead) + - successors (deprecated, use successorssets instead) + - troubles (deprecated, use instabilities instead) """ evolutionhelptext = b""" Obsolescence markers make it possible to mark changesets that have been -deleted or superset in a new version of the changeset. +deleted or superseded in a new version of the changeset. Unlike the previous way of handling such changes, by stripping the old changesets from the repository, obsolescence markers can be propagated
--- a/hgext3rd/evolve/compat.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/compat.py Fri Jul 31 19:19:13 2020 +0800 @@ -12,6 +12,7 @@ from mercurial import ( context, copies, + merge as mergemod, obsolete, pycompat, registrar, @@ -35,6 +36,13 @@ except (AttributeError, ImportError): dirs = util.dirs # pytype: disable=module-attr +# hg <= 5.4 (b7808443ed6a) +try: + from mercurial import mergestate as mergestatemod + mergestate = mergestatemod.mergestate +except (AttributeError, ImportError): + mergestate = mergemod.mergestate # pytype: disable=module-attr + from . import ( exthelper, )
--- a/hgext3rd/evolve/evolvecmd.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/evolvecmd.py Fri Jul 31 19:19:13 2020 +0800 @@ -1981,7 +1981,7 @@ def continueevolve(ui, repo, evolvestate): """logic for handling of `hg evolve --continue`""" - ms = merge.mergestate.read(repo) + ms = compat.mergestate.read(repo) mergeutil.checkunresolved(ms) if (evolvestate[b'command'] == b'next' or evolvestate[b'category'] == b'orphan'):
--- a/hgext3rd/evolve/metadata.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/metadata.py Fri Jul 31 19:19:13 2020 +0800 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -__version__ = b'10.0.0' +__version__ = b'10.0.1.dev' testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4' minimumhgversion = b'4.6' buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obsdiscovery.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/obsdiscovery.py Fri Jul 31 19:19:13 2020 +0800 @@ -28,7 +28,7 @@ exchange, extensions, localrepo, - node, + node as nodemod, obsolete, scmutil, store, @@ -195,7 +195,7 @@ def debugobshashrange(ui, repo, **opts): """display the ::REVS set topologically sorted in a stable way """ - s = node.short + s = nodemod.short revs = scmutil.revrange(repo, opts['rev']) # prewarm depth cache if revs: @@ -218,7 +218,7 @@ r[1], rangelength(repo, r), depthrev(repo, r[0]), - node.short(_obshashrange(repo, r))) + s(_obshashrange(repo, r))) ui.status(linetemplate % d) repo.obsstore.rangeobshashcache.save(repo) @@ -230,7 +230,7 @@ if obshash is not None: return obshash pieces = [] - nullid = node.nullid + nullid = nodemod.nullid if repo.stablerange.rangelength(repo, rangeid) == 1: rangenode = cl.node(rangeid[0]) tmarkers = repo.obsstore.relevantmarkers([rangenode]) @@ -249,7 +249,7 @@ # note: if there is only one subrange with actual data, we'll just # reuse the same hash. if not pieces: - obshash = node.nullid + obshash = nodemod.nullid elif len(pieces) != 1 or obshash is None: sha = hashlib.sha1() for p in pieces: @@ -293,34 +293,35 @@ """ affected_nodes = set() known_markers = set(markers) - node_to_proceed = set() - marker_to_proceed = set(known_markers) + nodes_to_proceed = set() + markers_to_proceed = set(known_markers) - obsstore = repo.obsstore + successors = repo.obsstore.successors + predecessors = repo.obsstore.predecessors - while node_to_proceed or marker_to_proceed: - while marker_to_proceed: - m = marker_to_proceed.pop() + while nodes_to_proceed or markers_to_proceed: + while markers_to_proceed: + marker = markers_to_proceed.pop() # check successors and parent - if m[1]: - relevant = (m[1], ) + if marker[1]: + relevant = (marker[1], ) else: # prune case - relevant = ((m[0], ), m[5]) - for l in relevant: - if l is None: + relevant = ((marker[0], ), marker[5]) + for relnodes in relevant: + if relnodes is None: continue - for n in l: - if n not in affected_nodes: - node_to_proceed.add(n) - affected_nodes.add(n) - # marker_to_proceed is now empty: - if node_to_proceed: - n = node_to_proceed.pop() + for node in relnodes: + if node not in affected_nodes: + nodes_to_proceed.add(node) + affected_nodes.add(node) + # markers_to_proceed is now empty: + if nodes_to_proceed: + node = nodes_to_proceed.pop() markers = set() - markers.update(obsstore.successors.get(n, ())) - markers.update(obsstore.predecessors.get(n, ())) + markers.update(successors.get(node, ())) + markers.update(predecessors.get(node, ())) markers -= known_markers - marker_to_proceed.update(markers) + markers_to_proceed.update(markers) known_markers.update(markers) return affected_nodes @@ -669,7 +670,7 @@ repo.obsstore.rangeobshashcache.update(repo) for r in ranges: if r[0] is None: - result.append(node.wdirid) + result.append(nodemod.wdirid) else: result.append(_obshashrange(repo, r)) repo.obsstore.rangeobshashcache.save(repo) @@ -843,13 +844,13 @@ revs = unfi.revs(b'::(%ln - null) - %ld', pullop.common, filteredrevs) boundaries = {b'heads': pullop.pulledsubset} if not revs: # nothing common - boundaries[b'common'] = [node.nullid] + boundaries[b'common'] = [nodemod.nullid] return boundaries if not usediscovery(repo): # discovery disabled by users. repo.ui.status(obsdiscovery_skip_message) - boundaries[b'common'] = [node.nullid] + boundaries[b'common'] = [nodemod.nullid] return boundaries if bundle2 and _canobshashrange(repo, remote): @@ -864,7 +865,7 @@ common = repo.set("heads(only(%ld, %ln))", revs, missing) boundaries[b'common'] = [c.node() for c in common] else: - boundaries[b'common'] = [node.nullid] + boundaries[b'common'] = [nodemod.nullid] return boundaries # merge later for outer layer wrapping
--- a/hgext3rd/evolve/obsexchange.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/obsexchange.py Fri Jul 31 19:19:13 2020 +0800 @@ -52,7 +52,7 @@ ARGUMENTS_LIMIT = 200 -OVERFLOW_MSG = """obsmarkers differ for %d common nodes +OVERFLOW_MSG = b"""obsmarkers differ for %d common nodes | | This might be too much for the remote HTTP server that doesn't accept | arguments through POST request. (config: experimental.httppostargs=yes)
--- a/hgext3rd/evolve/obshistory.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/evolve/obshistory.py Fri Jul 31 19:19:13 2020 +0800 @@ -219,9 +219,14 @@ r = obsutil.successorsandmarkers(repo, ctx) if r is None: r = [] - for succset in sorted(r): - if succset[b'markers']: - yield (succset[b'successors'], succset[b'markers']) + # replacing dicts and sets, they can't be compared + data = [ + (succset[b'successors'], tuple(sorted(succset[b'markers']))) + for succset in r + ] + for (nodes, markers) in sorted(data): + if markers: + yield (nodes, markers) else: markers = successors.get(ctx.node(), ()) for marker in sorted(markers):
--- a/hgext3rd/pullbundle.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/pullbundle.py Fri Jul 31 19:19:13 2020 +0800 @@ -190,7 +190,12 @@ ms = missingrevs.copy() ss = [] allslices = [] - missingheads = [rev(n) for n in sorted(outgoing.missingheads, reverse=True)] + # hg <= 5.4 (c93dd9d9f1e6) + if util.safehasattr(outgoing, 'ancestorsof'): + missingheads = outgoing.ancestorsof + else: + missingheads = outgoing.missingheads + missingheads = [rev(n) for n in sorted(missingheads, reverse=True)] for head in missingheads: localslices = [] localmissing = set(repo.revs(b'%ld and ::%d', missingrevs, head)) @@ -375,9 +380,11 @@ return num and not num & (num - 1) def outgoingfromnodes(repo, nodes): - return discovery.outgoing(repo, - missingroots=nodes, - missingheads=nodes) + # hg <= 5.4 (c93dd9d9f1e6) + if r'ancestorsof' in discovery.outgoing.__init__.__code__.co_varnames: + return discovery.outgoing(repo, missingroots=nodes, ancestorsof=nodes) + else: + return discovery.outgoing(repo, missingroots=nodes, missingheads=nodes) # changegroup part construction
--- a/hgext3rd/serverminitopic.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/serverminitopic.py Fri Jul 31 19:19:13 2020 +0800 @@ -33,6 +33,14 @@ default=False, ) +# hg <= 5.4 (e2d17974a869) +def nonpublicphaseroots(repo): + if util.safehasattr(repo._phasecache, 'nonpublicphaseroots'): + return repo._phasecache.nonpublicphaseroots(repo) + return set().union( + *[roots for roots in repo._phasecache.phaseroots[1:] if roots] + ) + def hasminitopic(repo): """true if minitopic is enabled on the repository @@ -106,11 +114,10 @@ cl = repo.changelog fr = cl.filteredrevs nm = cl.nodemap - for roots in repo._phasecache.phaseroots[1:]: - for n in roots: - r = nm.get(n) - if r not in fr and r < maxrev: - revs.add(r) + for n in nonpublicphaseroots(repo): + r = nm.get(n) + if r not in fr and r < maxrev: + revs.add(r) key = node.nullid revs = sorted(revs) if revs:
--- a/hgext3rd/topic/__init__.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/topic/__init__.py Fri Jul 31 19:19:13 2020 +0800 @@ -202,7 +202,7 @@ b'topic.active': b'green', } -__version__ = b'0.19.0' +__version__ = b'0.19.1.dev' testedwith = b'4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4' minimumhgversion = b'4.6' @@ -1269,7 +1269,11 @@ def pushoutgoingwrap(orig, ui, repo, *args, **opts): if opts.get('topic'): - topicrevs = repo.revs(b'topic(%s) - obsolete()', opts['topic']) + topic = opts['topic'] + if topic == b'.': + topic = repo.currenttopic + topic = b'literal:' + topic + topicrevs = repo.revs(b'topic(%s) - obsolete()', topic) opts.setdefault('rev', []).extend(topicrevs) return orig(ui, repo, *args, **opts)
--- a/hgext3rd/topic/compat.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/topic/compat.py Fri Jul 31 19:19:13 2020 +0800 @@ -38,3 +38,11 @@ if util.safehasattr(cl.index, 'get_rev'): return cl.index.get_rev return cl.nodemap.get + +# hg <= 5.4 (e2d17974a869) +def nonpublicphaseroots(repo): + if util.safehasattr(repo._phasecache, 'nonpublicphaseroots'): + return repo._phasecache.nonpublicphaseroots(repo) + return set().union( + *[roots for roots in repo._phasecache.phaseroots[1:] if roots] + )
--- a/hgext3rd/topic/stack.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/topic/stack.py Fri Jul 31 19:19:13 2020 +0800 @@ -44,10 +44,10 @@ this area. """ phasesets = repo._phasecache._phasesets - if not phasesets or None in phasesets[phases.draft:]: + if not phasesets: return repo.revs(b'(not public()) - obsolete()') - result = set.union(*phasesets[phases.draft:]) + result = set.union(*[phasesets[phase] for phase in phases.trackedphases]) result -= obsolete.getrevs(repo, b'obsolete') return result
--- a/hgext3rd/topic/topicmap.py Fri May 08 22:50:09 2020 +0800 +++ b/hgext3rd/topic/topicmap.py Fri Jul 31 19:19:13 2020 +0800 @@ -71,11 +71,10 @@ cl = repo.changelog fr = cl.filteredrevs getrev = compat.getgetrev(cl) - for roots in repo._phasecache.phaseroots[1:]: - for n in roots: - r = getrev(n) - if r not in fr and r < maxrev: - revs.add(r) + for n in compat.nonpublicphaseroots(repo): + r = getrev(n) + if r not in fr and r < maxrev: + revs.add(r) key = nullid revs = sorted(revs) if revs:
--- a/tests/hghaveaddon.py Fri May 08 22:50:09 2020 +0800 +++ b/tests/hghaveaddon.py Fri Jul 31 19:19:13 2020 +0800 @@ -12,3 +12,14 @@ except ImportError: return False return True + +@hghave.check("flake8", "Flake8 python linter") +def has_flake8(): + try: + import flake8 + + flake8.__version__ + except ImportError: + return False + else: + return True
--- a/tests/test-check-compat-strings.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-check-compat-strings.t Fri Jul 31 19:19:13 2020 +0800 @@ -5,4 +5,4 @@ > evolution = all > EOF - $ $TESTDIR/../contrib/check-compat-strings.sh "$TESTDIR/../hgext3rd/" "$RUNTESTDIR/.." + $ $TESTDIR/testlib/check-compat-strings.sh "$TESTDIR/../hgext3rd/" "$RUNTESTDIR/.."
--- a/tests/test-check-flake8.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-check-flake8.t Fri Jul 31 19:19:13 2020 +0800 @@ -1,12 +1,4 @@ -#require test-repo - - $ checkflake8() { - > if ! (which flake8 > /dev/null); then - > echo skipped: missing tool: flake8; - > exit 80; - > fi; - > }; - $ checkflake8 +#require test-repo flake8 Copied from Mercurial core (60ee2593a270) @@ -17,4 +9,4 @@ $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \ > -X hgext3rd/evolve/thirdparty \ > 2>/dev/null \ - > | xargs -0 flake8 + > | xargs -0 "$PYTHON" -m flake8
--- a/tests/test-check-pyflakes.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-check-pyflakes.t Fri Jul 31 19:19:13 2020 +0800 @@ -7,5 +7,7 @@ run pyflakes on all tracked files ending in .py or without a file ending (skipping binary file random-seed) - $ hg locate -I 'set:(**.py or grep("^#!.*python")) - removed()' 2>/dev/null \ - > | xargs pyflakes 2>/dev/null + $ hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' \ + > -X hgext3rd/evolve/thirdparty \ + > 2>/dev/null \ + > | xargs -0 "$PYTHON" -m pyflakes 2>/dev/null
--- a/tests/test-evolve-obshistory-content-divergent.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-evolve-obshistory-content-divergent.t Fri Jul 31 19:19:13 2020 +0800 @@ -98,6 +98,11 @@ +A1 + $ hg obslog --hidden 'desc(A0)' --no-origin -f + x 471f378eab4c (1) A0 + reworded(description) as 65b757b745b9 using amend by test (Thu Jan 01 00:00:00 1970 +0000) + reworded(description) as fdf9bde5129a using amend by test (Thu Jan 01 00:00:00 1970 +0000) + Check that with all option, every changeset is shown $ hg obslog --hidden --all 471f378eab4c --patch @@ -123,6 +128,15 @@ | x 471f378eab4c (1) A0 + $ hg obslog --hidden --all 'desc(A0)' --no-origin -f + @ 65b757b745b9 (3) A2 + | + | * fdf9bde5129a (2) A1 + |/ + x 471f378eab4c (1) A0 + reworded(description) as 65b757b745b9 using amend by test (Thu Jan 01 00:00:00 1970 +0000) + reworded(description) as fdf9bde5129a using amend by test (Thu Jan 01 00:00:00 1970 +0000) + $ hg obslog --hidden 471f378eab4c --no-graph --no-origin -Tjson | python -m json.tool [ {
--- a/tests/test-evolve-obshistory.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-evolve-obshistory.t Fri Jul 31 19:19:13 2020 +0800 @@ -1,5 +1,4 @@ -This test file test the various messages when accessing obsolete -revisions. +Testing obslog and other commands accessing obsolete revisions. Global setup ============
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-evolve-wdir.t Fri Jul 31 19:19:13 2020 +0800 @@ -0,0 +1,114 @@ +=============================================== +Testing evolution of obsolete working directory +=============================================== + +Pulling changes from other repos can make your working directory parent (wdir) +obsolete, most probably because now it has a new successor. But there are +other cases as well where it might be pruned with no successors or split +in multiple changesets etc. + +This test file deals with all the possible cases for the evolution from an +obsolete working directory parent. + +.. Case A: obsolete wdp with single successor +.. Resolution : simply update to the successor +.. +.. Case B: obsolete wdp with no successor (simply pruned) +.. Resolution : update to a not-dead ancestor +.. +.. Case C: obsolete wdp with multiple successor (divergence rewriting) +.. Resolution : #TODO: not handled yet +.. +.. Case D: obsolete wdp with multiple successor (split rewriting) +.. Resolution : #TODO: not handled yet + +A. Obsolete wdp with single successor +------------------------------------- + +Setup + $ . $TESTDIR/testlib/common.sh + $ cat >> $HGRCPATH <<EOF + > [extensions] + > evolve= + > rebase= + > [alias] + > glog = log --graph --template "{rev}:{node|short} ({phase}): {desc|firstline} {if(troubles, '[{troubles}]')}\n" + > EOF + + $ hg init repo + $ cd repo + $ mkcommit c_A + $ mkcommit c_B + $ hg amend -m "u_B" + $ hg up -r 'desc(c_B)' --hidden + updating to a hidden changeset 707ee88b2870 + (hidden revision '707ee88b2870' was rewritten as: 9bf151312dec) + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory parent is obsolete! (707ee88b2870) + (use 'hg evolve' to update to its successor: 9bf151312dec) + + $ hg evolve + update:[2] u_B + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at 9bf151312dec + $ hg glog + @ 2:9bf151312dec (draft): u_B + | + o 0:9f0188af4c58 (draft): c_A + + +B. Obsolete wdp with no successor +--------------------------------- + + $ hg prune . + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory is now at 9f0188af4c58 + 1 changesets pruned + $ hg up -r 'desc(c_B)' --hidden + updating to a hidden changeset 707ee88b2870 + (hidden revision '707ee88b2870' is pruned) + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory parent is obsolete! (707ee88b2870) + (use 'hg evolve' to update to its parent successor) + + $ hg evolve + update:[0] c_A + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory is now at 9f0188af4c58 + $ hg glog + @ 0:9f0188af4c58 (draft): c_A + + +C. Obsolete wdp with multiple successor (divergence rewriting) +--------------------------------------------------------------- + + $ hg metaedit -r 'desc(u_B)' -d '0 1' --hidden + $ hg metaedit -r 'desc(c_B)' -d '0 1' --hidden + 2 new content-divergent changesets + $ hg up -r 'min(desc(c_B))' --hidden + updating to a hidden changeset 707ee88b2870 + (hidden revision '707ee88b2870' has diverged) + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory parent is obsolete! (707ee88b2870) + (707ee88b2870 has diverged, use 'hg evolve --list --content-divergent' to resolve the issue) + + $ hg evolve + parent is obsolete with multiple successors: + [3] u_B + [4] c_B + [2] + + $ hg glog + * 4:39e54eb7aa3c (draft): c_B [content-divergent] + | + | * 3:90624b574289 (draft): u_B [content-divergent] + |/ + | @ 1:707ee88b2870 (draft): c_B + |/ + o 0:9f0188af4c58 (draft): c_A + + +D. Obsolete wdp with multiple successor (split rewriting) +---------------------------------------------------------- + +#TODO: yet to write tests for this case
--- a/tests/test-evolve.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-evolve.t Fri Jul 31 19:19:13 2020 +0800 @@ -48,7 +48,7 @@ """""""""""""""""""""""" Obsolescence markers make it possible to mark changesets that have been - deleted or superset in a new version of the changeset. + deleted or superseded in a new version of the changeset. Unlike the previous way of handling such changes, by stripping the old changesets from the repository, obsolescence markers can be propagated
--- a/tests/test-obsolete.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-obsolete.t Fri Jul 31 19:19:13 2020 +0800 @@ -523,22 +523,17 @@ should not rebase extinct changesets -#excluded 'whole rebase set is extinct and ignored.' message not in core - $ hg rebase -b '3' -d 4 --traceback --config experimental.rebaseskipobsolete=0 - rebasing 3:0d3f46688ccc "add obsol_c" + $ hg rebase -b '3' -d 4 --traceback + note: not rebasing 3:0d3f46688ccc "add obsol_c", already in destination as 4:725c380fe99b "add obsol_c'" rebasing 8:159dfc9fa5d3 "add obsol_d''" - 2 new content-divergent changesets - $ hg --hidden log -q -r 'successors(3)' + $ hg --hidden log -q -r 'successors(min(desc("re:^add obsol_c$")))' 4:725c380fe99b - 10:2033b4e49474 $ hg up tip ? files updated, 0 files merged, 0 files removed, 0 files unresolved (glob) $ hg log -G --template='{rev} - {node|short} {desc}\n' - @ 11 - 9468a5f5d8b2 add obsol_d'' + @ 10 - 8396b69aa9f7 add obsol_d'' | - * 10 - 2033b4e49474 add obsol_c - | - * 4 - 725c380fe99b add obsol_c' + o 4 - 725c380fe99b add obsol_c' | o 1 - 7c3bad9141dc add b | @@ -554,14 +549,13 @@ adding changesets adding manifests adding file changes - added 2 changesets with 1 changes to [12] files (re) - 3 new obsolescence markers + added 1 changesets with 1 changes to [12] files (re) + 2 new obsolescence markers obsoleted 1 changesets - 2 new content-divergent changesets - $ hg up -q 10 + $ hg up -q 'desc("re:^add obsol_c'\''$")' $ mkcommit "obsol_d'''" created new head - $ hg debugobsolete `getid 11` `getid 12` + $ hg debugobsolete `getid 'max(desc("re:^add obsol_d'\'\''$"))'` `getid 'desc("re:^add obsol_d'\'\'\''$")'` obsoleted 1 changesets $ hg push ../other-new --traceback pushing to ../other-new @@ -578,15 +572,13 @@ (make an obsolete changeset public) $ cd local - $ hg phase --hidden --public 11 + $ hg phase --hidden --public 'max(desc("re:^add obsol_d'\'\''$"))' 1 new phase-divergent changesets $ hg log -G --template='{rev} - ({phase}) {node|short} {desc}\n' - @ 12 - (draft) 6db5e282cb91 add obsol_d''' + @ 11 - (draft) 5a9eef7b778b add obsol_d''' | - | o 11 - (public) 9468a5f5d8b2 add obsol_d'' + | o 10 - (public) 8396b69aa9f7 add obsol_d'' |/ - o 10 - (public) 2033b4e49474 add obsol_c - | o 4 - (public) 725c380fe99b add obsol_c' | o 1 - (public) 7c3bad9141dc add b @@ -594,9 +586,9 @@ o 0 - (public) 1f0dee641bb7 add a $ hg log -r 'phasedivergent()' - changeset: 12:6db5e282cb91 + changeset: 11:5a9eef7b778b tag: tip - parent: 10:2033b4e49474 + parent: 4:725c380fe99b user: test date: Thu Jan 01 00:00:00 1970 +0000 instability: phase-divergent @@ -605,7 +597,7 @@ $ hg push ../other-new/ pushing to ../other-new/ searching for changes - abort: push includes phase-divergent changeset: 6db5e282cb91! + abort: push includes phase-divergent changeset: 5a9eef7b778b! (use 'hg evolve' to get a stable history or --force to ignore warnings) [255] @@ -618,31 +610,26 @@ $ echo 42 >> f $ hg commit --amend --traceback --quiet $ hg log -G - @ changeset: 14:705ab2a6b72e + @ changeset: 13:6491691ca36f | tag: tip - | parent: 10:2033b4e49474 + | parent: 4:725c380fe99b | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: add f | - | * changeset: 12:6db5e282cb91 - |/ parent: 10:2033b4e49474 + | * changeset: 11:5a9eef7b778b + |/ parent: 4:725c380fe99b | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | instability: phase-divergent | summary: add obsol_d''' | - | o changeset: 11:9468a5f5d8b2 - |/ user: test + | o changeset: 10:8396b69aa9f7 + |/ parent: 4:725c380fe99b + | user: test | date: Thu Jan 01 00:00:00 1970 +0000 | summary: add obsol_d'' | - o changeset: 10:2033b4e49474 - | parent: 4:725c380fe99b - | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: add obsol_c - | o changeset: 4:725c380fe99b | parent: 1:7c3bad9141dc | user: test @@ -667,76 +654,51 @@ 909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} 1f0dee641bb7258c56bd60e93edfa2405381c41e 83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} 83b5778897adafb967ef2f75be3aaa4fce49a4cc 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} - 0d3f46688ccc6e756c7e96cf64c391c411309597 2033b4e494742365851fac84d276640cbf52833e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} - 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} - 9468a5f5d8b2c5d91e17474e95ae4791e9718fdf 6db5e282cb91df5c43ff1f1287c119ff83230d42 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} - 0b1b6dd009c037985363e2290a0b579819f659db 705ab2a6b72e2cd86edb799ebe15f2695f86143e 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'} -#no produced by 2.3 -33d458d86621f3186c40bfccd77652f4a122743e 3734a65252e69ddcced85901647a4f335d40de1e 0 {'date': '* *', 'user': 'test'} (glob) + 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 8396b69aa9f7b4ea03ed94c63641e3c021d71f0c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'rebase', 'user': 'test'} + 8396b69aa9f7b4ea03ed94c63641e3c021d71f0c 5a9eef7b778bf2ba5e6cc1b741ec5a2110ba1480 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} + bc294e7f0681bbed7b83047814e9eadabead2f8d 6491691ca36ffa1b1c48d9bf8605ac5a25d200f6 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'} Check divergence detection (note: multiple successors is sorted by changeset hash) - $ hg up 9468a5f5d8b2 # add obsol_d'' + $ hg up 'max(desc("re:^add obsol_d'\'\''$"))' # add obsol_d'' 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ mkcommit "obsolet_conflicting_d" $ hg summary - parent: 15:50f11e5e3a63 tip + parent: 14:553bdab4dee8 tip add obsolet_conflicting_d branch: default commit: (clean) update: (2|9|11) new changesets, (3|9|10) branch heads \(merge\) (re) phases: 3 draft phase-divergent: 1 changesets - $ hg debugobsolete `getid a7a6f2b5d8a5` `getid 50f11e5e3a63` + $ hg debugobsolete `getid 'desc("re:^add d$")'` `getid 'desc("re:^add obsolet_conflicting_d$")'` 2 new content-divergent changesets $ hg log -r 'contentdivergent()' - changeset: 12:6db5e282cb91 - parent: 10:2033b4e49474 + changeset: 11:5a9eef7b778b + parent: 4:725c380fe99b user: test date: Thu Jan 01 00:00:00 1970 +0000 instability: phase-divergent, content-divergent summary: add obsol_d''' - changeset: 15:50f11e5e3a63 + changeset: 14:553bdab4dee8 tag: tip - parent: 11:9468a5f5d8b2 + parent: 10:8396b69aa9f7 user: test date: Thu Jan 01 00:00:00 1970 +0000 instability: content-divergent summary: add obsolet_conflicting_d - $ hg up --hidden 3 -q - updating to a hidden changeset 0d3f46688ccc - (hidden revision '0d3f46688ccc' has diverged) - working directory parent is obsolete! (0d3f46688ccc) - $ hg evolve - parent is obsolete with multiple successors: - [4] add obsol_c' - [10] add obsol_c - [2] - $ hg olog -a - o 2033b4e49474 (10) add obsol_c - | rebased(parent) from 0d3f46688ccc using rebase by test (Thu Jan 01 00:00:00 1970 +0000) - | - | o 725c380fe99b (4) add obsol_c' - |/ rewritten from 0d3f46688ccc by test (Thu Jan 01 00:00:00 1970 +0000) - | - @ 0d3f46688ccc (3) add obsol_c - | rewritten from 4538525df7e2 by test (Thu Jan 01 00:00:00 1970 +0000) - | - x 4538525df7e2 (2) add c - - Check import reports new unstable changeset: - $ hg up --hidden 2 + $ hg up --hidden 'desc("re:^add c$")' updating to a hidden changeset 4538525df7e2 - (hidden revision '4538525df7e2' has diverged) - 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + (hidden revision '4538525df7e2' was rewritten as: 725c380fe99b) + 1 files updated, 0 files merged, 3 files removed, 0 files unresolved working directory parent is obsolete! (4538525df7e2) - (4538525df7e2 has diverged, use 'hg evolve --list --content-divergent' to resolve the issue) - $ hg export 9468a5f5d8b2 | hg import - + (use 'hg evolve' to update to its successor: 725c380fe99b) + $ hg export 'desc("re:^add obsol_d'\'\''$")' | hg import - applying patch from stdin 1 new orphan changesets @@ -745,7 +707,7 @@ ============================== $ hg log -G --hidden - @ changeset: 16:a5f7a21fe7bc + @ changeset: 15:a5f7a21fe7bc | tag: tip | parent: 2:4538525df7e2 | user: test @@ -753,44 +715,39 @@ | instability: orphan | summary: add obsol_d'' | - | * changeset: 15:50f11e5e3a63 - | | parent: 11:9468a5f5d8b2 + | * changeset: 14:553bdab4dee8 + | | parent: 10:8396b69aa9f7 | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | instability: content-divergent | | summary: add obsolet_conflicting_d | | - | | o changeset: 14:705ab2a6b72e - | | | parent: 10:2033b4e49474 + | | o changeset: 13:6491691ca36f + | | | parent: 4:725c380fe99b | | | user: test | | | date: Thu Jan 01 00:00:00 1970 +0000 | | | summary: add f | | | - | | | x changeset: 13:0b1b6dd009c0 - | | |/ parent: 10:2033b4e49474 + | | | x changeset: 12:bc294e7f0681 + | | |/ parent: 4:725c380fe99b | | | user: test | | | date: Thu Jan 01 00:00:00 1970 +0000 - | | | obsolete: amended using amend as 14:705ab2a6b72e + | | | obsolete: amended using amend as 13:6491691ca36f | | | summary: add f | | | - | | | * changeset: 12:6db5e282cb91 - | | |/ parent: 10:2033b4e49474 + | | | * changeset: 11:5a9eef7b778b + | | |/ parent: 4:725c380fe99b | | | user: test | | | date: Thu Jan 01 00:00:00 1970 +0000 | | | instability: phase-divergent, content-divergent | | | summary: add obsol_d''' | | | - | o | changeset: 11:9468a5f5d8b2 - | |/ user: test + | o | changeset: 10:8396b69aa9f7 + | |/ parent: 4:725c380fe99b + | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | summary: add obsol_d'' | | - | o changeset: 10:2033b4e49474 - | | parent: 4:725c380fe99b - | | user: test - | | date: Thu Jan 01 00:00:00 1970 +0000 - | | summary: add obsol_c - | | | | x changeset: 9:83b5778897ad | | parent: -1:000000000000 | | user: test @@ -802,7 +759,7 @@ | | | parent: 3:0d3f46688ccc | | | user: test | | | date: Thu Jan 01 00:00:00 1970 +0000 - | | | obsolete: rebased using rebase as 11:9468a5f5d8b2 + | | | obsolete: rebased using rebase as 10:8396b69aa9f7 | | | summary: add obsol_d'' | | | | | | x changeset: 7:909a0fb57e5d @@ -824,7 +781,7 @@ | | | user: test | | | date: Thu Jan 01 00:00:00 1970 +0000 | | | obsolete: rewritten as 6:95de7fc6918d - | | | obsolete: rewritten as 15:50f11e5e3a63 + | | | obsolete: rewritten as 14:553bdab4dee8 | | | summary: add d | | | | o | changeset: 4:725c380fe99b @@ -838,7 +795,6 @@ | | user: test | | date: Thu Jan 01 00:00:00 1970 +0000 | | obsolete: rewritten as 4:725c380fe99b - | | obsolete: rebased using rebase as 10:2033b4e49474 | | summary: add obsol_c | | x | changeset: 2:4538525df7e2 @@ -860,17 +816,17 @@ Simple rewrite - $ hg --hidden debugobsolete --rev 3 + $ hg --hidden debugobsolete --rev 'min(desc("re:^add obsol_c$"))' 4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} simple rewrite with a prune attached to it - $ hg debugobsolete --rev 15 - a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 50f11e5e3a63806e678c734e525502f522d37e38 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} + $ hg debugobsolete --rev 'desc("re:^add obsolet_conflicting_d$")' + a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 553bdab4dee8f0032cd60de38be72d1d2e8225d5 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} Transitive rewrite - $ hg --hidden debugobsolete --rev 8 + $ hg --hidden debugobsolete --rev 'min(desc("re:^add obsol_d'\'\''$"))' 909a0fb57e5d909f353d89e394ffd7e0890fec88 159dfc9fa5d334d7e03a0aecfc7f7ab4c3431fea 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} 95de7fc6918dea4c9c8d5382f50649794b474c4a 909a0fb57e5d909f353d89e394ffd7e0890fec88 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} a7a6f2b5d8a54b81bc7aa2fba2934ad6d700a79e 95de7fc6918dea4c9c8d5382f50649794b474c4a 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- a/tests/test-topic-push.t Fri May 08 22:50:09 2020 +0800 +++ b/tests/test-topic-push.t Fri Jul 31 19:19:13 2020 +0800 @@ -192,6 +192,22 @@ |/ o 0 default public CA + + $ hg outgoing draft --topic nonexistent + abort: topic 'nonexistent' does not exist! + [255] + $ hg push draft --topic nonexistent + abort: topic 'nonexistent' does not exist! + [255] + + $ hg up babar + switching to topic babar + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg outgoing draft --topic . + comparing with $TESTTMP/draft + searching for changes + 5 default babar draft C'A + $ hg outgoing draft --topic babar comparing with $TESTTMP/draft searching for changes
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/testlib/check-compat-strings.sh Fri Jul 31 19:19:13 2020 +0800 @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -euo pipefail + +unset GREP_OPTIONS + +# This script finds compatibility-related comments with a node hash specified +# in all files in a given directory (. by default) and looks up the hash in a +# repo (~/hg by default) to determine if each of the comments is correct and, +# if not, it suggests the correct release. This can prevent accidentally +# removing a piece of code that was misattributed to a different (earlier) +# release of core hg. + +# Usage: $0 WDIR HGREPO where WDIR is usually evolve/hgext3rd/ and HGREPO is +# the place with core Mercurial repo (not just checkout). Said repo has to be +# sufficiently up-to-date, otherwise this script may not work correctly. + +workdir=${1:-'.'} +hgdir=${2:-~/hg} +grep -Ern 'hg <= [0-9.]+ \([0-9a-f+]+\)' "$workdir" | while read -r line; do + bashre='hg <= ([0-9.]+) \(([0-9a-f+]+)\)' + if [[ $line =~ $bashre ]]; then + expected=${BASH_REMATCH[1]} + revset=${BASH_REMATCH[2]} + tagrevset="max(tag('re:^[0-9]\\.[0-9]$') - ($revset)::)" + lastrel=$(HGPLAIN=1 hg --cwd "$hgdir" log -r "$tagrevset" -T '{tags}') + if [[ "$lastrel" != "$expected" ]]; then + echo "$line" + echo "actual last major release without $revset is $lastrel" + echo + fi + fi +done