# HG changeset patch # User Anton Shestakov # Date 1645564179 -10800 # Node ID 16f59121f8f61427f65077ad479d4effa58f6fa5 # Parent 8d04f00c2fbf4fb33862469bca61b2c965faafd3# Parent 4c0d0be7cf9550cbb5019251f641dfe872655dc1 test-compat: merge mercurial-4.9 into mercurial-4.8 diff -r 8d04f00c2fbf -r 16f59121f8f6 .gitlab-ci.yml --- a/.gitlab-ci.yml Fri Nov 19 09:59:57 2021 +0300 +++ b/.gitlab-ci.yml Wed Feb 23 00:09:39 2022 +0300 @@ -1,6 +1,6 @@ .prepare_hg: &prepare_hg - hg pull -R /ci/repos/mercurial/ - - 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" @@ -45,28 +45,3 @@ variables: RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt" TEST_HGMODULEPOLICY: "py" - -doc: - image: registry.heptapod.net/mercurial/ci-images/py3-evolve-doc - script: - - cd docs/ - - make - variables: - LANG: en_US.UTF-8 - PYTHON: python3 - PYTHONPATH: "/ci/repos/mercurial:$PYTHONPATH" - SPHINXBUILD: python3 -m sphinx -b html - artifacts: - paths: - - html/* - -sdist: - stage: .post - image: registry.heptapod.net/mercurial/ci-images/py3-hgext3rd - script: - - python3 setup.py sdist - artifacts: - paths: - - dist/* - only: - - tags diff -r 8d04f00c2fbf -r 16f59121f8f6 .gitlab/issue_templates/new-version.md --- a/.gitlab/issue_templates/new-version.md Fri Nov 19 09:59:57 2021 +0300 +++ b/.gitlab/issue_templates/new-version.md Wed Feb 23 00:09:39 2022 +0300 @@ -1,29 +1,30 @@ This is the actual check list for releasing evolve version X.Y.Z -More details in the [README.rst file](README.rst#L199). +More details in the [README.rst file](README.rst#L210). Preparation * [ ] merges with compatibility branches * [ ] compatibility tests are happy * [ ] update `testedwith` field -* [ ] make sure the changelog is up to data -* [ ] [prepare an announcement for the list/website](https://mypads.framapad.org/mypads/?/mypads/group/octobus-public-5d3rw470w/pad/view/evolution-announce-iswcp7qx) +* [ ] make sure CHANGELOG is up-to-date +* [ ] [prepare an announcement for the list/website](https://mypads.framapad.org/p/evolution-announce-iswcp7qx) * [ ] sanity check install and sdist targets of setup.py Releasing -* [ ] add the current date to the changelog +* [ ] add the current date to CHANGELOG * [ ] update the `__version__` field of all relevant extensions * [ ] create a new Debian entry * [ ] tag the version -* [ ] move the `@` bookmark on the new tag +* [ ] move the `@` bookmark to the new tag * [ ] push/publish the tag to the main repository * [ ] upload the tarball to PyPI * [ ] add `.dev` to the `__version__` field * [ ] merge stable into default -* [ ] push the result on the main repo +* [ ] push the result to https://www.mercurial-scm.org/repo/evolve/ * [ ] 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 8d04f00c2fbf -r 16f59121f8f6 .hgignore --- a/.hgignore Fri Nov 19 09:59:57 2021 +0300 +++ b/.hgignore Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 .hgtags --- a/.hgtags Fri Nov 19 09:59:57 2021 +0300 +++ b/.hgtags Wed Feb 23 00:09:39 2022 +0300 @@ -97,3 +97,4 @@ 30c8d8e6a7f4056c46a868b47ee949d3bdb48c4c 10.3.2 cca465bf6a6a103449aa58deecdffba8e546f7c6 10.3.3 de530d27554b43c00509696dc7a1496f5129e1a4 10.4.0 +64bb9c4a13d388233d4d6d9b761ece9c6ce77fb3 10.4.1 diff -r 8d04f00c2fbf -r 16f59121f8f6 CHANGELOG --- a/CHANGELOG Fri Nov 19 09:59:57 2021 +0300 +++ b/CHANGELOG Wed Feb 23 00:09:39 2022 +0300 @@ -1,6 +1,38 @@ Changelog ========= +10.5.0 - in progress +-------------------- + + * 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 +-------------------- + + * compatibility with Mercurial 6.0 + + * documentation: add a help section about making evolve skip + content-divergence check with experimental.evolution.allowdivergence. + * documentation: mention that pick uses the active topic if it's set + +topic (0.23.1) + + * compatibility with Mercurial 6.0 + 10.4.0 -- 2021-10-12 -------------------- diff -r 8d04f00c2fbf -r 16f59121f8f6 Makefile --- a/Makefile Fri Nov 19 09:59:57 2021 +0300 +++ b/Makefile Wed Feb 23 00:09:39 2022 +0300 @@ -1,5 +1,5 @@ PYTHON ?= python3 -VERSION = $(shell python setup.py --version) +VERSION = $(shell $(PYTHON) setup.py --version) TESTFLAGS ?= $(shell echo $$HGTESTFLAGS) HGTESTS = $(HGROOT)/tests @@ -15,7 +15,7 @@ .PHONY: deb-prepare deb-prepare: - python setup.py sdist --dist-dir .. + $(PYTHON) setup.py sdist --dist-dir .. mv -f ../hg-evolve-$(VERSION).tar.gz ../mercurial-evolve_$(VERSION).orig.tar.gz tar xf ../mercurial-evolve_$(VERSION).orig.tar.gz rm -rf ../mercurial-evolve_$(VERSION).orig diff -r 8d04f00c2fbf -r 16f59121f8f6 README.rst --- a/README.rst Fri Nov 19 09:59:57 2021 +0300 +++ b/README.rst Wed Feb 23 00:09:39 2022 +0300 @@ -76,6 +76,17 @@ [extensions] evolve = ~/evolve/hgext3rd/evolve +Pitfalls +-------- + +If you get ``"failed to import extension evolve: No module named 'evolve'"`` +error, there are a couple of things to check: + +* make sure you gave pip the correct package name (it's hg-evolve), + +* make sure evolve is installed for the same version of Python that you use for + running Mercurial (``hg debuginstall | grep Python``). + Server-only Setup ================= @@ -117,7 +128,7 @@ How to Contribute ================= -Discussion happens on the #hg-evolve IRC on libera_. +Discussion happens in #hg-evolve and #mercurial on libera_ IRC network. .. _libera: https://libera.chat/ @@ -199,31 +210,31 @@ Release Checklist ================= +* use contrib/merge-test-compat.sh to merge with the test compatibility + branches, + * make sure the tests are happy on all supported versions, - You can use the `contrib/merge-test-compat.sh` to merge with the test - compatibility branches. +* make sure there is no code difference between the compatibility branches and + stable (no diff within hgext3rd/), -* make sure there is no code difference between the compat branches and stable - (no diff within `hgext3rd/`), - -* update the `testedwith` variable for all extensions (remove '.dev'): +* update the ``testedwith`` variable for all extensions (remove '.dev'): - hgext3rd/evolve/metadata.py - hgext3rd/topic/__init__.py - hgext3rd/pullbundle.py -* make sure the changelog is up to date, +* make sure CHANGELOG is up-to-date, -* add a date to the changelog entry for the target version, +* add a date to the CHANGELOG entry for the target version, -* update the `__version__` field of all relevant extensions: +* update the ``__version__`` field of all relevant extensions: - hgext3rd/evolve/metadata.py - hgext3rd/topic/__init__.py - hgext3rd/pullbundle.py (if touched) -* create a new Debian entry: +* create a new Debian changelog entry: - debchange --newversion x.y.z-1 "new upstream release" - debchange --release @@ -235,21 +246,25 @@ * tag the commit, +* move ``@`` bookmark to the new tag, + * push and publish the tag, * upload the tarball to PyPI, -* make an announcement on evolve-testers@mercurial-scm.org (possibly on - mercurial@mercurial-scm.org too), +* make an announcement on evolve-testers@mercurial-scm.org and + mercurial@mercurial-scm.org, -* bump versions of all extensions and add '.dev' (see existing commits as an +* bump versions of all extensions and add ``.dev`` (see existing commits as an example): - hgext3rd/evolve/metadata.py - hgext3rd/topic/__init__.py - hgext3rd/pullbundle.py - The version we use on the stable branch during development should be - `x.y.z+1.dev`. The version of the default branch should be `x.y+1.0.dev`. + Version bump rules: + + - stable branch x.y.z+1.dev + - default branch x.y+1.0.dev * merge stable into default. diff -r 8d04f00c2fbf -r 16f59121f8f6 debian/changelog --- a/debian/changelog Fri Nov 19 09:59:57 2021 +0300 +++ b/debian/changelog Wed Feb 23 00:09:39 2022 +0300 @@ -1,3 +1,9 @@ +mercurial-evolve (10.4.1-1) unstable; urgency=medium + + * new upstream release + + -- Anton Shestakov Fri, 19 Nov 2021 16:17:59 +0300 + mercurial-evolve (10.4.0-1) unstable; urgency=medium * new upstream release diff -r 8d04f00c2fbf -r 16f59121f8f6 debian/control --- a/debian/control Fri Nov 19 09:59:57 2021 +0300 +++ b/debian/control Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 debian/rules --- a/debian/rules Fri Nov 19 09:59:57 2021 +0300 +++ b/debian/rules Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/__init__.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/cmdrewrite.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/evolvecmd.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/headchecking.py --- a/hgext3rd/evolve/headchecking.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/headchecking.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/metadata.py Wed Feb 23 00:09:39 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.1.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' +__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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/obscache.py --- a/hgext3rd/evolve/obscache.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/obscache.py Wed Feb 23 00:09:39 2022 +0300 @@ -432,9 +432,8 @@ def _computeobsoleteset(orig, repo): """the set of obsolete revisions""" - obs = set() 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 @@ -461,10 +460,7 @@ # disk when the transaction close. obscache.update(repo) isobs = obscache.get - for r in notpublic: - if isobs(r): - obs.add(r) - return obs + return frozenset(r for r in notpublic if isobs(r)) @eh.uisetup def cachefuncs(ui): diff -r 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/rewriteutil.py --- a/hgext3rd/evolve/rewriteutil.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/rewriteutil.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/evolve/utility.py --- a/hgext3rd/evolve/utility.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/evolve/utility.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/pullbundle.py --- a/hgext3rd/pullbundle.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/pullbundle.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/serverminitopic.py --- a/hgext3rd/serverminitopic.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/serverminitopic.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/topic/__init__.py Wed Feb 23 00:09:39 2022 +0300 @@ -231,10 +231,10 @@ b'log.topic': b'green_background', } -__version__ = b'0.23.1.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' -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'): @@ -440,6 +440,15 @@ except (KeyError, AttributeError): pass + try: + histedit = extensions.find(b'histedit') + except KeyError: + pass + else: + # Make histedit preserve topics of edited commits + extensions.wrapfunction(histedit.histeditaction, 'applychange', + applychangewrap) + server.setupserver(ui) def reposetup(ui, repo): @@ -732,6 +741,17 @@ return orig(cl, manifest, files, desc, transaction, p1, p2, user, date=date, extra=extra, **kwargs) +def applychangewrap(orig, self): + orig(self) + repo = self.repo + rulectx = repo[self.node] + + topic = None + if util.safehasattr(rulectx, 'topic'): + topic = rulectx.topic() + _changecurrenttopic(repo, topic) + + # revset predicates are automatically registered at loading via this symbol revsetpredicate = topicrevset.revsetpredicate diff -r 8d04f00c2fbf -r 16f59121f8f6 hgext3rd/topic/discovery.py --- a/hgext3rd/topic/discovery.py Fri Nov 19 09:59:57 2021 +0300 +++ b/hgext3rd/topic/discovery.py Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 tests/test-check-sdist.t --- a/tests/test-check-sdist.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-check-sdist.t Wed Feb 23 00:09:39 2022 +0300 @@ -35,7 +35,7 @@ $ tar -tzf hg-evolve-*.tar.gz | sed 's|^hg-evolve-[^/]*/||' | sort > files $ wc -l files - 351 files + 355 files $ fgrep debian files tests/test-check-debian.t $ fgrep __init__.py files diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-content-divergent-user-independent-resolution.t diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-issue5832.t --- a/tests/test-evolve-issue5832.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-evolve-issue5832.t Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-obshistory.t diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-orphan-split.t --- a/tests/test-evolve-orphan-split.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-evolve-orphan-split.t Wed Feb 23 00:09:39 2022 +0300 @@ -184,8 +184,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 @@ -197,8 +196,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 @@ -213,8 +211,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 @@ -225,8 +222,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 @@ -237,8 +233,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 @@ -249,8 +244,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 @@ -262,8 +256,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 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-phase-divergence.t --- a/tests/test-evolve-phase-divergence.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-evolve-phase-divergence.t Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-progress.t --- a/tests/test-evolve-progress.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-evolve-progress.t Wed Feb 23 00:09:39 2022 +0300 @@ -122,8 +122,8 @@ 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) updating: a 1/1 files (100.00%) picked tool ':merge' for a (binary False symlink False changedelete False) diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-evolve-wdir.t --- a/tests/test-evolve-wdir.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-evolve-wdir.t Wed Feb 23 00:09:39 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,131 @@ (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'? [Ynesfdaq?] f + + diff --git a/Y b/Y + new file mode 100644 + examine changes to 'Y'? [Ynesfdaq?] d + + created new head + continue splitting? [Ycdq?] y + diff --git a/Y b/Y + new file mode 100644 + examine changes to 'Y'? [Ynesfdaq?] f + + diff --git a/Z b/Z + new file mode 100644 + examine changes to 'Z'? [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 "c_XYZ" (tip) + $ 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 + [255] -#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 8d04f00c2fbf -r 16f59121f8f6 tests/test-fixup.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-fixup.t Wed Feb 23 00:09:39 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') + [1] + + $ 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') + [1] + + $ 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) + [255] + + $ 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 8d04f00c2fbf -r 16f59121f8f6 tests/test-issue6550.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-issue6550.t Wed Feb 23 00:09:39 2022 +0300 @@ -0,0 +1,124 @@ +histedit should preserve topics (issue6550) +https://bz.mercurial-scm.org/show_bug.cgi?id=6550 + + $ . "$TESTDIR/testlib/topic_setup.sh" + + $ cat << EOF >> "$HGRCPATH" + > [extensions] + > histedit = + > [alias] + > glog = log -G --template "{rev}:{node|short} [{topic}] {desc}\n" + > EOF + +Editing commits with one topic on top of a commit with a different topic: + + $ hg init repo1 + $ cd repo1 + $ hg topic topic1 + marked working directory as topic: topic1 + $ echo 1 > A + $ hg ci -Aqm A + $ hg topic topic2 + $ echo 1 > B + $ hg ci -Aqm B + $ echo 1 > C + $ hg ci -Aqm C + $ hg glog + @ 2:392a64d00726 [topic2] C + | + o 1:8a25a1549e46 [topic2] B + | + o 0:c051488dac25 [topic1] A + +Swap the order of commits B and C + + $ hg histedit s1 -q --commands - 2>&1 << EOF + > pick 392a64d00726 C + > pick 8a25a1549e46 B + > EOF + +Topic of B and C is preserved + + $ hg glog + @ 4:065a99df807b [topic2] B + | + o 3:43dddca3e1d1 [topic2] C + | + o 0:c051488dac25 [topic1] A + + $ cd .. + +Editing commits without a topic on top of a commit with a topic: + + $ hg init repo2 + $ cd repo2 + $ hg topic topic1 + marked working directory as topic: topic1 + $ echo 1 > A + $ hg ci -Aqm A + $ hg topic --clear + $ echo 1 > B + $ hg ci -Aqm B + $ echo 1 > C + $ hg ci -Aqm C + $ hg glog + @ 2:c47acbb860b3 [] C + | + o 1:e2e2ca96a6bb [] B + | + o 0:c051488dac25 [topic1] A + +Swap the order of commits B and C + + $ hg histedit s1 -q --commands - 2>&1 << EOF + > pick c47acbb860b3 C + > pick e2e2ca96a6bb B + > EOF + +B and C still don't have a topic + + $ hg glog + @ 4:ff3439fe6f3d [] B + | + o 3:bb6fab1a29c6 [] C + | + o 0:c051488dac25 [topic1] A + + $ cd .. + +Editing commits with a topic on top of a commit without a topic: + + $ hg init repo3 + $ cd repo3 + $ echo 1 > A + $ hg ci -Aqm A + $ hg topic topic1 + marked working directory as topic: topic1 + $ echo 1 > B + $ hg ci -Aqm B + $ echo 1 > C + $ hg ci -Aqm C + $ hg glog + @ 2:c3dae6eda73b [topic1] C + | + o 1:db3a7c9052ac [topic1] B + | + o 0:a18fe624bf77 [] A + +Swap the order of commits B and C + + $ hg histedit s1 -q --commands - 2>&1 << EOF + > pick c3dae6eda73b C + > pick db3a7c9052ac B + > EOF + +Topic of B and C is preserved + + $ hg glog + @ 4:aa7af5cc1567 [topic1] B + | + o 3:4bf8cf7b2c73 [topic1] C + | + o 0:a18fe624bf77 [] A + + $ cd .. diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-next-abort.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-next-abort.t Wed Feb 23 00:09:39 2022 +0300 @@ -0,0 +1,49 @@ +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') + [1] + + $ 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 + [255] + $ hg next --abort --merge + abort: cannot specify both --abort and --merge + [255] + + $ cd .. diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-pick.t --- a/tests/test-pick.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-pick.t Wed Feb 23 00:09:39 2022 +0300 @@ -260,7 +260,8 @@ [1] $ hg abort - aborting pick, updating to c437988de89f + pick aborted + working directory is now at c437988de89f $ hg glog @ 10:c437988de89f foo to b diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-named-branch-A1.t --- a/tests/test-single-head-obsolescence-named-branch-A1.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A1.t Wed Feb 23 00:09:39 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,10 +70,10 @@ 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)"` obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` obsoleted 1 changesets $ hg log -G --hidden @ 262c8c798096 [default] (draft): B1 diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-named-branch-A2.t --- a/tests/test-single-head-obsolescence-named-branch-A2.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A2.t Wed Feb 23 00:09:39 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)"` obsoleted 1 changesets 2 new orphan changesets $ hg log -G --hidden diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-named-branch-A3.t --- a/tests/test-single-head-obsolescence-named-branch-A3.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A3.t Wed Feb 23 00:09:39 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,10 +78,10 @@ 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)"` obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` obsoleted 1 changesets $ hg log -G --hidden @ 0c76bc104656 [default] (draft): C1 diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-named-branch-A4.t --- a/tests/test-single-head-obsolescence-named-branch-A4.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A4.t Wed Feb 23 00:09:39 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)"` obsoleted 1 changesets 1 new orphan changesets $ hg log -G --hidden diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-named-branch-A5.t --- a/tests/test-single-head-obsolescence-named-branch-A5.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-named-branch-A5.t Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-topic-B1.t --- a/tests/test-single-head-obsolescence-topic-B1.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-topic-B1.t Wed Feb 23 00:09:39 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,10 +76,10 @@ 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)"` obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"` + $ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"` obsoleted 1 changesets $ hg log -G --hidden @ f4ed6717fb66 [default:topic-X] (draft): B1 diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-topic-B2.t --- a/tests/test-single-head-obsolescence-topic-B2.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-topic-B2.t Wed Feb 23 00:09:39 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)"` obsoleted 1 changesets 2 new orphan changesets $ hg log -G --hidden diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-topic-B3.t --- a/tests/test-single-head-obsolescence-topic-B3.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-topic-B3.t Wed Feb 23 00:09:39 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,10 +78,10 @@ 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)"` obsoleted 1 changesets 3 new orphan changesets - $ hg debugobsolete `getid "desc(C0)" ` `getid "desc(C1)"` + $ hg debugobsolete `getid "desc(C0)"` `getid "desc(C1)"` obsoleted 1 changesets $ hg log -G --hidden @ 9f6e6381b9aa [default:topic-X] (draft): C1 diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-topic-B4.t --- a/tests/test-single-head-obsolescence-topic-B4.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-topic-B4.t Wed Feb 23 00:09:39 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)"` obsoleted 1 changesets 1 new orphan changesets $ hg log -G --hidden diff -r 8d04f00c2fbf -r 16f59121f8f6 tests/test-single-head-obsolescence-topic-B5.t --- a/tests/test-single-head-obsolescence-topic-B5.t Fri Nov 19 09:59:57 2021 +0300 +++ b/tests/test-single-head-obsolescence-topic-B5.t Wed Feb 23 00:09:39 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 8d04f00c2fbf -r 16f59121f8f6 tests/testlib/update-hg-repo.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/testlib/update-hg-repo.sh Wed Feb 23 00:09:39 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