# HG changeset patch # User Anton Shestakov # Date 1645457185 -10800 # Node ID 74665d83fb3b72183fdf5ff1465a7827d08c7323 # Parent 1a20edff5cbd71d83f9dab830802ee7bebc594ee# Parent 30ca8eb17b21676c3fc9a94653eadd0f7b85d9b6 branching: merge stable into default diff -r 30ca8eb17b21 -r 74665d83fb3b .gitlab-ci.yml --- a/.gitlab-ci.yml Mon Feb 21 18:18:10 2022 +0300 +++ b/.gitlab-ci.yml Mon Feb 21 18:26:25 2022 +0300 @@ -1,7 +1,7 @@ .prepare_hg: &prepare_hg - hg pull -R /ci/repos/mercurial/ - hg pull -R /ci/repos/mercurial/ https://www.mercurial-scm.org/repo/hg-committed - - hg_branch=$(tests/testlib/map-hg-rev.sh "$(hg identify --branch)") + - hg_branch=${HG_BRANCH:-$(tests/testlib/map-hg-rev.sh "$(hg identify --branch)")} - hg -R /ci/repos/mercurial/ update "$hg_branch" - hg_rev=$(hg log -R /ci/repos/mercurial/ -r . -T '{node}') - echo testing with mercurial branch="$hg_branch", revision="$hg_rev" @@ -93,3 +93,30 @@ - dist/* only: - tags + +.windows_runtests_template: &windows_runtests + before_script: + - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && ls -1 tests/test-check-*.t > C:/Temp/check-tests.txt' + script: + - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && tests/testlib/update-hg-repo.sh C:/Temp/hg' + - > + C:/MinGW/msys/1.0/bin/sh.exe --login -c ' + cd "$OLDPWD" && + evo_branch=$(hg identify --branch) && + hg_branch=${HG_BRANCH:-$(tests/testlib/map-hg-rev.sh "$evo_branch")} && + hg -R C:/Temp/hg update "$hg_branch" && + hg_rev=$(hg log -R C:/Temp/hg -r . -T "\{node\}") && + echo testing with mercurial branch="$hg_branch", revision="$hg_rev"' + - Invoke-Expression "$Env:PYTHON --version" + - echo "$Env:RUNTEST_ARGS" + - C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && HGMODULEPOLICY="$TEST_HGMODULEPOLICY" $PYTHON C:/Temp/hg/tests/run-tests.py --color=always $RUNTEST_ARGS' + +windows-py3: + <<: *windows_runtests + tags: + - windows + variables: + PYTHON: py -3 + RUNTEST_ARGS: "--blacklist C:/Temp/check-tests.txt" + TEST_HGMODULEPOLICY: "c" + when: manual diff -r 30ca8eb17b21 -r 74665d83fb3b .gitlab/issue_templates/new-version.md --- a/.gitlab/issue_templates/new-version.md Mon Feb 21 18:18:10 2022 +0300 +++ b/.gitlab/issue_templates/new-version.md Mon Feb 21 18:26:25 2022 +0300 @@ -26,4 +26,5 @@ * [ ] send the announcement by email to evolve-testers@mercurial-scm.org * [ ] send the announcement by email to mercurial@mercurial-scm.org * [ ] publish the announcement as a blog on https://octobus.net/blog/ +* [ ] update #hg-evolve topic * [ ] tweet about it diff -r 30ca8eb17b21 -r 74665d83fb3b .hgignore --- a/.hgignore Mon Feb 21 18:18:10 2022 +0300 +++ b/.hgignore Mon Feb 21 18:26:25 2022 +0300 @@ -1,24 +1,30 @@ -syntax: re -/figures/[^/]+\.png$ -^html/ -\.pyc$ -~$ -\.swp$ -\.orig$ -\.rej$ -^tests/.*\.err$ -^tests/easy_run.sh$ -^build/ -^dist/ -^MANIFEST$ -^docs/tutorials/.*\.rst$ -\.ico$ -tests/\.testtimes +syntax: glob +*.py[cdo] +*~ +*.swp +*.orig +*.rej +*.egg-info -^docs/training/graphs/ -^docs/training/html/ -^docs/training/index.html -^docs/training/graphviz-images/ -^docs/training/img/ -^docs/training/output/ -^docs/training/pandocfilters/ +syntax: rootglob +.idea/ +.mypy_cache/ +.pytype/ +.vscode/ +html/ +build/ +dist/ +MANIFEST +tests/easy_run.sh +tests/*.err +tests/.testtimes* +docs/training/graphs/ +docs/training/html/ +docs/training/index.html +docs/training/graphviz-images/ +docs/training/img/ +docs/training/output/ +docs/training/pandocfilters/ +docs/tutorials/**.rst +docs/figures/**.png +docs/static/**.ico diff -r 30ca8eb17b21 -r 74665d83fb3b CHANGELOG --- a/CHANGELOG Mon Feb 21 18:18:10 2022 +0300 +++ b/CHANGELOG Mon Feb 21 18:26:25 2022 +0300 @@ -1,14 +1,25 @@ Changelog ========= -10.4.2 - in progress +10.5.0 - in progress -------------------- -topic (0.23.2) + * evolve: handle cases when working directory parent has multiple successors + * multiple commands: do not check for new divergence if divergence is allowed + via configuration + * fixup: a new experimental command to add working directory changes to a + specified revision + * pick: show abort message after pick is aborted for consistency + + * evolve, pullbundle: drop compatibility with Mercurial 4.7 + +topic (0.24.0) * topic: make histedit preserve topics when the first changeset in a stack is rewritten (issue6550) + * drop compatibility with Mercurial 4.7 + 10.4.1 -- 2021-11-19 -------------------- diff -r 30ca8eb17b21 -r 74665d83fb3b debian/control --- a/debian/control Mon Feb 21 18:18:10 2022 +0300 +++ b/debian/control Mon Feb 21 18:26:25 2022 +0300 @@ -7,15 +7,14 @@ Pierre-Yves David , Standards-Version: 4.3.0 Build-Depends: - mercurial (>= 4.7), - python, + mercurial (>= 4.8), python3, debhelper (>= 10), dh-python, - python-sphinx, - imagemagick, - librsvg2-bin, - graphviz, + python3-sphinx , + imagemagick , + librsvg2-bin , + graphviz , X-Python3-Version: >= 3.6 Homepage: https://www.mercurial-scm.org/doc/evolution/ Vcs-Browser: https://www.mercurial-scm.org/repo/evolve/ @@ -24,11 +23,10 @@ Package: mercurial-evolve Architecture: all Depends: - ${python:Depends}, ${python3:Depends}, ${misc:Depends}, ${sphinxdoc:Depends}, - mercurial (>= 4.7), + mercurial (>= 4.8), Built-Using: ${sphinxdoc:Built-Using} Description: evolve extension for Mercurial This package provides the experimental "evolve" extension for the Mercurial diff -r 30ca8eb17b21 -r 74665d83fb3b debian/rules --- a/debian/rules Mon Feb 21 18:18:10 2022 +0300 +++ b/debian/rules Mon Feb 21 18:26:25 2022 +0300 @@ -2,13 +2,12 @@ #export DH_VERBOSE=1 %: - dh $@ --with python2,python3,sphinxdoc --buildsystem=pybuild + dh $@ --with python3,sphinxdoc --buildsystem=pybuild ifeq (,$(filter nodoc, $(DEB_BUILD_OPTIONS))) override_dh_auto_build: dh_auto_build - # Workaround for Sphinx in Debian Buster defaulting to Python 3 - SPHINXBUILD="python -m sphinx -bhtml" $(MAKE) -C docs + $(MAKE) -C docs endif hgsrc_defined: @@ -20,11 +19,6 @@ cd tests && python $(HGSRC)/tests/run-tests.py --with-hg=$(HGSRC)/hg --blacklist=$(CURDIR)/debian/test-blacklist endif -override_dh_python2: - # avoid conflict with mercurial's own hgext3rd/__init__.py - find debian -path '*/hgext3rd/__init__.py' -delete - dh_python2 - override_dh_python3: # avoid conflict with mercurial's own hgext3rd/__init__.py find debian -path '*/hgext3rd/__init__.py' -delete diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/__init__.py Mon Feb 21 18:26:25 2022 +0300 @@ -33,7 +33,7 @@ backported to older version of Mercurial by this extension. Some older experimental protocols are also supported for a longer time in the extension to help people transitioning. (The extension is currently compatible down to -Mercurial version 4.7). +Mercurial version 4.8). New Config:: @@ -1151,6 +1151,11 @@ b'(also see `hg help evolve.interrupted`)') return cmdutil._commentlines(_msg) +def _fixupmessage(): + _msg = _(b'To continue: hg fixup --continue\n' + b'To abort: hg fixup --abort\n') + return cmdutil._commentlines(_msg) + @eh.uisetup def setupevolveunfinished(ui): if not util.safehasattr(cmdutil, 'unfinishedstates'): @@ -1165,6 +1170,10 @@ abortfunc=evolvecmd.hgabortevolve) statemod.addunfinished(b'pick', fname=b'pickstate', continueflag=True, abortfunc=cmdrewrite.hgabortpick) + _fixup_msg = _(b'To continue: hg fixup --continue\n' + b'To abort: hg fixup --abort\n') + statemod.addunfinished(b'fixup', fname=b'fixup-state', + continueflag=True, statushint=_fixup_msg) else: # hg <= 5.0 (5f2f6912c9e6) estate = (b'evolvestate', False, False, _(b'evolve in progress'), @@ -1173,16 +1182,23 @@ pstate = (b'pickstate', False, False, _(b'pick in progress'), _(b"use 'hg pick --continue' or 'hg pick --abort' to abort")) cmdutil.unfinishedstates.append(pstate) + fstate = (b'fixup-state', False, False, _(b'fixup in progress'), + _(b"use 'hg fixup --continue' or 'hg fixup --abort' to abort")) + cmdutil.unfinishedstates.append(fstate) afterresolved = (b'evolvestate', _(b'hg evolve --continue')) pickresolved = (b'pickstate', _(b'hg pick --continue')) + fixupresolved = (b'fixup-state', _(b'hg fixup --continue')) cmdutil.afterresolvedstates.append(afterresolved) cmdutil.afterresolvedstates.append(pickresolved) + cmdutil.afterresolvedstates.append(fixupresolved) + # hg <= 5.0 (12243f15d53e) if util.safehasattr(cmdutil, 'STATES'): - statedata = (b'evolve', cmdutil.fileexistspredicate(b'evolvestate'), - _evolvemessage) - cmdutil.STATES = (statedata, ) + cmdutil.STATES + cmdutil.STATES = ( + (b'evolve', cmdutil.fileexistspredicate(b'evolvestate'), _evolvemessage), + (b'fixup', cmdutil.fileexistspredicate(b'fixup-state'), _fixupmessage), + ) + cmdutil.STATES @eh.wrapfunction(hg, 'clean') def clean(orig, repo, *args, **kwargs): diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/cmdrewrite.py Mon Feb 21 18:26:25 2022 +0300 @@ -30,6 +30,7 @@ pycompat, scmutil, util, + repair, ) from mercurial.utils import dateutil @@ -42,6 +43,7 @@ exthelper, rewriteutil, utility, + evolvecmd, ) eh = exthelper.exthelper() @@ -1430,10 +1432,11 @@ raise error.Abort(_(b"no interrupted pick state exists")) pickstate.load() pctxnode = pickstate[b'oldpctx'] - ui.status(_(b"aborting pick, updating to %s\n") % - node.short(pctxnode)) compat.clean_update(repo[pctxnode]) pickstate.delete() + ui.status(_(b'pick aborted\n')) + ui.status(_(b'working directory is now at %s\n') + % node.short(pctxnode)) return 0 def hgabortpick(ui, repo): @@ -1441,3 +1444,153 @@ with repo.wlock(), repo.lock(): pickstate = state.cmdstate(repo, path=b'pickstate') return abortpick(ui, repo, pickstate, abortcmd=True) + +@eh.command( + b'fixup|fix-up', + [ + (b'r', b'rev', b'', _(b'revision to amend'), _(b'REV')), + (b'c', b'continue', False, _(b'continue an interrupted fixup')), + (b'', b'abort', False, _(b'abort an interrupted fixup')), + ], + _(b'[OPTION]... [-r] REV'), + helpbasic=True, + **compat.helpcategorykwargs('CATEGORY_COMMITTING') +) +def fixup(ui, repo, node=None, **opts): + """add working directory changes to an arbitrary revision + + A new changeset will be created, superseding the one specified. The new + changeset will combine working directory changes with the changes in the + target revision. + + This operation requires the working directory changes to be relocated onto + the target revision, which might result in merge conflicts. + + If fixup is interrupted to manually resolve a conflict, it can be continued + with --continue/-c, or aborted with --abort. + + Note that this command is fairly new and its behavior is still + experimental. For example, the working copy will be left on a temporary, + obsolete commit containing the fixed-up changes after the operation. This + might change in the future. + + Returns 0 on success, 1 if nothing changed. + """ + compat.check_at_most_one_arg(opts, 'continue', 'abort') + with repo.wlock(), repo.lock(): + return _perform_fixup(ui, repo, node, **opts) + +def _perform_fixup(ui, repo, node, **opts): + contopt = opts.get('continue') + abortopt = opts.get('abort') + if node or opts.get('rev'): + if contopt: + raise error.Abort(_(b'cannot specify a revision with --continue')) + if abortopt: + raise error.Abort(_(b'cannot specify a revision with --abort')) + # state file for --continue/--abort cases + fixup_state = state.cmdstate(repo, b'fixup-state') + if contopt: + if not fixup_state.exists(): + raise error.Abort(_(b'no interrupted fixup to continue')) + fixup_state.load() + return continuefixup(ui, repo, fixup_state) + if abortopt: + if not fixup_state.exists(): + raise error.Abort(_(b'no interrupted fixup to abort')) + fixup_state.load() + return abortfixup(ui, repo, fixup_state) + + if node and opts.get('rev'): + raise error.Abort(_(b'please specify just one revision')) + if not node: + node = opts.get('rev') + if not node: + raise error.Abort(_(b'please specify a revision to fixup')) + target_ctx = scmutil.revsingle(repo, node) + + fixup_state[b'startnode'] = repo[b'.'].node() + + tr = repo.transaction(b'fixup') + with util.acceptintervention(tr): + overrides = {(b'ui', b'allowemptycommit'): False} + with repo.ui.configoverride(overrides, b'fixup'): + tempnode = repo.commit( + text=b'temporary fixup commit', user=opts.get(b'user'), + date=opts.get(b'date')) + if tempnode is None: + ui.status(_(b"nothing changed\n")) + return 1 + fixup_state[b'tempnode'] = tempnode + # XXX: storing 'tempnode' should be enough, but 'current' + # is used by _relocate() logic + fixup_state[b'current'] = tempnode + fixup_state[b'target'] = target_ctx.node() + with state.saver(fixup_state): + # relocate temporary node to target revision + newnode = evolvecmd._relocate( + repo, repo[tempnode], target_ctx, fixup_state, update=False + ) + # fold the two changesets + revs = (repo[newnode].rev(), target_ctx.rev()) + root, head, p2 = rewriteutil.foldcheck(repo, revs) + + allctx = [repo[r] for r in revs] + commitopts = {b'edit': False, b'message': target_ctx.description()} + newid, unusedvariable = rewriteutil.rewrite( + repo, root, head, [root.p1().node(), p2.node()], + commitopts=commitopts + ) + phases.retractboundary(repo, tr, target_ctx.phase(), [newid]) + replacements = {tuple(ctx.node() for ctx in allctx): [newid]} + compat.cleanupnodes(repo, replacements, operation=b'fixup') + fixup_state.delete() + compat.update(repo.unfiltered()[tempnode]) + return 0 + +def continuefixup(ui, repo, fixup_state): + """logic for handling of `hg fixup --continue`""" + target_node = fixup_state[b'target'] + tempnode = fixup_state[b'tempnode'] + target_ctx = repo[target_node] + tr = repo.transaction(b'fixup') + with util.acceptintervention(tr): + newnode = evolvecmd._completerelocation(ui, repo, fixup_state) + current = repo[fixup_state[b'current']] + obsolete.createmarkers(repo, [(current, (repo[newnode],))], + operation=b'fixup') + # fold the two changesets + revs = (repo[newnode].rev(), target_ctx.rev()) + root, head, p2 = rewriteutil.foldcheck(repo, revs) + + allctx = [repo[r] for r in revs] + commitopts = {b'edit': False, b'message': target_ctx.description()} + newid, unusedvariable = rewriteutil.rewrite( + repo, root, head, [root.p1().node(), p2.node()], + commitopts=commitopts + ) + phases.retractboundary(repo, tr, target_ctx.phase(), [newid]) + replacements = {tuple(ctx.node() for ctx in allctx): [newid]} + compat.cleanupnodes(repo, replacements, operation=b'fixup') + fixup_state.delete() + compat.update(repo.unfiltered()[tempnode]) + return 0 + +def abortfixup(ui, repo, fixup_state): + """logic for handling of `hg fixup --abort`""" + with repo.wlock(), repo.lock(): + startnode = fixup_state[b'startnode'] + tempnode = fixup_state[b'tempnode'] + tempctx = repo[tempnode] + compat.clean_update(repo[startnode]) + + stats = merge.graft(repo, tempctx, tempctx.p1(), [b'graft', b'fixup']) + # conflict is not possible, since grafting changes from descendant + assert not stats.unresolvedcount + repair.strip(ui, repo, [tempnode], backup=False) + + pctx = repo[b'.'] + ui.status(_(b'fixup aborted\n')) + ui.status(_(b'working directory is now at %s\n') % pctx) + fixup_state.delete() + return 0 diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/evolvecmd.py Mon Feb 21 18:26:25 2022 +0300 @@ -133,14 +133,14 @@ ui.write_err(msg) return (False, b".") if exc.splitflag: - splitsucc = utility.picksplitsuccessor(ui, repo, obs, orig) - if not splitsucc[0]: + splitsucc = utility.select_split_successor(ui, repo, obs) + if not splitsucc: msg = _(b"could not solve instability, " b"ambiguous destination: " b"parent split across two branches\n") ui.write_err(msg) return (False, b".") - newer = splitsucc[1] + newer = splitsucc target = repo[newer] if not ui.quiet or confirm: repo.ui.write(_(b'move:'), label=b'evolve.operation') @@ -816,16 +816,18 @@ there were conflicts or not while merging the messages""" merger = simplemerge.Merge3Text(basedesc, divdesc, othdesc) - mdesc = [] - kwargs = {} - kwargs['name_base'] = b'base' - kwargs['base_marker'] = b'|||||||' - for line in merger.merge_lines(name_a=b'divergent', name_b=b'other', - **kwargs): - mdesc.append(line) + kwargs = {'name_a': b'divergent', 'name_b': b'other', 'name_base': b'base'} - desc = b''.join(mdesc) - if merger.conflicts: + if util.safehasattr(simplemerge, 'render_merge3'): + lines, conflicts = simplemerge.render_merge3(merger, **kwargs) + desc = b''.join(lines) + else: + # hg <= 6.0 (12ac4401ff7d) + kwargs['base_marker'] = b'|||||||' + desc = b''.join(merger.merge_lines(**kwargs)) + conflicts = merger.conflicts + + if conflicts: prefixes = (b"HG: Conflicts while merging changeset description of" b" content-divergent changesets.\nHG: Resolve conflicts" @@ -1138,18 +1140,14 @@ Fall back to rev number, but in ascending order, for historical reasons. """ ledmap = { - # For purpose of comparing, from `led` which is (unixtime, offset) - # we only need `unixtime`. + # for comparing, we only need unixtime from (unixtime, offset) rev: latest_evolution_date(repo, repo[rev])[0] for rev in divergent_revs } - # Sorting by negating the `rev` in key func, to fallback to the old way - # of selecting revision, in case when `led` is same while comparing. - # Old way: was to select the one with minimum revision number return sorted(divergent_revs, key=lambda rev: (-ledmap[rev], rev)) def latest_evolution_date(repo, ctx): - """Return latest evolution date of `ctx`""" + """Return latest evolution date of `ctx` as (unixtime, offset)""" node = ctx.node() nodes = list(obsutil.closestpredecessors(repo, node)) nodes.append(node) @@ -1814,21 +1812,33 @@ return ret def solveobswdp(ui, repo, opts): - """this function updates to the successor of obsolete wdir parent""" + """update to the successor of obsolete wdir parent""" oldid = repo[b'.'].node() - startctx = repo[b'.'] + oldctx = repo[b'.'] dryrunopt = opts.get('dry_run', False) display = compat.format_changeset_summary_fn(ui, repo, b'evolve', shorttemplate) try: - ctx = repo[utility._singlesuccessor(repo, repo[b'.'])] + ctx = repo[utility._singlesuccessor(repo, oldctx)] except utility.MultipleSuccessorsError as exc: - repo.ui.write_err(_(b'parent is obsolete with multiple' - b' successors:\n')) - for ln in exc.successorssets: - for n in ln: - display(repo[n]) - return 2 + if exc.splitflag: + splitsucc = utility.select_split_successor(ui, repo, oldctx) + if splitsucc: + ctx = repo[splitsucc] + else: + if util.safehasattr(error, 'CanceledError'): + err = error.CanceledError + else: + # hg <= 5.6 (ac362d5a7893) + err = error.Abort + raise err(_(b'user quit')) + elif exc.divergenceflag: + repo.ui.write_err(_(b'parent is obsolete with multiple' + b' content-divergent successors:\n')) + for sset in exc.successorssets: + for succ in sset: + display(repo[succ]) + return 2 ui.status(_(b'update:')) if not ui.quiet: @@ -1839,7 +1849,7 @@ res = hg.update(repo, ctx.rev()) newid = ctx.node() - if ctx != startctx: + if ctx != oldctx: with repo.wlock(), repo.lock(), repo.transaction(b'evolve') as tr: bmupdater = rewriteutil.bookmarksupdater(repo, oldid, tr) bmupdater(newid) diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/headchecking.py --- a/hgext3rd/evolve/headchecking.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/headchecking.py Mon Feb 21 18:26:25 2022 +0300 @@ -25,7 +25,10 @@ @eh.uisetup def uisetup(ui): extensions.wrapfunction(discovery, '_postprocessobsolete', _postprocessobsolete) - extensions.wrapfunction(scmutil, 'enforcesinglehead', enforcesinglehead) + code = scmutil.filteredhash.__code__ + if r'needobsolete' not in code.co_varnames[:code.co_argcount]: + # hg <= 6.0 (053a5bf508da) + extensions.wrapfunction(scmutil, 'enforcesinglehead', enforcesinglehead) def branchinfo(pushop, repo, node): return repo[node].branch() diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/metadata.py Mon Feb 21 18:26:25 2022 +0300 @@ -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.4.2.dev' -testedwith = b'4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0' -minimumhgversion = b'4.7' +__version__ = b'10.5.0.dev' +testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0' +minimumhgversion = b'4.8' buglink = b'https://bz.mercurial-scm.org/' diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/obscache.py --- a/hgext3rd/evolve/obscache.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/obscache.py Mon Feb 21 18:26:25 2022 +0300 @@ -433,7 +433,7 @@ def _computeobsoleteset(orig, repo): """the set of obsolete revisions""" repo = repo.unfiltered() - notpublic = repo._phasecache.getrevset(repo, (phases.draft, phases.secret)) + notpublic = repo._phasecache.getrevset(repo, phases.mutablephases) if notpublic: obscache = repo.obsstore.obscache # Since we warm the cache at the end of every transaction, the cache diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/rewriteutil.py --- a/hgext3rd/evolve/rewriteutil.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/rewriteutil.py Mon Feb 21 18:26:25 2022 +0300 @@ -85,11 +85,14 @@ msg %= (action, len(newunstable)) hint = _(b"see 'hg help evolution.instability'") raise error.Abort(msg, hint=hint) - divrisk = revs_hascontentdivrisk(repo, revs) allowdivergence = compat.isenabled(repo, compat.allowdivergenceopt) - if divrisk and not allowdivergence: - localdiv = repo[divrisk[0]] - otherdiv, base = repo[divrisk[1][0]], repo[divrisk[1][1]] + if allowdivergence: + return + divergence = new_divergence(repo, revs) + if divergence: + local, other, common_prec = divergence + localdiv = repo[local] + otherdiv, base = repo[other], repo[common_prec] msg = _(b"%s of %s creates content-divergence " b"with %s") % (action, localdiv, otherdiv) if localdiv.rev() != base.rev(): @@ -121,13 +124,16 @@ repo._bookmarks.applychanges(repo, tr, bmchanges) return updatebookmarks -def revs_hascontentdivrisk(repo, revs): +def new_divergence(repo, revs): + """Return a tuple (rev, divergent, common_precursor) if rewriting one of + the revs will create content-divergence. + """ obsrevs = repo.revs(b'%ld and obsolete()', revs) for r in obsrevs: - div = precheck_contentdiv(repo, repo[r]) - if div: - return [r, div] - return [] + div_prec = precheck_contentdiv(repo, repo[r]) + if div_prec: + divergent, common_prec = div_prec + return (r, divergent, common_prec) def disallowednewunstable(repo, revs): """Check that editing will not create disallowed unstable @@ -270,6 +276,7 @@ if commitopts.get(b'edit'): editor = cmdutil.commitforceeditor new = wctx.tomemctx(text=message, + branch=extra[b'branch'], parents=newbases, date=date, extra=extra, diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/evolve/utility.py --- a/hgext3rd/evolve/utility.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/evolve/utility.py Mon Feb 21 18:26:25 2022 +0300 @@ -128,32 +128,28 @@ return repo[newer[0][0]].rev() -def picksplitsuccessor(ui, repo, ctx, evolvecand): - """choose a successor of ctx from split targets +def select_split_successor(ui, repo, ctx): + """Return most suitable split successor of for evolution. - Choose highest one if all successors are in a topological branch. And if - they are split over multiple topological branches, we ask user to choose - an evolve destination. + If all successors are on one topological branch, we choose tipmost successor. + Otherwise, we ask user to choose an evolve destination. - Return (True, succ) unless split targets are split over multiple - topological branches and user didn't choose any evolve destination, - in which case return (False, '.') + Return ``None`` if no successor selected. """ targets = obsutil.successorssets(repo, ctx.node())[0] assert targets targetrevs = [repo[r].rev() for r in targets] heads = repo.revs(b'heads(%ld::%ld)', targetrevs, targetrevs) if len(heads) > 1: - cheader = (_(b"ancestor of '%s' split over multiple topological" - b" branches.\nchoose an evolve destination:") % - evolvecand) + cheader = (_(b"changeset %s split over multiple topological" + b" branches, choose an evolve destination:") % ctx) selectedrev = revselectionprompt(ui, repo, list(heads), cheader) if selectedrev is None: - return (False, '.') + return succ = repo[selectedrev] else: succ = repo[heads.first()] - return (True, repo[succ].rev()) + return repo[succ].rev() def _successorrevs(repo, ctx): try: diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/pullbundle.py --- a/hgext3rd/pullbundle.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/pullbundle.py Mon Feb 21 18:26:25 2022 +0300 @@ -93,8 +93,8 @@ from mercurial.i18n import _ __version__ = b'0.1.3.dev' -testedwith = b'4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9' -minimumhgversion = b'4.7' +testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9' +minimumhgversion = b'4.8' buglink = b'https://bz.mercurial-scm.org/' cmdtable = {} diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/serverminitopic.py --- a/hgext3rd/serverminitopic.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/serverminitopic.py Mon Feb 21 18:26:25 2022 +0300 @@ -33,6 +33,14 @@ default=False, ) +# nodemap.get and index.[has_node|rev|get_rev] +# hg <= 5.2 (02802fa87b74) +def getgetrev(cl): + """Returns index.get_rev or nodemap.get (for pre-5.3 Mercurial).""" + 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'): @@ -113,9 +121,9 @@ revs = set() cl = repo.changelog fr = cl.filteredrevs - nm = cl.nodemap + getrev = getgetrev(cl) for n in nonpublicphaseroots(repo): - r = nm.get(n) + r = getrev(n) if r not in fr and r < maxrev: revs.add(r) key = node.nullid diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/topic/__init__.py Mon Feb 21 18:26:25 2022 +0300 @@ -231,10 +231,10 @@ b'log.topic': b'green_background', } -__version__ = b'0.23.2.dev' +__version__ = b'0.24.0.dev' -testedwith = b'4.7 4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0' -minimumhgversion = b'4.7' +testedwith = b'4.8 4.9 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 6.0' +minimumhgversion = b'4.8' buglink = b'https://bz.mercurial-scm.org/' if util.safehasattr(registrar, 'configitem'): diff -r 30ca8eb17b21 -r 74665d83fb3b hgext3rd/topic/discovery.py --- a/hgext3rd/topic/discovery.py Mon Feb 21 18:18:10 2022 +0300 +++ b/hgext3rd/topic/discovery.py Mon Feb 21 18:26:25 2022 +0300 @@ -217,12 +217,18 @@ # # Handle this by doing an extra check for new head creation server side def _nbheads(repo): + code = scmutil.filteredhash.__code__ + if r'needobsolete' not in code.co_varnames[:code.co_argcount]: + # hg <= 6.0 (053a5bf508da) + filterfn = _filter_obsolete_heads + else: + filterfn = lambda repo, heads: heads data = {} for b in repo.branchmap().iterbranches(): if b':' in b[0]: continue oldheads = [repo[n].rev() for n in b[1]] - newheads = _filter_obsolete_heads(repo, oldheads) + newheads = filterfn(repo, oldheads) data[b[0]] = newheads return data diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-amend.t --- a/tests/test-amend.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-amend.t Mon Feb 21 18:26:25 2022 +0300 @@ -218,6 +218,7 @@ $ echo edited_a > a $ hg ci -m "edited a" 1 new orphan changesets + created new head $ hg debugobsolete $(hg id -ir 0 --debug) $(hg id -ir 2 --debug) 1 new obsolescence markers 2 new content-divergent changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-check-sdist.t --- a/tests/test-check-sdist.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-check-sdist.t Mon Feb 21 18:26:25 2022 +0300 @@ -35,7 +35,7 @@ $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files $ wc -l files - 353 files + 356 files $ fgrep debian files tests/test-check-debian.t $ fgrep __init__.py files diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-discovery-obshashrange.t --- a/tests/test-discovery-obshashrange.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-discovery-obshashrange.t Mon Feb 21 18:26:25 2022 +0300 @@ -305,7 +305,8 @@ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> sending hello command (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> sending between command (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> remote: * (glob) - * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> remote: capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch branchmap bundle2=HG20%0Abookmarks%0Achangegroup%3D01%2C02%0Acheckheads%3Drelated%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps%0Astream%3Dv2 changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> remote: capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch branchmap bundle2=HG20%0Abookmarks%0Achangegroup%3D01%2C02%0Acheckheads%3Drelated%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps%0Astream%3Dv2 changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-zstd !) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> remote: capabilities: _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch branchmap bundle2=HG20%0Abookmarks%0Achangegroup%3D01%2C02%0Acheckheads%3Drelated%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps%0Astream%3Dv2 changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlog-compression-zstd,revlogv1,sparserevlog unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (zstd !) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> remote: 1 (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> sending protocaps command (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> query 1; heads (glob) diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-content-divergent-corner-cases.t --- a/tests/test-evolve-content-divergent-corner-cases.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-content-divergent-corner-cases.t Mon Feb 21 18:26:25 2022 +0300 @@ -375,7 +375,7 @@ with: [6] updated e base: [4] added e rebasing "divergent" content-divergent changeset ff6f7cd76a7c on 5f6d8a4bf34a - file 'd' was deleted in local but was modified in other. + file 'd' was deleted in local [local] but was modified in other [other]. You can use (c)hanged version, leave (d)eleted, or leave (u)nresolved. What do you want to do? c 0 files updated, 1 files merged, 0 files removed, 0 files unresolved diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-content-divergent-interrupted.t --- a/tests/test-evolve-content-divergent-interrupted.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-content-divergent-interrupted.t Mon Feb 21 18:26:25 2022 +0300 @@ -383,8 +383,8 @@ $ hg evolve -c evolving 8:a8673909e314 "added d" merging a + warning: conflicts while merging a! (edit, then use 'hg resolve --mark') merging d - warning: conflicts while merging a! (edit, then use 'hg resolve --mark') warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 2 files unresolved unresolved merge conflicts diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-content-divergent-user-independent-resolution.t --- a/tests/test-evolve-content-divergent-user-independent-resolution.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-content-divergent-user-independent-resolution.t Mon Feb 21 18:26:25 2022 +0300 @@ -35,7 +35,7 @@ $ hg push -q $ cd ../local - $ hg push -q + $ hg push --force -q 2 new content-divergent changesets $ hg pull -q 2 new content-divergent changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-inmemory.t --- a/tests/test-evolve-inmemory.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-inmemory.t Mon Feb 21 18:26:25 2022 +0300 @@ -17,9 +17,9 @@ $ hg init single-orphan $ cd single-orphan $ hg debugdrawdag <<'EOS' - > C # C/c = c\n - > B2 | # B2/b = b2\n - > | B # B/b = b\n + > C # C/C = C\n + > B2 | # B2/B = B2\n + > | B # B/B = B\n > \ / # replace: B -> B2 > A > EOS @@ -28,19 +28,19 @@ move:[3] C atop:[2] B2 $ hg glog - o 4:52da76e91abb draft tip + o 4:a2a0434af50b draft tip | C - | x 3:bc77848cde3a draft C + | x 3:46f17045c5ee draft C | | C - o | 2:377a194b9b8a draft B2 + o | 2:3d6c495db414 draft B2 | | B2 - | x 1:830b6315076c draft B + | x 1:caf23a7900cb draft B |/ B o 0:426bada5c675 draft A A - $ hg cat -r tip b c - b2 - c + $ hg cat -r tip B C + B2 + C $ cd .. Test that in-memory evolve works when there are conflicts @@ -49,13 +49,13 @@ $ hg init conflicts $ cd conflicts $ hg debugdrawdag <<'EOS' - > E # E/e = e\n + > E # E/E = E\n > | - > D # D/b = d\n + > D # D/B = D\n > | - > C # C/c = c\n - > B2 | # B2/b = b2\n - > | B # B/b = b\n + > C # C/C = C\n + > B2 | # B2/B = B2\n + > | B # B/B = B\n > \ / # replace: B -> B2 > A > EOS @@ -64,67 +64,67 @@ move:[3] C atop:[2] B2 move:[4] D - merging b + merging B hit merge conflicts; retrying merge in working copy - merging b - warning: conflicts while merging b! (edit, then use 'hg resolve --mark') + merging B + warning: conflicts while merging B! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see 'hg help evolve.interrupted') [240] $ hg glog - @ 6:52da76e91abb draft tip + @ 6:a2a0434af50b draft tip | C - | * 5:eae7899dd92b draft E + | * 5:844900596917 draft E | | E - | % 4:57e51f6a6d36 draft D + | % 4:a75d38413966 draft D | | D - | x 3:bc77848cde3a draft C + | x 3:46f17045c5ee draft C | | C - o | 2:377a194b9b8a draft B2 + o | 2:3d6c495db414 draft B2 | | B2 - | x 1:830b6315076c draft B + | x 1:caf23a7900cb draft B |/ B o 0:426bada5c675 draft A A - $ cat c - c - $ cat b - <<<<<<< destination: 52da76e91abb - test: C - b2 + $ cat C + C + $ cat B + <<<<<<< destination: a2a0434af50b - test: C + B2 ======= - d - >>>>>>> evolving: 57e51f6a6d36 D - test: D - $ echo d2 > b + D + >>>>>>> evolving: a75d38413966 D - test: D + $ echo D2 > B $ hg resolve -m (no more unresolved files) continue: hg evolve --continue $ hg evolve --continue - evolving 4:57e51f6a6d36 "D" + evolving 4:a75d38413966 "D" move:[5] E atop:[7] D $ hg glog - o 8:3c658574f8ed draft tip + o 8:166afca01be8 draft tip | E - o 7:16e609b952e8 draft + o 7:4f84a36487e4 draft | D - o 6:52da76e91abb draft + o 6:a2a0434af50b draft | C - | x 5:eae7899dd92b draft E + | x 5:844900596917 draft E | | E - | x 4:57e51f6a6d36 draft D + | x 4:a75d38413966 draft D | | D - | x 3:bc77848cde3a draft C + | x 3:46f17045c5ee draft C | | C - o | 2:377a194b9b8a draft B2 + o | 2:3d6c495db414 draft B2 | | B2 - | x 1:830b6315076c draft B + | x 1:caf23a7900cb draft B |/ B o 0:426bada5c675 draft A A - $ hg cat -r tip b c e - d2 - c - e + $ hg cat -r tip B C E + D2 + C + E $ cd .. Test that in-memory merge is disabled if there's a precommit hook @@ -132,16 +132,16 @@ $ hg init precommit-hook $ cd precommit-hook $ hg debugdrawdag <<'EOS' - > C # C/c = c\n - > B2 | # B2/b = b2\n - > | B # B/b = b\n + > C # C/C = C\n + > B2 | # B2/B = B2\n + > | B # B/B = B\n > \ / # replace: B -> B2 > A > EOS 1 new orphan changesets $ cat >> .hg/hgrc < [hooks] - > precommit = echo "running precommit hook" + > precommit = sh -c "echo 'running precommit hook'" > EOF The hook is not run with in-memory=force $ hg co B2 @@ -149,20 +149,20 @@ $ hg evolve --config experimental.evolution.in-memory=force --update move:[3] C atop:[2] B2 - working directory is now at 52da76e91abb + working directory is now at a2a0434af50b $ hg glog - @ 4:52da76e91abb draft tip + @ 4:a2a0434af50b draft tip | C - | x 3:bc77848cde3a draft C + | x 3:46f17045c5ee draft C | | C - o | 2:377a194b9b8a draft B2 + o | 2:3d6c495db414 draft B2 | | B2 - | x 1:830b6315076c draft B + | x 1:caf23a7900cb draft B |/ B o 0:426bada5c675 draft A A $ hg co tip^ - 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg amend -m B3 1 new orphan changesets The hook is run with in-memory=yes @@ -170,17 +170,17 @@ move:[4] C atop:[5] B3 running precommit hook - working directory is now at aeee7323c054 + working directory is now at 24f38f1ca271 $ hg glog - @ 6:aeee7323c054 draft tip + @ 6:24f38f1ca271 draft tip | C - o 5:908ce5f9d7eb draft + o 5:b43c30321752 draft | B3 - | x 3:bc77848cde3a draft C + | x 3:46f17045c5ee draft C | | C - +---x 2:377a194b9b8a draft B2 + +---x 2:3d6c495db414 draft B2 | | B2 - | x 1:830b6315076c draft B + | x 1:caf23a7900cb draft B |/ B o 0:426bada5c675 draft A A diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-issue5832.t --- a/tests/test-evolve-issue5832.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-issue5832.t Mon Feb 21 18:26:25 2022 +0300 @@ -117,8 +117,7 @@ move:[2] added b atop:[5] added a move:[4] merge commit - ancestor of '7235ef625ea3' split over multiple topological branches. - choose an evolve destination: + changeset 9402371b436e split over multiple topological branches, choose an evolve destination: 1: [62fb70414f99] added c 2: [5841d7cf9893] added d q: quit the prompt @@ -257,8 +256,7 @@ move:[2] added b atop:[6] added a move:[4] merge commit - ancestor of 'cdf2ea1b9312' split over multiple topological branches. - choose an evolve destination: + changeset 9402371b436e split over multiple topological branches, choose an evolve destination: 1: [62fb70414f99] added c 2: [5841d7cf9893] added d q: quit the prompt @@ -402,8 +400,7 @@ > EOF move:[2] added b atop:[6] added a - ancestor of 'b9b387427a53' split over multiple topological branches. - choose an evolve destination: + changeset 9402371b436e split over multiple topological branches, choose an evolve destination: 1: [62fb70414f99] added c 2: [5841d7cf9893] added d q: quit the prompt diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-obshistory.t --- a/tests/test-evolve-obshistory.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-obshistory.t Mon Feb 21 18:26:25 2022 +0300 @@ -151,7 +151,7 @@ 2 new obsolescence markers obsoleted 1 changesets new changesets 7a230b46bf61 (1 drafts) - (run 'hg heads' to see heads, 'hg merge' to merge) + (run 'hg heads' to see heads) working directory parent is obsolete! (471f378eab4c) (use 'hg evolve' to update to its successor: 7a230b46bf61) Check that obslog works with markers pointing to missing local changectx diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-orphan-split.t --- a/tests/test-evolve-orphan-split.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-orphan-split.t Mon Feb 21 18:26:25 2022 +0300 @@ -193,8 +193,7 @@ $ hg evolve --dry-run < 1 > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -206,8 +205,7 @@ $ hg evolve --dry-run < 2 > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -222,8 +220,7 @@ $ hg evolve --all < foo > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -234,8 +231,7 @@ $ hg evolve --all < 4 > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -246,8 +242,7 @@ $ hg evolve --all < -1 > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -258,8 +253,7 @@ $ hg evolve --all < q > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt @@ -271,8 +265,7 @@ $ hg evolve --all < 1 > EOF - ancestor of 'd48a30875f01' split over multiple topological branches. - choose an evolve destination: + changeset f89e4764f2ed split over multiple topological branches, choose an evolve destination: 1: [f2632392aefe] added a b c 2: [7f87764e5b64] added a b c q: quit the prompt diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-phase-divergence.t --- a/tests/test-evolve-phase-divergence.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-phase-divergence.t Mon Feb 21 18:26:25 2022 +0300 @@ -17,11 +17,6 @@ $ hg init public $ cd public $ echo a > a - $ mkcommit() { - > echo "$1" > "$1" - > hg add "$1" - > hg ci -m "add $1" - > } $ hg commit -A -m init adding a $ cd .. diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-progress.t --- a/tests/test-evolve-progress.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-progress.t Mon Feb 21 18:26:25 2022 +0300 @@ -101,6 +101,8 @@ committing changelog updating the branch cache obscache is out of date + invalid branch cache (served): tip differs + invalid branch cache (served.hidden): tip differs resolving manifests branchmerge: False, force: False, partial: False ancestor: df5d742141b0, local: df5d742141b0+, remote: 152c368c622b @@ -122,17 +124,13 @@ resolving manifests branchmerge: True, force: True, partial: False ancestor: 152c368c622b, local: f8d7d38c0a88+, remote: df5d742141b0 + starting 4 threads for background file closing (?) preserving a for resolve of a - starting 4 threads for background file closing (?) - a: versions differ -> m (premerge) + a: versions differ -> m updating: a 1/1 files (100.00%) picked tool ':merge' for a (binary False symlink False changedelete False) merging a my a@f8d7d38c0a88+ other a@df5d742141b0 ancestor a@152c368c622b - a: versions differ -> m (merge) - updating: a 2/2 files (100.00%) - picked tool ':merge' for a (binary False symlink False changedelete False) - my a@f8d7d38c0a88+ other a@df5d742141b0 ancestor a@152c368c622b warning: conflicts while merging a! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see 'hg help evolve.interrupted') @@ -179,6 +177,7 @@ updating the branch cache obscache is out of date invalid branch cache (served): tip differs + invalid branch cache (served.hidden): tip differs resolving manifests branchmerge: False, force: False, partial: False ancestor: c6e6fdb1d046, local: c6e6fdb1d046+, remote: f8d7d38c0a88 diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-public-content-divergent-corner-cases.t --- a/tests/test-evolve-public-content-divergent-corner-cases.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-public-content-divergent-corner-cases.t Mon Feb 21 18:26:25 2022 +0300 @@ -421,7 +421,7 @@ $ hg evolve --continue evolving 4:e568fd1029bb "added c e" - file 'd' was deleted in other but was modified in local. + file 'd' was deleted in other [other] but was modified in local [local]. You can use (c)hanged version, (d)elete, or leave (u)nresolved. What do you want to do? u 1 files updated, 0 files merged, 0 files removed, 1 files unresolved diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-templates.t --- a/tests/test-evolve-templates.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-templates.t Mon Feb 21 18:26:25 2022 +0300 @@ -1080,7 +1080,7 @@ 2 new obsolescence markers obsoleted 1 changesets new changesets 7a230b46bf61 (1 drafts) - (run 'hg heads' to see heads, 'hg merge' to merge) + (run 'hg heads' to see heads) working directory parent is obsolete! (471f378eab4c) (use 'hg evolve' to update to its successor: 7a230b46bf61) $ hg log --hidden -G diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-evolve-wdir.t --- a/tests/test-evolve-wdir.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-evolve-wdir.t Mon Feb 21 18:26:25 2022 +0300 @@ -17,10 +17,12 @@ .. Resolution : update to a not-dead ancestor .. .. Case C: obsolete wdp with multiple successor (divergence rewriting) -.. Resolution : #TODO: not handled yet +.. Resolution : suggest to check out one of the divergent cset and +.. run `hg evolve --content-divergent` .. .. Case D: obsolete wdp with multiple successor (split rewriting) -.. Resolution : #TODO: not handled yet +.. Resolution : if split over a single topological branch, update to +.. tipmost, otherwise ask user to choose one A. Obsolete wdp with single successor ------------------------------------- @@ -101,22 +103,135 @@ (707ee88b2870 has diverged, use 'hg evolve --list --content-divergent' to resolve the issue) $ hg evolve - parent is obsolete with multiple successors: + parent is obsolete with multiple content-divergent successors: [3] u_B [4] c_B [2] +test that given hint works + $ hg up -r 'desc(u_B)' + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg evolve --content-div + merge:[3] u_B + with: [4] c_B + base: [1] c_B + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at 767c654afe84 $ hg glog - * 4:39e54eb7aa3c (draft): c_B [content-divergent] + @ 5:767c654afe84 (draft): u_B | - | * 3:90624b574289 (draft): u_B [content-divergent] - |/ - | @ 1:707ee88b2870 (draft): c_B + o 0:9f0188af4c58 (draft): c_A + + +D. Obsolete wdp with multiple successors (split rewriting) +---------------------------------------------------------- + +when split csets are on a single topological branch + $ hg up -r 'desc(c_A)' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo X > X; echo Y > Y; echo Z > Z; + $ hg ci -Am 'c_XYZ' + adding X + adding Y + adding Z + created new head + $ hg split -r "desc(c_XYZ)" -d "0 0" --config ui.interactive=True << EOF + > f + > d + > y + > f + > d + > c + > EOF + 0 files updated, 0 files merged, 3 files removed, 0 files unresolved + adding X + adding Y + adding Z + diff --git a/X b/X + new file mode 100644 + examine changes to 'X'? + (enter ? for help) [Ynesfdaq?] f + + diff --git a/Y b/Y + new file mode 100644 + examine changes to 'Y'? + (enter ? for help) [Ynesfdaq?] d + + created new head + continue splitting? [Ycdq?] y + diff --git a/Y b/Y + new file mode 100644 + examine changes to 'Y'? + (enter ? for help) [Ynesfdaq?] f + + diff --git a/Z b/Z + new file mode 100644 + examine changes to 'Z'? + (enter ? for help) [Ynesfdaq?] d + + continue splitting? [Ycdq?] c + + $ hg up -r 'min(desc(c_XYZ))' --hidden + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + updated to hidden changeset c8b6cf6ce628 + (hidden revision 'c8b6cf6ce628' was split as: 1eb7dbbcecbd, b99a391251cc and 1 more) + working directory parent is obsolete! (c8b6cf6ce628) + (use 'hg evolve' to update to its tipmost successor: 1eb7dbbcecbd, b99a391251cc and 1 more) + + $ hg glog -l 3 + o 9:b7ec9e61ccbf (draft): c_XYZ + | + o 8:b99a391251cc (draft): c_XYZ + | + o 7:1eb7dbbcecbd (draft): c_XYZ + | + ~ +test that given hint works + $ hg evolve + update:[9] c_XYZ + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at b7ec9e61ccbf + +when split csets are on multiple topological branches + $ hg rebase -r 'max(desc(c_XYZ))' -d 'desc(u_B)' + rebasing 9:b7ec9e61ccbf tip "c_XYZ" + $ hg glog + @ 10:cadaa9246c55 (draft): c_XYZ + | + | o 8:b99a391251cc (draft): c_XYZ + | | + | o 7:1eb7dbbcecbd (draft): c_XYZ + | | + o | 5:767c654afe84 (draft): u_B |/ o 0:9f0188af4c58 (draft): c_A + $ hg up -r 'min(desc(c_XYZ))' --hidden + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + updated to hidden changeset c8b6cf6ce628 + (hidden revision 'c8b6cf6ce628' was split as: 1eb7dbbcecbd, b99a391251cc and 1 more) + working directory parent is obsolete! (c8b6cf6ce628) + (use 'hg evolve' to update to its tipmost successor: 1eb7dbbcecbd, b99a391251cc and 1 more) -D. Obsolete wdp with multiple successor (split rewriting) ----------------------------------------------------------- + $ hg evolve --config ui.interactive=True << EOF + > q + > EOF + changeset c8b6cf6ce628 split over multiple topological branches, choose an evolve destination: + 1: [b99a391251cc] c_XYZ + 2: [cadaa9246c55] c_XYZ + q: quit the prompt + enter the index of the revision you want to select: q + abort: user quit + [250] -#TODO: yet to write tests for this case + $ hg evolve --config ui.interactive=True << EOF + > 1 + > EOF + changeset c8b6cf6ce628 split over multiple topological branches, choose an evolve destination: + 1: [b99a391251cc] c_XYZ + 2: [cadaa9246c55] c_XYZ + q: quit the prompt + enter the index of the revision you want to select: 1 + update:[8] c_XYZ + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory is now at b99a391251cc diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-fixup.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-fixup.t Mon Feb 21 18:26:25 2022 +0300 @@ -0,0 +1,417 @@ +========================== +Testing `hg fixup` command +========================== + + $ . $TESTDIR/testlib/common.sh + + $ cat >> $HGRCPATH < [extensions] + > rebase = + > evolve = + > [diff] + > git = 1 + > EOF + + $ hg help fixup + hg fixup [OPTION]... [-r] REV + + aliases: fix-up + + add working directory changes to an arbitrary revision + + A new changeset will be created, superseding the one specified. The new + changeset will combine working directory changes with the changes in the + target revision. + + This operation requires the working directory changes to be relocated onto + the target revision, which might result in merge conflicts. + + If fixup is interrupted to manually resolve a conflict, it can be + continued with --continue/-c, or aborted with --abort. + + Note that this command is fairly new and its behavior is still + experimental. For example, the working copy will be left on a temporary, + obsolete commit containing the fixed-up changes after the operation. This + might change in the future. + + Returns 0 on success, 1 if nothing changed. + + options: + + -r --rev REV revision to amend + -c --continue continue an interrupted fixup + --abort abort an interrupted fixup + + (some details hidden, use --verbose to show complete help) + +Simple cases +------------ + + $ hg init simple + $ cd simple + $ mkcommit foo + $ mkcommit bar + $ mkcommit baz + +amending the middle of the stack +-------------------------------- + + $ echo 'hookah bar' > bar + $ hg fixup -r 'desc(bar)' + 1 new orphan changesets + + $ hg diff -c tip + diff --git a/bar b/bar + new file mode 100644 + --- /dev/null + +++ b/bar + @@ -0,0 +1,1 @@ + +hookah bar + + $ hg glog + o 5:2eec5320cfc7 bar + | () draft + | @ 3:fd2f632e47ab temporary fixup commit + | | () draft + | * 2:a425495a8e64 baz + | | () draft orphan + | x 1:c0c7cf58edc5 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + + $ hg glog --hidden + o 5:2eec5320cfc7 bar + | () draft + | x 4:4869c1db2884 temporary fixup commit + | | () draft + | | @ 3:fd2f632e47ab temporary fixup commit + | | | () draft + | | * 2:a425495a8e64 baz + | |/ () draft orphan + | x 1:c0c7cf58edc5 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + + $ hg evolve + update:[5] bar + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory is now at 2eec5320cfc7 + + $ hg evolve + move:[2] baz + atop:[5] bar + + $ hg glog + o 6:eb1755d9f810 baz + | () draft + @ 5:2eec5320cfc7 bar + | () draft + o 0:e63c23eaa88a foo + () draft + +amending working directory parent in secret phase +------------------------------------------------- + + $ hg up -r 'desc(baz)' + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg phase --secret --force -r . + $ echo buzz >> baz + $ hg fix-up -r . + + $ hg evolve + update:[9] baz + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at 12b5e442244f + $ hg glog + @ 9:12b5e442244f baz + | () secret + o 5:2eec5320cfc7 bar + | () draft + o 0:e63c23eaa88a foo + () draft + +testing --abort/--continue +-------------------------- + + $ hg up -r 'desc(foo)' + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo 'update foo' > foo + $ hg ci -m 'update foo' + created new head + $ hg up -r 'desc(baz)' + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ hg glog + o 10:c90c517f86b3 update foo + | () draft + | @ 9:12b5e442244f baz + | | () secret + | o 5:2eec5320cfc7 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + +testing --abort flag + + $ echo 'update foo again' >> foo + + $ hg fixup -r 'desc("update foo")' + merging foo + warning: conflicts while merging foo! (edit, then use 'hg resolve --mark') + unresolved merge conflicts + (see 'hg help evolve.interrupted') + [240] + + $ hg diff + diff --git a/foo b/foo + --- a/foo + +++ b/foo + @@ -1,1 +1,6 @@ + +<<<<<<< destination: c90c517f86b3 - test: update foo + update foo + +======= + +foo + +update foo again + +>>>>>>> evolving: 1c9958e73c2d - test: temporary fixup commit + + $ hg fixup --abort + fixup aborted + working directory is now at 12b5e442244f + + $ hg diff + diff --git a/foo b/foo + --- a/foo + +++ b/foo + @@ -1,1 +1,2 @@ + foo + +update foo again + +testing --continue flag + + $ hg fixup -r 'desc("update foo")' + merging foo + warning: conflicts while merging foo! (edit, then use 'hg resolve --mark') + unresolved merge conflicts + (see 'hg help evolve.interrupted') + [240] + + $ hg status --verbose + M foo + ? foo.orig + # The repository is in an unfinished *fixup* state. + + # Unresolved merge conflicts: + # + # foo + # + # To mark files as resolved: hg resolve --mark FILE + + # To continue: hg fixup --continue + # To abort: hg fixup --abort + + $ echo 'finalize foo' > foo + + $ hg resolve -m + (no more unresolved files) + continue: hg fixup --continue + + $ hg fixup --continue + evolving 11:1c9958e73c2d "temporary fixup commit" + + $ hg diff -c tip + diff --git a/foo b/foo + --- a/foo + +++ b/foo + @@ -1,1 +1,1 @@ + -foo + +finalize foo + + $ hg glog + o 13:fed7e534b3bb update foo + | () draft + | @ 11:1c9958e73c2d temporary fixup commit + | | () secret + | o 9:12b5e442244f baz + | | () secret + | o 5:2eec5320cfc7 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + + $ hg evolve + update:[13] update foo + 1 files updated, 0 files merged, 2 files removed, 0 files unresolved + working directory is now at fed7e534b3bb + +amending a descendant of wdp + + $ hg up 0 + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo foobar > foobar + $ hg add foobar + $ hg fixup -r 'desc(baz)' + $ hg glog + o 16:b50fd0850076 baz + | () secret + | @ 14:4a9c4d14d447 temporary fixup commit + | | () draft + | | o 13:fed7e534b3bb update foo + | |/ () draft + o | 5:2eec5320cfc7 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + + $ hg evolve + update:[16] baz + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at b50fd0850076 + + $ hg glog + @ 16:b50fd0850076 baz + | () secret + | o 13:fed7e534b3bb update foo + | | () draft + o | 5:2eec5320cfc7 bar + |/ () draft + o 0:e63c23eaa88a foo + () draft + $ hg diff -c . + diff --git a/baz b/baz + new file mode 100644 + --- /dev/null + +++ b/baz + @@ -0,0 +1,2 @@ + +baz + +buzz + diff --git a/foobar b/foobar + new file mode 100644 + --- /dev/null + +++ b/foobar + @@ -0,0 +1,1 @@ + +foobar + +no fixup in progress + + $ hg fixup --continue + abort: no interrupted fixup to continue + [255] + + $ hg fixup --abort + abort: no interrupted fixup to abort + [255] + +testing error cases + + $ hg fixup tip --abort + abort: cannot specify a revision with --abort + [255] + + $ hg fixup -r tip --continue + abort: cannot specify a revision with --continue + [255] + + $ hg fixup + abort: please specify a revision to fixup + [255] + + $ hg fixup tip + nothing changed + [1] + + $ hg fixup -r tip + nothing changed + [1] + + $ hg fixup 1 2 3 + hg fixup: invalid arguments + hg fixup [OPTION]... [-r] REV + + add working directory changes to an arbitrary revision + + options: + + -r --rev REV revision to amend + -c --continue continue an interrupted fixup + --abort abort an interrupted fixup + + (use 'hg fixup -h' to show more help) + [10] + + $ hg fixup :10 -r 5 + abort: please specify just one revision + [255] + + $ cd .. + +Multiple branches +----------------- + + $ hg init branches + $ cd branches + + $ cat >> .hg/hgrc << EOF + > [extensions] + > topic = + > [alias] + > glog = log -GT '{rev}:{node|short} {desc}\n ({branch}) [{topic}]\n' + > EOF + + $ mkcommit ROOT + $ hg topic topic-A -q + $ mkcommit A -q + $ hg topic topic-B -q + $ mkcommit B -q + $ hg up 'desc(ROOT)' -q + $ hg branch other-branch -q + $ hg topic topic-C -q + $ mkcommit C -q + $ hg topic topic-D -q + $ mkcommit D -q + $ hg up 'desc(A)' -q + + $ hg glog + o 4:deb0223c611b D + | (other-branch) [topic-D] + o 3:381934d792ab C + | (other-branch) [topic-C] + | o 2:d2dfccd24f25 B + | | (default) [topic-B] + | @ 1:0a2783c5c927 A + |/ (default) [topic-A] + o 0:ea207398892e ROOT + (default) [] + + $ echo Z > Z + $ hg add Z + $ hg fix-up -r 'desc(C)' + switching to topic topic-C + 1 new orphan changesets + + $ hg evolve + update:[7] C + switching to topic topic-C + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory is now at 57d19d0ff7ee + $ hg evolve --any + move:[4] D + atop:[7] C + switching to topic topic-C + +C and D keep their original branch and topics + + $ hg glog + o 8:203e06b553f5 D + | (other-branch) [topic-D] + @ 7:57d19d0ff7ee C + | (other-branch) [topic-C] + | o 2:d2dfccd24f25 B + | | (default) [topic-B] + | o 1:0a2783c5c927 A + |/ (default) [topic-A] + o 0:ea207398892e ROOT + (default) [] + + $ cd .. diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-fold.t --- a/tests/test-fold.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-fold.t Mon Feb 21 18:26:25 2022 +0300 @@ -146,7 +146,7 @@ $ hg fold --from 6 # want to run hg fold 6 abort: hidden revision '6' was rewritten as: 198b5c405d01 (use --hidden to access hidden revisions) - [255] + [10] $ hg log -G @ 11 - 198b5c405d01 r5 [debugbuilddag] (draft) bm1 diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-next-abort.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-next-abort.t Mon Feb 21 18:26:25 2022 +0300 @@ -0,0 +1,61 @@ +Testing hg next with --abort flag and hg abort command handling an interrupted hg next + + $ . "$TESTDIR/testlib/common.sh" + + $ cat >> "$HGRCPATH" << EOF + > [extensions] + > evolve = + > EOF + + $ hg init next-abort + $ cd next-abort + + $ echo apple > a + $ hg ci -qAm apple + $ echo banana > b + $ hg ci -qAm banana + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo blueberry > b + $ hg ci -qAm 'apple and blueberry' --amend + 1 new orphan changesets + + $ hg next + move:[1] banana + atop:[2] apple and blueberry + merging b + warning: conflicts while merging b! (edit, then use 'hg resolve --mark') + unresolved merge conflicts + (see 'hg help evolve.interrupted') + [240] + +#testcases abortcommand abortflag +#if abortflag + $ hg next --abort + next aborted + working directory is now at 1c7f51cf0ef0 + $ hg next --abort + abort: no interrupted next to abort + [255] + $ hg evolve --abort + abort: no interrupted evolve to abort + [255] + + $ hg next --abort --move-bookmark + abort: cannot specify both --abort and --move-bookmark + [10] + $ hg next --abort --merge + abort: cannot specify both --abort and --merge + [10] +#else + $ hg abort --dry-run + evolve in progress, will be aborted + $ hg abort + evolve aborted + working directory is now at 1c7f51cf0ef0 + $ hg abort + abort: no operation in progress + [20] +#endif + + $ cd .. diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-obsolete.t --- a/tests/test-obsolete.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-obsolete.t Mon Feb 21 18:26:25 2022 +0300 @@ -134,6 +134,7 @@ (use 'hg evolve' to update to its successor: 725c380fe99b) $ mkcommit d # 5 (on 3) 1 new orphan changesets + created new head $ qlog -r 'obsolete()' 3 - 0d3f46688ccc diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-pick.t --- a/tests/test-pick.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-pick.t Mon Feb 21 18:26:25 2022 +0300 @@ -269,7 +269,8 @@ pick in progress, will be aborted #endif $ hg abort - aborting pick, updating to c437988de89f + pick aborted + working directory is now at c437988de89f $ hg glog @ 10:c437988de89f foo to b diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-prev-next.t --- a/tests/test-prev-next.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-prev-next.t Mon Feb 21 18:26:25 2022 +0300 @@ -611,49 +611,6 @@ $ cd .. -hg next --abort - - $ hg init next-abort - $ cd next-abort - - $ echo apple > a - $ hg ci -qAm apple - $ echo banana > b - $ hg ci -qAm banana - $ hg up 0 - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ echo blueberry > b - $ hg ci -qAm 'apple and blueberry' --amend - 1 new orphan changesets - - $ hg next - move:[1] banana - atop:[2] apple and blueberry - merging b - warning: conflicts while merging b! (edit, then use 'hg resolve --mark') - unresolved merge conflicts - (see 'hg help evolve.interrupted') - [240] - - $ hg next --abort - next aborted - working directory is now at 1c7f51cf0ef0 - $ hg next --abort - abort: no interrupted next to abort - [255] - $ hg evolve --abort - abort: no interrupted evolve to abort - [255] - - $ hg next --abort --move-bookmark - abort: cannot specify both --abort and --move-bookmark - [10] - $ hg next --abort --merge - abort: cannot specify both --abort and --merge - [10] - - $ cd .. - Testing --merge and --evolve flags: 1 child, 1 aspchild, dirty working copy $ hg init next-dirty-evolve diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-sharing.t --- a/tests/test-sharing.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-sharing.t Mon Feb 21 18:26:25 2022 +0300 @@ -104,8 +104,6 @@ obsoleted 1 changesets new changesets 522d503432a2 (1 drafts) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - updated to "522d503432a2: fix bug 37" - 1 other heads for branch "default" Figure SG03 $ hg -R ../dev-repo shortlog --hidden -G @@ -138,8 +136,6 @@ $ cd ../test-repo $ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - updated to "7b49f864d655: fix bug 37" - 1 other heads for branch "default" $ hg shortlog --hidden -G @ 4:7b49 draft fix bug 37 | diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-named-branch-A1.t --- a/tests/test-single-head-obsolescence-named-branch-A1.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A1.t Mon Feb 21 18:26:25 2022 +0300 @@ -14,13 +14,13 @@ .. old-state: .. -.. * 2 changeset changeset on branch default -.. * 2 changeset changeset on branch Z on top of them. +.. * 2 changesets on branch default +.. * 2 changesets on branch Z on top of them. .. .. new-state: .. -.. * 2 changeset changeset on branch Z at the same location -.. * 2 changeset changeset on branch default superseding the other ones +.. * 2 changesets on branch Z at the same location +.. * 2 changesets on branch default superseding the other ones .. .. expected-result: .. @@ -70,11 +70,11 @@ created new head (consider using topic for lightweight branches. See 'hg help topic') $ mkcommit B1 - $ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"` + $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"` 1 new obsolescence markers obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` 1 new obsolescence markers obsoleted 1 changesets $ hg log -G --hidden diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-named-branch-A2.t --- a/tests/test-single-head-obsolescence-named-branch-A2.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A2.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,4 +1,3 @@ - ========================================= Testing single head enforcement: Case A-2 ========================================= @@ -15,14 +14,14 @@ .. old-state: .. -.. * 2 changeset changeset on branch default -.. * 2 changeset changeset on branch Z on top of them. +.. * 2 changesets on branch default +.. * 2 changesets on branch Z on top of them. .. .. new-state: .. -.. * 2 changeset changeset on branch Z at the same location -.. * 1 changeset changeset on branch default unchanged -.. * 1 changeset changeset on branch default superseding the other ones +.. * 2 changesets on branch Z at the same location +.. * 1 changeset on branch default unchanged +.. * 1 changeset on branch default superseding the other ones .. .. expected-result: .. @@ -71,7 +70,7 @@ $ mkcommit B1 created new head (consider using topic for lightweight branches. See 'hg help topic') - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` 1 new obsolescence markers obsoleted 1 changesets 2 new orphan changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-named-branch-A3.t --- a/tests/test-single-head-obsolescence-named-branch-A3.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A3.t Mon Feb 21 18:26:25 2022 +0300 @@ -10,17 +10,17 @@ This case is part of a series of tests checking this behavior. Category A: Involving obsolescence -TestCase 3: Full supersedig of a branch interleaved with another +TestCase 3: Full superseding of a branch interleaved with another .. old-state: .. -.. * 2 changeset changeset on branch default -.. * 2 changeset changeset on branch Z interleaved with the other +.. * 2 changesets on branch default +.. * 2 changesets on branch Z interleaved with the other .. .. new-state: .. -.. * 2 changeset changeset on branch Z at the same location -.. * 2 changeset changeset on branch default superseding the other ones +.. * 2 changesets on branch Z at the same location +.. * 2 changesets on branch default superseding the other ones .. .. expected-result: .. @@ -78,11 +78,11 @@ created new head (consider using topic for lightweight branches. See 'hg help topic') $ mkcommit C1 - $ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"` + $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"` 1 new obsolescence markers obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` 1 new obsolescence markers obsoleted 1 changesets $ hg log -G --hidden diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-named-branch-A4.t --- a/tests/test-single-head-obsolescence-named-branch-A4.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A4.t Mon Feb 21 18:26:25 2022 +0300 @@ -14,12 +14,12 @@ .. old-state: .. -.. * 2 changeset changeset on branch default -.. * 2 changeset changeset on branch Z interleaved with the other one +.. * 2 changesets on branch default +.. * 2 changesets on branch Z interleaved with the other one .. .. new-state: .. -.. * 2 changeset changeset on branch Z at the same location +.. * 2 changesets on branch Z at the same location .. * 1 changeset on default untouched (the lower one) .. * 1 changeset on default moved on the other one .. @@ -78,7 +78,7 @@ $ mkcommit C1 created new head (consider using topic for lightweight branches. See 'hg help topic') - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` 1 new obsolescence markers obsoleted 1 changesets 1 new orphan changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-named-branch-A5.t --- a/tests/test-single-head-obsolescence-named-branch-A5.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A5.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,5 +1,5 @@ ========================================= -Testing single head enforcement: Case A-1 +Testing single head enforcement: Case A-5 ========================================= A repository is set to only accept a single head per name (typically named @@ -10,16 +10,16 @@ This case is part of a series of tests checking this behavior. Category A: Involving obsolescence -TestCase 1: obsoleting a merge reveal two heads +TestCase 5: Obsoleting a merge reveals two heads .. old-state: .. -.. * 3 changeset changeset on branch default (2 on their own branch + 1 merge) +.. * 3 changesets on branch default (2 on their own branch + 1 merge) .. * 1 changeset on branch Z (children of the merge) .. .. new-state: .. -.. * 2 changeset changeset on branch default (merge is obsolete) each a head +.. * 2 changesets on branch default (merge is obsolete) each a head .. * 1 changeset on branch Z keeping the merge visible .. .. expected-result: @@ -28,8 +28,6 @@ .. .. graph-summary: .. -.. D ● (branch Z) -.. | .. C ● (branch Z) .. | .. M ⊗ diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-topic-B1.t --- a/tests/test-single-head-obsolescence-topic-B1.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-topic-B1.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,5 +1,5 @@ ========================================= -Testing single head enforcement: Case A-1 +Testing single head enforcement: Case B-1 ========================================= A repository is set to only accept a single head per name (typically named @@ -9,18 +9,18 @@ This case is part of a series of tests checking this behavior. -Category B: Involving obsolescence and topic +Category B: Involving obsolescence with topic TestCase 1: A fully obsolete topic kept visible by another one. .. old-state: .. -.. * 2 changeset changeset on topic X -.. * 2 changeset changeset on topic Y on top of them. +.. * 2 changesets on topic X +.. * 2 changesets on topic Y on top of them. .. .. new-state: .. -.. * 2 changeset changeset on topic Y at the same location -.. * 2 changeset changeset on topic X superseding the other ones +.. * 2 changesets on topic Y at the same location +.. * 2 changesets on topic X superseding the other ones .. .. expected-result: .. @@ -76,11 +76,11 @@ marked working directory as topic: topic-X $ mkcommit A1 $ mkcommit B1 - $ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"` + $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"` 1 new obsolescence markers obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` 1 new obsolescence markers obsoleted 1 changesets $ hg log -G --hidden diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-topic-B2.t --- a/tests/test-single-head-obsolescence-topic-B2.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-topic-B2.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,6 +1,5 @@ - ========================================= -Testing single head enforcement: Case A-2 +Testing single head enforcement: Case B-2 ========================================= A repository is set to only accept a single head per name (typically named @@ -15,14 +14,14 @@ .. old-state: .. -.. * 2 changeset changeset on topic X -.. * 2 changeset changeset on topic Y on top of them. +.. * 2 changesets on topic X +.. * 2 changesets on topic Y on top of them. .. .. new-state: .. -.. * 2 changeset changeset on topic Y at the same location -.. * 1 changeset changeset on topic X unchanged -.. * 1 changeset changeset on topic X superseding the other ones +.. * 2 changesets on topic Y at the same location +.. * 1 changeset on topic X unchanged +.. * 1 changeset on topic X superseding the other ones .. .. expected-result: .. @@ -79,7 +78,7 @@ $ hg topic topic-X marked working directory as topic: topic-X $ mkcommit B1 - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` 1 new obsolescence markers obsoleted 1 changesets 2 new orphan changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-topic-B3.t --- a/tests/test-single-head-obsolescence-topic-B3.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-topic-B3.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,5 +1,5 @@ ========================================= -Testing single head enforcement: Case A-3 +Testing single head enforcement: Case B-3 ========================================= A repository is set to only accept a single head per name (typically named @@ -10,17 +10,17 @@ This case is part of a series of tests checking this behavior. Category B: Involving obsolescence with topic -TestCase 3: Full supersedig of a branch interleaved with another +TestCase 3: Full superseding of a branch interleaved with another .. old-state: .. -.. * 2 changeset changeset on topic Y -.. * 2 changeset changeset on topic X interleaved with the other +.. * 2 changesets on topic Y +.. * 2 changesets on topic X interleaved with the other .. .. new-state: .. -.. * 2 changeset changeset on topic X at the same location -.. * 2 changeset changeset on topic Y superseding the other ones +.. * 2 changesets on topic X at the same location +.. * 2 changesets on topic Y superseding the other ones .. .. expected-result: .. @@ -78,11 +78,11 @@ marked working directory as topic: topic-X $ mkcommit A1 $ mkcommit C1 - $ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"` + $ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"` 1 new obsolescence markers obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` 1 new obsolescence markers obsoleted 1 changesets $ hg log -G --hidden diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-topic-B4.t --- a/tests/test-single-head-obsolescence-topic-B4.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-topic-B4.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,5 +1,5 @@ ========================================= -Testing single head enforcement: Case A-4 +Testing single head enforcement: Case B-4 ========================================= A repository is set to only accept a single head per name (typically named @@ -9,17 +9,17 @@ This case is part of a series of tests checking this behavior. -Category A: Involving obsolescence +Category B: Involving obsolescence with topic TestCase 4: Partial rewrite of a branch to dis-interleave it .. old-state: .. -.. * 2 changeset changeset on topic X -.. * 2 changeset changeset on topic Y interleaved with the other one +.. * 2 changesets on topic X +.. * 2 changesets on topic Y interleaved with the other one .. .. new-state: .. -.. * 2 changeset changeset on topic Y at the same location +.. * 2 changesets on topic Y at the same location .. * 1 changeset on topic X untouched (the lower one) .. * 1 changeset on topic X moved on the other one .. @@ -78,7 +78,7 @@ 0 files updated, 0 files merged, 3 files removed, 0 files unresolved $ hg topic topic-X $ mkcommit C1 - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` 1 new obsolescence markers obsoleted 1 changesets 1 new orphan changesets diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-single-head-obsolescence-topic-B5.t --- a/tests/test-single-head-obsolescence-topic-B5.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-single-head-obsolescence-topic-B5.t Mon Feb 21 18:26:25 2022 +0300 @@ -1,5 +1,5 @@ ========================================= -Testing single head enforcement: Case A-1 +Testing single head enforcement: Case B-5 ========================================= A repository is set to only accept a single head per name (typically named @@ -9,17 +9,17 @@ This case is part of a series of tests checking this behavior. -Category A: Involving obsolescence -TestCase 1: obsoleting a merge reveal two heads +Category B: Involving obsolescence with topic +TestCase 5: Obsoleting a merge reveals two heads .. old-state: .. -.. * 3 changeset changeset on topic X (2 on their own branch + 1 merge) -.. * 1 changeset on topic Y (children of the merge) +.. * 3 changesets on topic X (2 on their own branch + 1 merge) +.. * 1 changeset on topic Y (child of the merge) .. .. new-state: .. -.. * 2 changeset changeset on topic X (merge is obsolete) each a head +.. * 2 changesets on topic X (merge is obsolete) each a head .. * 1 changeset on topic Y keeping the merge visible .. .. expected-result: @@ -28,8 +28,6 @@ .. .. graph-summary: .. -.. D ● (topic-Y) -.. | .. C ● (topic-Y) .. | .. M ⊗ (topic-X) diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-topic-push.t --- a/tests/test-topic-push.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-topic-push.t Mon Feb 21 18:26:25 2022 +0300 @@ -211,10 +211,10 @@ $ hg outgoing draft --topic nonexistent abort: topic 'nonexistent' does not exist - [255] + [10] $ hg push draft --topic nonexistent abort: topic 'nonexistent' does not exist - [255] + [10] $ hg up babar switching to topic babar diff -r 30ca8eb17b21 -r 74665d83fb3b tests/test-topic.t --- a/tests/test-topic.t Mon Feb 21 18:18:10 2022 +0300 +++ b/tests/test-topic.t Mon Feb 21 18:26:25 2022 +0300 @@ -645,7 +645,7 @@ $ hg pull ../pinky -r narf pulling from ../pinky abort: unknown revision 'narf' - [255] + [10] $ hg pull ../pinky -r default pulling from ../pinky searching for changes diff -r 30ca8eb17b21 -r 74665d83fb3b tests/testlib/update-hg-repo.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/testlib/update-hg-repo.sh Mon Feb 21 18:26:25 2022 +0300 @@ -0,0 +1,12 @@ +#!/bin/sh +# Clone or update core Mercurial repo at the provided path. Useful for CI +# runners that don't have a shared repo setup, e.g. the shell runner that is +# currently used for Windows CI. + +URL=https://mirror.octobus.net/hg +if hg root -R "$1"; then + hg pull -R "$1" "$URL" +else + rm -rf "$1" + hg clone "$URL" "$1" +fi