--- a/.gitlab-ci.yml Sun Feb 02 13:25:23 2020 +0100
+++ b/.gitlab-ci.yml Sun Feb 02 13:28:47 2020 +0100
@@ -3,6 +3,16 @@
script:
- hg files -0 'set:(**.py or grep("^#!.*python")) - removed()' -X hgext3rd/evolve/thirdparty | xargs -0 flake8
+pytype:
+ image: octobus/ci-py3-hgext3rd
+ script:
+ - hg pull -R /ci/repos/mercurial/
+ - hg_rev=$(tests/testlib/map-hg-rev.sh "$(hg log -r . -T '{branch}')")
+ - hg -R /ci/repos/mercurial/ update "$hg_rev"
+ - jobs=$(python -c 'import multiprocessing; print multiprocessing.cpu_count()')
+ - pytype -P /ci/repos/mercurial/:hgext3rd -k hgext3rd -x hgext3rd/evolve/thirdparty -j $jobs || true
+ when: manual
+
tests-py2-cext:
image: octobus/ci-py2-hgext3rd
script:
@@ -34,3 +44,14 @@
- hg_rev=$(tests/testlib/map-hg-rev.sh "$(hg log -r . -T '{branch}')")
- hg -R /ci/repos/mercurial/ update "$hg_rev"
- (cd tests; python3 /ci/repos/mercurial/tests/run-tests.py --color=always --pure)
+
+doc:
+ image: octobus/ci-py2-evolve-doc
+ script:
+ - cd docs/
+ - make
+ variables:
+ LANG: en_us.UTF-8
+ artifacts:
+ paths:
+ - html/*
--- a/CHANGELOG Sun Feb 02 13:25:23 2020 +0100
+++ b/CHANGELOG Sun Feb 02 13:28:47 2020 +0100
@@ -1,6 +1,19 @@
Changelog
=========
+9.3.0 - in progress
+-------------------
+
+ * evolve: extensive cleanup of functions, template keywords and compatibility
+ code related to obsfate and successorssets
+ * exchange: dropped more bundle-1 related dead code
+ * help: categorizing evolve and topic commands
+ * obslog: make templatable
+ * compat: cleanup some compatibility code for mercurial < 4.5
+ * compat: compatibility with some changes of the upcoming Mercurial 5.3
+ * evolve: add content divergence checking to the standard pre-rewrite check,
+ * evolve: improve the message associated with content divergence.
+
9.2.2 -- 2020-01-31
-------------------
--- a/hgext3rd/evolve/__init__.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/__init__.py Sun Feb 02 13:28:47 2020 +0100
@@ -251,7 +251,6 @@
""".strip()
import sys
-import struct
try:
from mercurial import registrar
@@ -326,9 +325,6 @@
b'evolve.operation': b'bold'
}
-_pack = struct.pack
-_unpack = struct.unpack
-
aliases, entry = cmdutil.findcmd(b'commit', commands.table)
# This extension contains the following code
@@ -465,7 +461,8 @@
_alias, statuscmd = cmdutil.findcmd(b'status', commands.table)
pstatusopts = [o for o in statuscmd[1] if o[1] != b'rev']
- @eh.command(b'pstatus', pstatusopts)
+ @eh.command(b'pstatus', pstatusopts,
+ **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
def pstatus(ui, repo, *args, **kwargs):
"""show status combining committed and uncommited changes
@@ -480,7 +477,8 @@
_alias, diffcmd = cmdutil.findcmd(b'diff', commands.table)
pdiffopts = [o for o in diffcmd[1] if o[1] != b'rev']
- @eh.command(b'pdiff', pdiffopts)
+ @eh.command(b'pdiff', pdiffopts,
+ **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
def pdiff(ui, repo, *args, **kwargs):
"""show diff combining committed and uncommited changes
@@ -705,10 +703,10 @@
debugcommand = b"hg evolve --list --content-divergent"
basemsg = _(b"%s has diverged, use '%s' to resolve the issue")
solvemsg = basemsg % (shortnode, debugcommand)
- elif reason == b'superseed':
+ elif reason == b'superseded':
msg = _(b"use 'hg evolve' to update to its successor: %s")
solvemsg = msg % successors[0]
- elif reason == b'superseed_split':
+ elif reason == b'superseded_split':
msg = _(b"use 'hg evolve' to update to its tipmost successor: %s")
if len(successors) <= 2:
@@ -736,10 +734,10 @@
rev = repo[scmutil.revsingle(unfilteredrepo, changeid)]
reason, successors = obshistory._getobsfateandsuccs(unfilteredrepo, rev.node())
- # Be more precise in case the revision is superseed
- if reason == b'superseed':
+ # Be more precise in case the revision is superseded
+ if reason == b'superseded':
reason = _(b"successor: %s") % successors[0]
- elif reason == b'superseed_split':
+ elif reason == b'superseded_split':
if len(successors) <= 2:
reason = _(b"successors: %s") % b", ".join(successors)
else:
@@ -947,7 +945,7 @@
def _findprevtarget(repo, displayer, movebookmark=False, topic=True):
target = bookmark = None
wkctx = repo[None]
- p1 = wkctx.parents()[0]
+ p1 = wkctx.p1()
parents = p1.parents()
currenttopic = _getcurrenttopic(repo)
@@ -989,7 +987,8 @@
(b'n', b'dry-run', False,
_(b'do not perform actions, just print what would be done'))],
b'[OPTION]...',
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
def cmdprevious(ui, repo, **opts):
"""update to parent revision
@@ -1023,15 +1022,14 @@
target, bookmark = _findprevtarget(repo, displayer,
opts.get('move_bookmark'), topic)
if target is not None:
- backup = repo.ui.backupconfig(b'_internal', b'keep-topic')
- try:
- if topic and _getcurrenttopic(repo) != _gettopic(target):
- repo.ui.setconfig(b'_internal', b'keep-topic', b'yes',
- source=b'topic-extension')
+ configoverride = util.nullcontextmanager()
+ if topic and _getcurrenttopic(repo) != _gettopic(target):
+ configoverride = repo.ui.configoverride({
+ (b'_internal', b'keep-topic'): b'yes'
+ }, source=b'topic-extension')
+ with configoverride:
_prevupdate(repo, displayer, target, bookmark, dryrunopt,
mergeopt)
- finally:
- repo.ui.restoreconfig(backup)
return 0
else:
return 1
@@ -1048,7 +1046,8 @@
(b'n', b'dry-run', False,
_(b'do not perform actions, just print what would be done'))],
b'[OPTION]...',
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_WORKING_DIRECTORY'))
def cmdnext(ui, repo, **opts):
"""update to next child revision
@@ -1339,8 +1338,16 @@
if entry[0] == b"evolution":
break
else:
- help.helptable.append(([b"evolution"], _(b"Safely Rewriting History"),
- _helploader))
+ if util.safehasattr(help, 'TOPIC_CATEGORY_CONCEPTS'):
+ help.helptable.append(([b"evolution"],
+ _(b"Safely Rewriting History"),
+ _helploader,
+ help.TOPIC_CATEGORY_CONCEPTS))
+ else:
+ # hg <= 4.7 (c303d65d2e34)
+ help.helptable.append(([b"evolution"],
+ _(b"Safely Rewriting History"),
+ _helploader))
help.helptable.sort()
evolvestateversion = 0
--- a/hgext3rd/evolve/cmdrewrite.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/cmdrewrite.py Sun Feb 02 13:28:47 2020 +0100
@@ -26,7 +26,6 @@
merge,
node,
obsolete,
- obsutil,
patch,
phases,
pycompat,
@@ -36,11 +35,6 @@
from mercurial.i18n import _
-try:
- from mercurial.utils.dateutil import datestr
-except ImportError: # hg <= 4.5
- from mercurial.util import datestr
-
from . import (
compat,
state,
@@ -56,6 +50,7 @@
commitopts2 = commands.commitopts2
mergetoolopts = commands.mergetoolopts
stringio = util.stringio
+precheck_contentdiv = rewriteutil.precheck_contentdiv
# option added by evolve
@@ -66,9 +61,6 @@
if not note:
return
- if not compat.isobsnotesupported():
- ui.warn(_(b"current hg version does not support storing"
- b" note in obsmarker\n"))
if len(note) > 255:
raise error.Abort(_(b"cannot store a note of more than 255 bytes"))
if b'\n' in note:
@@ -109,7 +101,8 @@
(b'n', b'note', b'', _(b'store a note on amend'), _(b'TEXT')),
] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
_(b'[OPTION]... [FILE]...'),
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_COMMITTING'))
def amend(ui, repo, *pats, **opts):
"""combine a changeset with updates and replace it with a new one
@@ -274,7 +267,7 @@
fp.write(b"# HG changeset patch\n")
fp.write(b"# User %s\n" % ctx.user())
fp.write(b"# Date %d %d\n" % ctx.date())
- fp.write(b"# %s\n" % datestr(ctx.date()))
+ fp.write(b"# %s\n" % compat.datestr(ctx.date()))
if branch and branch != b'default':
fp.write(b"# Branch %s\n" % branch)
fp.write(b"# Node ID %s\n" % node.hex(nodeval))
@@ -458,7 +451,8 @@
(b'', b'revert', False, _(b'discard working directory changes after uncommit')),
(b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')),
] + commands.walkopts + commitopts + commitopts2 + commitopts3,
- _(b'[OPTION]... [FILE]...'))
+ _(b'[OPTION]... [FILE]...'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def uncommit(ui, repo, *pats, **opts):
"""move changes from parent revision to working directory
@@ -694,7 +688,8 @@
(b'n', b'note', b'', _(b'store a note on fold'), _(b'TEXT')),
] + commitopts + commitopts2 + commitopts3,
_(b'hg fold [OPTION]... [-r] REV...'),
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def fold(ui, repo, *revs, **opts):
"""fold multiple revisions into a single one
@@ -806,9 +801,15 @@
p2.node()],
commitopts=commitopts)
phases.retractboundary(repo, tr, targetphase, [newid])
- replacements = {ctx.node(): [newid] for ctx in allctx}
- scmutil.cleanupnodes(repo, replacements, operation=b"fold",
- metadata=metadata)
+ if 'repls' in scmutil.cleanupnodes.__code__.co_varnames:
+ replacements = {tuple(ctx.node() for ctx in allctx): [newid]}
+ scmutil.cleanupnodes(repo, replacements, operation=b"fold",
+ metadata=metadata)
+ else:
+ # hg <= 4.7 (b99903534e06)
+ replacements = {ctx.node(): [newid] for ctx in allctx}
+ scmutil.cleanupnodes(repo, replacements, operation=b"fold",
+ metadata=metadata)
tr.close()
finally:
tr.release()
@@ -824,7 +825,8 @@
(b'', b'fold', None, _(b"also fold specified revisions into one")),
(b'n', b'note', b'', _(b'store a note on metaedit'), _(b'TEXT')),
] + commitopts + commitopts2 + commitopts3,
- _(b'hg metaedit [OPTION]... [[-r] REV]...'))
+ _(b'hg metaedit [OPTION]... [[-r] REV]...'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def metaedit(ui, repo, *revs, **opts):
"""edit commit information
@@ -934,9 +936,13 @@
metadata[b'note'] = opts['note']
phases.retractboundary(repo, tr, targetphase, [newid])
- obsolete.createmarkers(repo, [(ctx, (repo[newid],))
- for ctx in allctx],
- metadata=metadata, operation=b"metaedit")
+ if 'predecessors' in obsolete.createmarkers.__code__.co_varnames:
+ obsolete.createmarkers(repo, [(tuple(allctx), (repo[newid],))],
+ metadata=metadata, operation=b"metaedit")
+ else:
+ # hg <= 4.7 (6335c0de80fa)
+ obsolete.createmarkers(repo, [(ctx, (repo[newid],)) for ctx in allctx],
+ metadata=metadata, operation=b"metaedit")
else:
ui.status(_(b"nothing changed\n"))
tr.close()
@@ -982,7 +988,8 @@
(b'B', b'bookmark', [], _(b"remove revs only reachable from given"
b" bookmark"), _(b'BOOKMARK'))] + metadataopts,
_(b'[OPTION]... [-r] REV...'),
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
# XXX -U --noupdate option to prevent wc update and or bookmarks update ?
def cmdprune(ui, repo, *revs, **opts):
"""mark changesets as obsolete or succeeded by another changeset
@@ -1092,7 +1099,7 @@
newnode = wdp
while newnode in precs or newnode.obsolete():
- newnode = newnode.parents()[0]
+ newnode = newnode.p1()
else:
# no need to update anywhere as wdp is not related to revs
# being pruned
@@ -1176,7 +1183,8 @@
(b'n', b'note', b'', _(b"store a note on split"), _(b'TEXT')),
] + commitopts + commitopts2 + commitopts3,
_(b'hg split [OPTION]... [-r REV] [FILE]...'),
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def cmdsplit(ui, repo, *pats, **opts):
"""split a changeset into smaller changesets
@@ -1353,7 +1361,8 @@
b'mark the new revision as successor of the old one potentially creating '
b'divergence')],
# allow to choose the seed ?
- _(b'[OPTION]... [-r] REV...'))
+ _(b'[OPTION]... [-r] REV...'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def touch(ui, repo, *revs, **opts):
"""create successors identical to their predecessors but the changeset ID
@@ -1393,27 +1402,7 @@
p2 = newmapping.get(p2, p2)
if not (duplicate or allowdivergence):
- # If reviving this cset creates divergence, let's ask user
- # what to do: create divergence or duplicate
-
- # We need to check two cases that can cause divergence:
- # case 1: the rev being revived has a non-obsolete successor (easily
- # detected by successorssets)
- sset = obsutil.successorssets(repo, ctx.node())
- nodivergencerisk = (len(sset) == 0
- or (len(sset) == 1
- and len(sset[0]) == 1
- and repo[sset[0][0]].rev() == ctx.rev()
- ))
- if nodivergencerisk:
- # case 2: one of the precursors of the rev being revived has a
- # non-obsolete successor (we need divergentsets for this)
- from . import evolvecmd
- if evolvecmd.divergentsets(repo, ctx):
- nodivergencerisk = False
- if nodivergencerisk:
- duplicate = False
- else:
+ if precheck_contentdiv(repo, ctx):
displayer.show(ctx)
index = ui.promptchoice(
_(b"reviving this changeset will create divergence"
@@ -1421,9 +1410,7 @@
b" (d)uplicate the changeset? $$ &Allowdivergence $$ "
b"&Duplicate"), 0)
choice = [b'allowdivergence', b'duplicate'][index]
- if choice == b'allowdivergence':
- duplicate = False
- else:
+ if choice == b'duplicate':
duplicate = True
updates = []
@@ -1454,7 +1441,8 @@
(b'c', b'continue', False, b'continue interrupted pick'),
(b'a', b'abort', False, b'abort interrupted pick'),
] + mergetoolopts,
- _(b'[OPTION]... [-r] REV'))
+ _(b'[OPTION]... [-r] REV'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def cmdpick(ui, repo, *revs, **opts):
"""move a commit on the top of working directory parent and updates to it."""
--- a/hgext3rd/evolve/compat.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/compat.py Sun Feb 02 13:28:47 2020 +0100
@@ -13,11 +13,10 @@
from mercurial import (
context,
copies,
- encoding,
mdiff,
obsolete,
- obsutil,
pycompat,
+ registrar,
repair,
scmutil,
util,
@@ -41,9 +40,9 @@
changesetdiffer = logcmdutil.changesetdiffer
except (AttributeError, ImportError):
from mercurial import cmdutil
- changesetdisplayer = cmdutil.show_changeset
- changesetprinter = cmdutil.changeset_printer
- displaygraph = cmdutil.displaygraph
+ changesetdisplayer = cmdutil.show_changeset # pytype: disable=module-attr
+ changesetprinter = cmdutil.changeset_printer # pytype: disable=module-attr
+ displaygraph = cmdutil.displaygraph # pytype: disable=module-attr
changesetdiffer = None
# hg <= 5.3 (c21aca51b392)
@@ -51,7 +50,7 @@
from mercurial import pathutil
dirs = pathutil.dirs
except (AttributeError, ImportError):
- dirs = util.dirs
+ dirs = util.dirs # pytype: disable=module-attr
from . import (
exthelper,
@@ -59,14 +58,6 @@
eh = exthelper.exthelper()
-def isobsnotesupported():
- # hack to know obsnote is supported. The patches for obsnote support was
- # pushed before the obsfateprinter patches, so this will serve as a good
- # check
- if not obsutil:
- return False
- return util.safehasattr(obsutil, 'obsfateprinter')
-
# Evolution renaming compat
TROUBLES = {
@@ -75,6 +66,7 @@
r'PHASEDIVERGENT': b'phase-divergent',
}
+# hg <= 4.6 (bec1212eceaa)
if util.safehasattr(uimod.ui, 'makeprogress'):
def progress(ui, topic, pos, item=b"", unit=b"", total=None):
progress = ui.makeprogress(topic, unit, total)
@@ -96,7 +88,7 @@
def memfilectx(repo, ctx, fctx, flags, copied, path):
# XXX Would it be better at the module level?
- varnames = context.memfilectx.__init__.__code__.co_varnames
+ varnames = context.memfilectx.__init__.__code__.co_varnames # pytype: disable=attribute-error
if r"copysource" in varnames:
mctx = context.memfilectx(repo, ctx, fctx.path(), fctx.data(),
@@ -108,12 +100,12 @@
mctx = context.memfilectx(repo, ctx, fctx.path(), fctx.data(),
islink=b'l' in flags,
isexec=b'x' in flags,
- copied=copied.get(path))
+ copied=copied.get(path)) # pytype: disable=wrong-keyword-args
else:
mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
islink=b'l' in flags,
isexec=b'x' in flags,
- copied=copied.get(path))
+ copied=copied.get(path)) # pytype: disable=wrong-keyword-args
return mctx
def strdiff(a, b, fn1, fn2):
@@ -136,14 +128,17 @@
# date related
+# hg <= 4.5 (c6061cadb400)
try:
import mercurial.utils.dateutil
+ datestr = mercurial.utils.dateutil.datestr
makedate = mercurial.utils.dateutil.makedate
parsedate = mercurial.utils.dateutil.parsedate
except ImportError:
import mercurial.util
- makedate = mercurial.util.makedate
- parsedate = mercurial.util.parsedate
+ datestr = mercurial.util.datestr # pytype: disable=module-attr
+ makedate = mercurial.util.makedate # pytype: disable=module-attr
+ parsedate = mercurial.util.parsedate # pytype: disable=module-attr
def wireprotocommand(exthelper, name, args=b'', permission=b'pull'):
try:
@@ -174,7 +169,7 @@
# scmutil.bookmarkrevs
# This change is a part of 4.7 cycle, so drop this when we drop support for 4.6
try:
- bmrevset = repair.stripbmrevset
+ bmrevset = repair.stripbmrevset # pytype: disable=module-attr
except AttributeError:
bmrevset = scmutil.bookmarkrevs
@@ -220,9 +215,9 @@
# hg < 4.8 compat (dc50121126ae)
try:
- limit = copies._findlimit(repo, c1, c2)
+ limit = copies._findlimit(repo, c1, c2) # pytype: disable=module-attr
except (AttributeError, TypeError):
- limit = copies._findlimit(repo, c1.rev(), c2.rev())
+ limit = copies._findlimit(repo, c1.rev(), c2.rev()) # pytype: disable=module-attr
if limit is None:
# no common ancestor, no copies
return {}, {}, {}, {}, {}
@@ -263,11 +258,11 @@
bothnew = sorted(addedinm1 & addedinm2)
if tca == base:
# unmatched file from base
- u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
+ u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2) # pytype: disable=module-attr
u1u, u2u = u1r, u2r
else:
# unmatched file from base (DAG rotation in the graft case)
- u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2,
+ u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2, # pytype: disable=module-attr
baselabel=b'base')
# unmatched file from topological common ancestors (no DAG rotation)
# need to recompute this for directory move handling when grafting
@@ -276,18 +271,18 @@
m1f = m1.filesnotin(mta, repo.narrowmatch())
m2f = m2.filesnotin(mta, repo.narrowmatch())
baselabel = b'topological common ancestor'
- u1u, u2u = copies._computenonoverlap(repo, c1, c2, m1f, m2f,
+ u1u, u2u = copies._computenonoverlap(repo, c1, c2, m1f, m2f, # pytype: disable=module-attr
baselabel=baselabel)
else:
- u1u, u2u = copies._computenonoverlap(repo, c1, c2, m1.filesnotin(mta),
+ u1u, u2u = copies._computenonoverlap(repo, c1, c2, m1.filesnotin(mta), # pytype: disable=module-attr
m2.filesnotin(mta),
baselabel=b'topological common ancestor')
for f in u1u:
- copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
+ copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1) # pytype: disable=module-attr
for f in u2u:
- copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
+ copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2) # pytype: disable=module-attr
copy = dict(data1[b'copy'])
copy.update(data2[b'copy'])
@@ -295,10 +290,10 @@
fullcopy.update(data2[b'fullcopy'])
if dirtyc1:
- copies._combinecopies(data2[b'incomplete'], data1[b'incomplete'], copy, diverge,
+ copies._combinecopies(data2[b'incomplete'], data1[b'incomplete'], copy, diverge, # pytype: disable=module-attr
incompletediverge)
else:
- copies._combinecopies(data1[b'incomplete'], data2[b'incomplete'], copy, diverge,
+ copies._combinecopies(data1[b'incomplete'], data2[b'incomplete'], copy, diverge, # pytype: disable=module-attr
incompletediverge)
renamedelete = {}
@@ -334,19 +329,19 @@
b'incompletediverge': bothincompletediverge
}
for f in bothnew:
- copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
- copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
+ copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1) # pytype: disable=module-attr
+ copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2) # pytype: disable=module-attr
if dirtyc1 and dirtyc2:
pass
elif dirtyc1:
# incomplete copies may only be found on the "dirty" side for bothnew
assert not both2[b'incomplete']
- remainder = copies._combinecopies({}, both1[b'incomplete'], copy, bothdiverge,
+ remainder = copies._combinecopies({}, both1[b'incomplete'], copy, bothdiverge, # pytype: disable=module-attr
bothincompletediverge)
elif dirtyc2:
assert not both1[b'incomplete']
- remainder = copies._combinecopies({}, both2[b'incomplete'], copy, bothdiverge,
+ remainder = copies._combinecopies({}, both2[b'incomplete'], copy, bothdiverge, # pytype: disable=module-attr
bothincompletediverge)
else:
# incomplete copies and divergences can't happen outside grafts
@@ -444,85 +439,14 @@
if not fixupstreamed:
copies._fullcopytracing = fixedcopytracing
-if not util.safehasattr(obsutil, "_succs"):
- class _succs(list):
- """small class to represent a successors with some metadata about it"""
-
- def __init__(self, *args, **kwargs):
- super(_succs, self).__init__(*args, **kwargs)
- self.markers = set()
-
- def copy(self):
- new = _succs(self)
- new.markers = self.markers.copy()
- return new
-
- @util.propertycache
- def _set(self):
- # immutable
- return set(self)
-
- def canmerge(self, other):
- return self._set.issubset(other._set)
-else:
- from mercurial.obsutil import _succs
-
-def wrap_succs(succs):
- """ Wrap old data format of successorsets (tuple) only if if's not yet a
- _succs instance
- """
-
- if not util.safehasattr(succs, "markers"):
- return _succs(succs)
- else:
- return succs
-
-if not util.safehasattr(obsutil, "markersdates"):
- MARKERS_DATE_COMPAT = True
-else:
- MARKERS_DATE_COMPAT = False
-
-def markersdates(markers):
- """returns the list of dates for a list of markers
- """
- if MARKERS_DATE_COMPAT is False:
- return obsutil.markersdates(markers)
-
- return [m[4] for m in markers]
-
-if not util.safehasattr(obsutil, "markersusers"):
- MARKERS_USERS_COMPAT = True
-else:
- MARKERS_USERS_COMPAT = False
-
-def markersusers(markers):
- """ Returns a sorted list of markers users without duplicates
- """
- if MARKERS_USERS_COMPAT is False:
- return obsutil.markersusers(markers)
-
- markersmeta = [dict(m[3]) for m in markers]
- users = set(encoding.tolocal(meta[b'user']) for meta in markersmeta
- if meta.get(b'user'))
-
- return sorted(users)
-
-if not util.safehasattr(obsutil, "markersoperations"):
- MARKERS_OPERATIONS_COMPAT = True
-else:
- MARKERS_OPERATIONS_COMPAT = False
-
-def markersoperations(markers):
- """ Returns a sorted list of markers operations without duplicates
- """
- if MARKERS_OPERATIONS_COMPAT is False:
- return obsutil.markersoperations(markers)
-
- markersmeta = [dict(m[3]) for m in markers]
- operations = set(meta.get(b'operation') for meta in markersmeta
- if meta.get(b'operation'))
-
- return sorted(operations)
+# help category compatibility
+# hg <= 4.7 (c303d65d2e34)
+def helpcategorykwargs(categoryname):
+ """Backwards-compatible specification of the helpategory argument."""
+ category = getattr(registrar.command, categoryname, None)
+ if not category:
+ return {}
+ return {'helpcategory': category}
# nodemap.get and index.[has_node|rev|get_rev]
# hg <= 5.3 (02802fa87b74)
--- a/hgext3rd/evolve/evolvecmd.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/evolvecmd.py Sun Feb 02 13:28:47 2020 +0100
@@ -16,7 +16,6 @@
cmdutil,
commands,
context,
- copies,
error,
encoding,
hg,
@@ -62,7 +61,7 @@
returns a tuple (bool, newnode) where,
bool: a boolean value indicating whether the instability was solved
newnode: if bool is True, then the newnode of the resultant commit
- formed. newnode can be node, when resolution led to no new
+ formed. newnode can be None, when resolution led to no new
commit. If bool is False, this is ".".
"""
tr = repo.currenttransaction()
@@ -123,43 +122,28 @@
ui.warn(_(b"cannot solve instability of %s, skipping\n") % orig)
return (False, b".")
obs = pctx
- newer = obsutil.successorssets(repo, obs.node())
- # search of a parent which is not killed, but also isn't the orig
- while not newer or newer == [()] or newer[0][0] == orig.node():
- ui.debug(b"stabilize target %s is plain dead,"
- b" trying to stabilize on its parent\n" %
- obs)
- obs = obs.parents()[0]
- newer = obsutil.successorssets(repo, obs.node())
- if len(newer) > 1:
- msg = _(b"skipping %s: divergent rewriting. can't choose "
- b"destination\n") % obs
- ui.write_err(msg)
- return (False, b".")
- targets = newer[0]
- assert targets
- if len(targets) > 1:
- # split target, figure out which one to pick, are they all in line?
- targetrevs = [repo[r].rev() for r in targets]
- roots = repo.revs(b'roots(%ld)', targetrevs)
- heads = repo.revs(b'heads(%ld)', targetrevs)
- if len(roots) > 1 or len(heads) > 1:
- cheader = _(b"ancestor '%s' split over multiple topological"
- b" branches.\nchoose an evolve destination:") % orig
- selectedrev = utility.revselectionprompt(ui, repo, list(heads),
- cheader)
- if selectedrev is None:
+ try:
+ newer = utility._singlesuccessor(repo, obs)
+ # search of a parent which isn't the orig
+ while repo[newer].node() == orig.node():
+ obs = obs.parents()[0]
+ newer = utility._singlesuccessor(repo, obs)
+ except utility.MultipleSuccessorsError as exc:
+ if exc.divergenceflag:
+ msg = _(b"skipping %s: divergent rewriting. can't choose "
+ b"destination\n") % obs
+ ui.write_err(msg)
+ return (False, b".")
+ if exc.splitflag:
+ splitsucc = utility.picksplitsuccessor(ui, repo, obs, orig)
+ if not splitsucc[0]:
msg = _(b"could not solve instability, "
b"ambiguous destination: "
b"parent split across two branches\n")
ui.write_err(msg)
return (False, b".")
- target = repo[selectedrev]
- else:
- target = repo[heads.first()]
- else:
- target = targets[0]
- target = repo[target]
+ newer = splitsucc[1]
+ target = repo[newer]
if not ui.quiet or confirm:
repo.ui.write(_(b'move:'), label=b'evolve.operation')
displayer.show(orig)
@@ -179,8 +163,8 @@
if progresscb:
progresscb()
with state.saver(evolvestate, {b'current': orig.node()}):
- newid = relocate(repo, orig, target, evolvestate, pctx,
- keepbranch, b'orphan')
+ newid = _relocate(repo, orig, target, evolvestate, pctx,
+ keepbranch, b'orphan')
return (True, newid)
def _solvephasedivergence(ui, repo, bumped, evolvestate, displayer,
@@ -238,8 +222,8 @@
_(b'rebasing to destination parent: %s\n') % prec.p1())
with state.saver(evolvestate, {b'current': bumped.hex(),
b'precursor': prec.hex()}):
- newnode = relocate(repo, bumped, prec.p1(), evolvestate,
- category=b'phasedivergent')
+ newnode = _relocate(repo, bumped, prec.p1(), evolvestate,
+ category=b'phasedivergent')
if newnode is not None:
new = repo[newnode]
obsolete.createmarkers(repo, [(bumped, (new,))],
@@ -300,17 +284,9 @@
repo.dirstate.setparents(newid, nodemod.nullid)
return (True, replacementnode)
-def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
- confirm=False, progresscb=None):
- """tries to solve content-divergence of a changeset
-
- returns a tuple (bool, newnode) where,
- bool: a boolean value indicating whether the instability was solved
- newnode: if bool is True, then the newnode of the resultant commit
- formed. newnode can be node, when resolution led to no new
- commit. If bool is False, this is ".".
- """
- repo = repo.unfiltered()
+def _prepcontentdivresolution(ui, repo, divergent, other, evolvestate):
+ """ if relocation required, decide which divergent cset will be relocated
+ to the other side"""
divergent = repo[divergent.rev()]
evolvestate[b'divergent'] = divergent.node()
evolvestate[b'orig-divergent'] = divergent.node()
@@ -320,32 +296,15 @@
# strip that relocated commit. However if `--all` is passed, we need to
# reset this value for each content-divergence resolution which we are doing
# below.
- evolvestate[b'relocated'] = None
- evolvestate[b'relocating'] = False
+ evolvestate[b'relocated-other'] = None
+ evolvestate[b'relocating-other'] = False
+ evolvestate[b'relocated-div'] = None
+ evolvestate[b'relocating-div'] = False
+ evolvestate[b'relocation-req'] = False
# in case or relocation we get a new other node, we need to store the old
# other for purposes like `--abort` or `--stop`
evolvestate[b'old-other'] = None
- base, others = divergentdata(divergent)
-
- # we don't handle split in content-divergence yet
- if len(others) > 1:
- othersstr = b"[%s]" % (b','.join([bytes(i) for i in others]))
- msg = _(b"skipping %s: %s with a changeset that got split"
- b" into multiple ones:\n"
- b"|[%s]\n"
- b"| This is not handled by automatic evolution yet\n"
- b"| You have to fallback to manual handling with commands "
- b"such as:\n"
- b"| - hg touch -D\n"
- b"| - hg prune\n"
- b"| \n"
- b"| You should contact your local evolution Guru for help.\n"
- ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
- ui.write_err(msg)
- return (False, b".")
- other = others[0]
- evolvestate[b'other-divergent'] = other.node()
- evolvestate[b'base'] = base.node()
+ evolvestate[b'old-divergent'] = None
def swapnodes(div, other):
div, other = other, div
@@ -364,6 +323,7 @@
else:
publicdiv = divergent
evolvestate[b'public-divergent'] = publicdiv.node()
+
# we don't handle merge content-divergent changesets yet
if len(other.parents()) > 1:
msg = _(b"skipping %s: %s changeset can't be "
@@ -375,32 +335,32 @@
ui.write_err(hint)
return (False, b".")
- otherp1 = other.p1().rev()
- divp1 = divergent.p1().rev()
+ otherp1 = succsotherp1 = other.p1().rev()
+ divp1 = succsdivp1 = divergent.p1().rev()
# finding single successors of otherp1 and divp1
try:
- otherp1 = utility._singlesuccessor(repo, other.p1())
+ succsotherp1 = utility._singlesuccessor(repo, other.p1())
except utility.MultipleSuccessorsError:
pass
try:
- divp1 = utility._singlesuccessor(repo, divergent.p1())
+ succsdivp1 = utility._singlesuccessor(repo, divergent.p1())
except utility.MultipleSuccessorsError:
pass
# the changeset on which resolution changeset will be based on
- resolutionparent = repo[divp1].node()
+ resolutionparent = repo[succsdivp1].node()
# the nullrev has to be handled specially because -1 is overloaded to both
# mean nullrev (this meaning is used for the result of changectx.rev(), as
# called above) and the tipmost revision (this meaning is used for the %d
# format specifier, as used below)
- if nodemod.nullrev in (otherp1, divp1):
- # nullrev is the only possible ancestor if otherp1 or divp1 is nullrev
+ if nodemod.nullrev in (succsotherp1, succsdivp1):
+ # nullrev is the only possible ancestor if succsotherp1 or succsdivp1 is nullrev
gca = [nodemod.nullrev]
else:
- gca = repo.revs(b"ancestor(%d, %d)" % (otherp1, divp1))
+ gca = repo.revs(b"ancestor(%d, %d)" % (succsotherp1, succsdivp1))
# divonly: non-obsolete csets which are topological ancestor of "divergent"
# but not "other"
divonly = repo.revs(b"only(%d, %d) - obsolete()" % (divergent.rev(),
@@ -428,32 +388,31 @@
# for 2) we will relocate one which is behind to the parent of ahead one and
# then solve the content-divergence the way we solve 1)
# for 3) and 4), we still have to decide
- if otherp1 in gca and divp1 in gca:
- if otherp1 == other.p1().rev() and divp1 == divergent.p1().rev():
- # both are on the same parents
+ if otherp1 == divp1:
+ # both are on the same parents
+ pass
+ elif succsotherp1 in gca and succsdivp1 in gca:
+ # both are not on the same parent but have same parents's succs.
+ if otheronly and divonly:
+ # case: we have visible csets on both side diverging from
+ # tca of "divergent" and "other". We still need to decide what
+ # to do in this case
pass
+ if otheronly:
+ relocatereq = True
+ if not haspubdiv:
+ # can't swap when public divergence, as public can't move
+ divergent, other = swapnodes(divergent, other)
+ resolutionparent = repo[succsotherp1].node()
+ elif divonly:
+ relocatereq = True
else:
- # both are not on the same parent but have same parents's succs.
- if otheronly and divonly:
- # case: we have visible csets on both side diverging from
- # tca of "divergent" and "other". We still need to decide what
- # to do in this case
- pass
- if otheronly:
- relocatereq = True
- if not haspubdiv:
- # can't swap when public divergence, as public can't move
- divergent, other = swapnodes(divergent, other)
- resolutionparent = repo[otherp1].node()
- elif divonly:
- relocatereq = True
- else:
- # no extra cset on either side; so not considering relocation
- pass
- elif otherp1 in gca and divp1 not in gca:
+ # no extra cset on either side; so not considering relocation
+ pass
+ elif succsotherp1 in gca and succsdivp1 not in gca:
relocatereq = True
pass
- elif divp1 in gca and otherp1 not in gca:
+ elif succsdivp1 in gca and succsotherp1 not in gca:
relocatereq = True
# When public branch is behind to the mutable branch, for now we
@@ -482,6 +441,52 @@
ui.write_err(hint)
return (False, b".")
+ return (True, divergent, other, resolutionparent, relocatereq)
+
+def _solvedivergent(ui, repo, divergent, evolvestate, displayer, dryrun=False,
+ confirm=False, progresscb=None):
+ """tries to solve content-divergence of a changeset
+
+ returns a tuple (bool, newnode) where,
+ bool: a boolean value indicating whether the instability was solved
+ newnode: if bool is True, then the newnode of the resultant commit
+ formed. newnode can be node, when resolution led to no new
+ commit. If bool is False, this is ".".
+ """
+ repo = repo.unfiltered()
+ base, others = divergentdata(divergent)
+
+ # we don't handle split in content-divergence yet
+ if len(others) > 1:
+ othersstr = b"[%s]" % (b','.join([bytes(i) for i in others]))
+ msg = _(b"skipping %s: %s with a changeset that got split"
+ b" into multiple ones:\n"
+ b"|[%s]\n"
+ b"| This is not handled by automatic evolution yet\n"
+ b"| You have to fallback to manual handling with commands "
+ b"such as:\n"
+ b"| - hg touch -D\n"
+ b"| - hg prune\n"
+ b"| \n"
+ b"| You should contact your local evolution Guru for help.\n"
+ ) % (divergent, TROUBLES['CONTENTDIVERGENT'], othersstr)
+ ui.write_err(msg)
+ return (False, b".")
+ other = others[0]
+ evolvestate[b'other-divergent'] = other.node()
+ evolvestate[b'base'] = base.node()
+
+ # setup everything before merging two content-divergent csets
+ datatoproceed = _prepcontentdivresolution(ui, repo, divergent, other,
+ evolvestate)
+ if not datatoproceed[0]:
+ return (False, b".")
+ divergent, other, resolutionparent, relocatereq = datatoproceed[1:]
+
+ if relocatereq:
+ evolvestate['relocation-req'] = True
+ evolvestate[b'resolutionparent'] = resolutionparent
+
if not ui.quiet or confirm:
ui.write(_(b'merge:'), label=b'evolve.operation')
displayer.show(divergent)
@@ -502,19 +507,26 @@
% divergent))
return (False, b".")
+ if relocatereq:
+ evolvestate[b'relocation-req'] = True
+ evolvestate[b'resolutionparent'] = resolutionparent
try:
succsdivp1 = utility._singlesuccessor(repo, divergent.p1())
except utility.MultipleSuccessorsError:
- msg = _(b"ambiguous orphan resolution parent for %b")
+ msg = _(b"ambiguous orphan resolution parent for %s")
raise error.Abort(msg % divergent.hex()[:12])
# relocate divergent cset to its obsolete parent's successsor
if succsdivp1 != divergent.p1().rev():
+ evolvestate[b'relocating-div'] = True
ui.status(_(b'rebasing "divergent" content-divergent changeset %s on'
b' %s\n' % (divergent, repo[succsdivp1])))
with state.saver(evolvestate, {b'current': divergent.node()}):
- newdivergent = relocate(repo, divergent, repo[succsdivp1],
- evolvestate, keepbranch=True)
+ newdivergent = _relocate(repo, divergent, repo[succsdivp1],
+ evolvestate, keepbranch=True)
+ evolvestate[b'old-divergent'] = divergent.node()
divergent = repo[newdivergent]
+ evolvestate[b'relocating-div'] = False
+ evolvestate[b'relocated-div'] = divergent.node()
evolvestate[b'temprevs'].append(divergent.node())
evolvestate[b'divergent'] = divergent.node()
@@ -522,22 +534,21 @@
if relocatereq and other == divergent.p1():
relocatereq = False
- evolvestate[b'resolutionparent'] = resolutionparent
# relocate the other divergent if required
if relocatereq:
# relocating will help us understand during the time of conflicts that
# whether conflicts occur at reloacting or they occured at merging
# content divergent changesets
- evolvestate[b'relocating'] = True
+ evolvestate[b'relocating-other'] = True
ui.status(_(b'rebasing "other" content-divergent changeset %s on'
b' %s\n' % (other, divergent.p1())))
with state.saver(evolvestate, {b'current': other.node()}):
- newother = relocate(repo, other, divergent.p1(), evolvestate,
- keepbranch=True)
+ newother = _relocate(repo, other, divergent.p1(), evolvestate,
+ keepbranch=True)
evolvestate[b'old-other'] = other.node()
other = repo[newother]
- evolvestate[b'relocating'] = False
- evolvestate[b'relocated'] = other.node()
+ evolvestate[b'relocating-other'] = False
+ evolvestate[b'relocated-other'] = other.node()
evolvestate[b'temprevs'].append(other.node())
evolvestate[b'other-divergent'] = other.node()
@@ -545,9 +556,11 @@
evolvestate)
res, newnode = _completecontentdivergent(ui, repo, progresscb, divergent,
other, base, evolvestate)
+ haspubdiv = not (divergent.mutable() and other.mutable())
if not haspubdiv:
return (res, newnode)
else:
+ publicdiv = repo[evolvestate[b'public-divergent']]
# we have content-divergence with a public cset:
# after performing content divergence resolution steps, possbile cases:
# 1) merging results in a new node:
@@ -607,7 +620,6 @@
# resume resolution
if progresscb:
progresscb()
- emtpycommitallowed = repo.ui.backupconfig(b'ui', b'allowemptycommit')
tr = repo.currenttransaction()
assert tr is not None
# whether to store the obsmarker in the evolvestate
@@ -635,68 +647,64 @@
obsolete.createmarkers(repo, [(otherdiv, (publicdiv,))],
operation=b'evolve')
return (True, publicnode)
- try:
- with repo.dirstate.parentchange(), compat.parentchange(repo):
- repo.dirstate.setparents(resparent, nodemod.nullid)
-
- dirstatedance(repo, divergent, resparent, None)
- # merge the branches
- mergebranches(repo, divergent, other, base)
- # merge the commit messages
- desc = mergecommitmessages(ui, base.description(),
- divergent.description(),
- other.description())
- user = utility.mergeusers(ui, base, divergent, other)
+ with repo.dirstate.parentchange(), compat.parentchange(repo):
+ repo.dirstate.setparents(resparent, nodemod.nullid)
+
+ dirstatedance(repo, divergent, resparent, None)
- # new node if any formed as the replacement
- newnode = None
+ # merge the branches
+ mergebranches(repo, divergent, other, base)
+ # merge the commit messages
+ desc = mergecommitmessages(ui, base.description(),
+ divergent.description(),
+ other.description())
+ user = utility.mergeusers(ui, base, divergent, other)
- mergehook(repo, base, divergent, other)
+ mergehook(repo, base, divergent, other)
- date = divergent.date()
- if other.date() != divergent.date():
- basedate = base.date()
- if other.date() == basedate:
- date = divergent.date()
- elif divergent.date() == basedate:
- date = other.date()
- else:
- date = max(divergent.date(), other.date())
+ date = divergent.date()
+ if other.date() != divergent.date():
+ basedate = base.date()
+ if other.date() == basedate:
+ date = divergent.date()
+ elif divergent.date() == basedate:
+ date = other.date()
+ else:
+ date = max(divergent.date(), other.date())
- newnode = repo.commit(text=desc, user=user, date=date)
- if newnode == divergent.node() or newnode is None:
- # no changes
- new = divergent
- storemarker = True
- repo.ui.status(_(b"nothing changed\n"))
- hg.updaterepo(repo, divergent.rev(), False)
+ # new node if any formed as the replacement
+ newnode = repo.commit(text=desc, user=user, date=date)
+ if newnode == divergent.node() or newnode is None:
+ # no changes
+ new = divergent
+ storemarker = True
+ repo.ui.status(_(b"nothing changed\n"))
+ hg.updaterepo(repo, divergent.rev(), False)
+ else:
+ new = repo[newnode]
+ newnode = new.node()
+ hg.updaterepo(repo, new.rev(), False)
+ if haspubdiv and publicdiv == divergent:
+ bypassphase(repo, (divergent, new), operation=b'evolve')
else:
- new = repo[newnode]
- newnode = new.node()
- hg.updaterepo(repo, new.rev(), False)
- if haspubdiv and publicdiv == divergent:
- bypassphase(repo, (divergent, new), operation=b'evolve')
- else:
- obsolete.createmarkers(repo, [(divergent, (new,))],
- operation=b'evolve')
+ obsolete.createmarkers(repo, [(divergent, (new,))],
+ operation=b'evolve')
- # creating markers and moving phases post-resolution
- if haspubdiv and publicdiv == other:
- bypassphase(repo, (other, new), operation=b'evolve')
- else:
- obsolete.createmarkers(repo, [(other, (new,))], operation=b'evolve')
- if storemarker:
- # storing the marker in the evolvestate
- # we just store the precursors and successor pair for now, we might
- # want to store more data and serialize obsmarker in a better way in
- # future
- evolvestate[b'obsmarkers'].append((other.node(), new.node()))
+ # creating markers and moving phases post-resolution
+ if haspubdiv and publicdiv == other:
+ bypassphase(repo, (other, new), operation=b'evolve')
+ else:
+ obsolete.createmarkers(repo, [(other, (new,))], operation=b'evolve')
+ if storemarker:
+ # storing the marker in the evolvestate
+ # we just store the precursors and successor pair for now, we might
+ # want to store more data and serialize obsmarker in a better way in
+ # future
+ evolvestate[b'obsmarkers'].append((other.node(), new.node()))
- phases.retractboundary(repo, tr, other.phase(), [new.node()])
- return (True, newnode)
- finally:
- repo.ui.restoreconfig(emtpycommitallowed)
+ phases.retractboundary(repo, tr, other.phase(), [new.node()])
+ return (True, newnode)
def warnmetadataloss(repo, local, other):
"""warn the user for the metadata being lost while resolving
@@ -954,8 +962,8 @@
ordering.extend(sorted(dependencies))
return ordering
-def relocate(repo, orig, dest, evolvestate, pctx=None, keepbranch=False,
- category=None):
+def _relocate(repo, orig, dest, evolvestate, pctx=None, keepbranch=False,
+ category=None):
"""rewrites the orig rev on dest rev
returns the node of new commit which is formed
@@ -1009,14 +1017,6 @@
with repo.dirstate.parentchange(), compat.parentchange(repo):
repo.setparents(dest.node(), orig.node())
repo.dirstate.write(tr)
- # fix up dirstate for copies and renames
- if util.safehasattr(copies, 'graftcopies'):
- copies.graftcopies(repo[None], dest, orig.p1())
- else:
- # hg <= 5.2 (2f0a44c69e07)
- copies.duplicatecopies(repo, repo[None], dest.rev(),
- orig.p1().rev())
- dirstatedance(repo, dest, orig.node(), None)
hint = _(b"see 'hg help evolve.interrupted'")
raise error.InterventionRequired(_(b"unresolved merge conflicts"),
hint=hint)
@@ -1032,16 +1032,14 @@
del extra[b'branch']
extra[b'rebase_source'] = orig.hex()
- backup = repo.ui.backupconfig(b'phases', b'new-commit')
- try:
- targetphase = max(orig.phase(), phases.draft)
- repo.ui.setconfig(b'phases', b'new-commit', targetphase, b'evolve')
+ targetphase = max(orig.phase(), phases.draft)
+ configoverride = repo.ui.configoverride({
+ (b'phases', b'new-commit'): targetphase
+ }, source=b'evolve')
+ with configoverride:
# Commit might fail if unresolved files exist
- nodenew = repo.commit(text=commitmsg, user=orig.user(),
- date=orig.date(), extra=extra)
- finally:
- repo.ui.restoreconfig(backup)
- return nodenew
+ return repo.commit(text=commitmsg, user=orig.user(),
+ date=orig.date(), extra=extra)
def _finalizerelocate(repo, orig, dest, nodenew, tr, category, evolvestate):
destbookmarks = repo.nodebookmarks(dest.node())
@@ -1050,7 +1048,7 @@
bmchanges = []
if nodenew is not None:
- obsolete.createmarkers(repo, [(repo[nodesrc], (repo[nodenew],))],
+ obsolete.createmarkers(repo, [(orig, (repo[nodenew],))],
operation=b'evolve')
for book in oldbookmarks:
bmchanges.append((book, nodenew))
@@ -1059,7 +1057,7 @@
if category == b'orphan':
repo.ui.status(_(b"evolution of %d:%s created no changes "
b"to commit\n") % (orig.rev(), orig))
- obsolete.createmarkers(repo, [(repo[nodesrc], ())], operation=b'evolve')
+ obsolete.createmarkers(repo, [(orig, ())], operation=b'evolve')
# Behave like rebase, move bookmarks to dest
for book in oldbookmarks:
evolvestate[b'bookmarkchanges'].append((book, nodesrc))
@@ -1544,7 +1542,8 @@
b' in the repo')),
] + mergetoolopts,
_(b'[OPTIONS]...'),
- helpbasic=True
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT')
)
def evolve(ui, repo, **opts):
"""solve troubled changesets in your repository
@@ -1847,15 +1846,29 @@
"""logic for handling of `hg evolve --stop`"""
updated = False
pctx = None
+ divrelocated = evolvestate.get(b'relocated-div')
+ otherrelocated = evolvestate.get(b'relocated-other')
+ strips = []
+ if divrelocated:
+ strips.append(divrelocated)
+ if otherrelocated:
+ strips.append(otherrelocated)
if (evolvestate[b'command'] == b'evolve'
and evolvestate[b'category'] == b'contentdivergent'
- and evolvestate[b'relocated']):
+ and strips):
oldother = evolvestate[b'old-other']
- if oldother:
+ olddiv = evolvestate[b'old-divergent']
+ if olddiv:
+ with repo.wlock(), repo.lock():
+ repo = repo.unfiltered()
+ hg.updaterepo(repo, olddiv, True)
+ repair.strip(ui, repo, strips, False)
+ updated = True
+ pctx = repo[olddiv]
+ elif oldother:
with repo.wlock(), repo.lock():
repo = repo.unfiltered()
hg.updaterepo(repo, oldother, True)
- strips = [evolvestate[b'relocated']]
repair.strip(ui, repo, strips, False)
updated = True
pctx = repo[oldother]
@@ -2029,13 +2042,47 @@
divergent = evolvestate[b'divergent']
base = evolvestate[b'base']
repo = repo.unfiltered()
- if evolvestate[b'relocating']:
+ if evolvestate[b'relocating-div']:
+ newdiv = _completerelocation(ui, repo, evolvestate)
+ current = repo[evolvestate[b'current']]
+ obsolete.createmarkers(repo, [(current, (repo[newdiv],))],
+ operation=b'evolve')
+ evolvestate[b'old-divergent'] = repo[divergent].node()
+ evolvestate[b'relocating-div'] = False
+ evolvestate[b'relocated-div'] = newdiv
+ evolvestate[b'temprevs'].append(newdiv)
+ evolvestate[b'divergent'] = newdiv
+
+ relocatereq = evolvestate[b'relocation-req']
+ if relocatereq:
+ divergent = repo[evolvestate[b'divergent']]
+ other = repo[evolvestate[b'other-divergent']]
+ evolvestate[b'relocating-other'] = True
+ ui.status(_(b'rebasing "other" content-divergent changeset %s on'
+ b' %s\n' % (other, divergent.p1())))
+ with state.saver(evolvestate, {b'current': other.node()}):
+ newother = _relocate(repo, other, divergent.p1(),
+ evolvestate, keepbranch=True)
+ evolvestate[b'old-other'] = other.node()
+ other = repo[newother]
+ evolvestate[b'relocating-other'] = False
+ evolvestate[b'relocated-other'] = other.node()
+ evolvestate[b'temprevs'].append(other.node())
+ evolvestate[b'other-divergent'] = other.node()
+ # continue the resolution by merging the content-divergence
+ _mergecontentdivergents(repo, progresscb,
+ divergent,
+ repo[newother],
+ repo[base],
+ evolvestate)
+
+ if evolvestate[b'relocating-other']:
newother = _completerelocation(ui, repo, evolvestate)
current = repo[evolvestate[b'current']]
obsolete.createmarkers(repo, [(current, (repo[newother],))],
operation=b'evolve')
- evolvestate[b'relocating'] = False
- evolvestate[b'relocated'] = newother
+ evolvestate[b'relocating-other'] = False
+ evolvestate[b'relocated-other'] = newother
evolvestate[b'temprevs'].append(newother)
evolvestate[b'other-divergent'] = newother
# continue the resolution by merging the content-divergence
@@ -2045,18 +2092,19 @@
repo[base],
evolvestate)
+ divergent = evolvestate[b'divergent']
other = evolvestate[b'other-divergent']
- ret = _completecontentdivergent(ui, repo, progresscb,
- repo[divergent],
- repo[other],
- repo[base],
- evolvestate)
+ res, newnode = _completecontentdivergent(ui, repo, progresscb,
+ repo[divergent],
+ repo[other],
+ repo[base],
+ evolvestate)
origdivergent = evolvestate[b'orig-divergent']
- evolvestate[b'replacements'][origdivergent] = ret[1]
+ evolvestate[b'replacements'][origdivergent] = newnode
+ ret = (res, newnode)
# logic to continue the public content-divergent
publicnode = evolvestate.get(b'public-divergent')
if publicnode:
- res, newnode = ret
if not res:
# no need to proceed for phase divergence resolution step
pass
@@ -2141,7 +2189,7 @@
ctxparents = orig.parents()
if len(ctxparents) == 2:
- currentp1 = repo.dirstate.parents()[0]
+ currentp1 = repo.dirstate.p1()
p1obs = ctxparents[0].obsolete()
p2obs = ctxparents[1].obsolete()
# asumming that the parent of current wdir is successor of one
@@ -2171,7 +2219,7 @@
pass
else:
with repo.dirstate.parentchange(), compat.parentchange(repo):
- repo.dirstate.setparents(repo.dirstate.parents()[0], nodemod.nullid)
+ repo.dirstate.setparents(repo.dirstate.p1(), nodemod.nullid)
with repo.ui.configoverride(overrides, b'evolve-continue'):
node = repo.commit(text=message, user=user,
--- a/hgext3rd/evolve/exthelper.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/exthelper.py Sun Feb 02 13:28:47 2020 +0100
@@ -50,7 +50,7 @@
@eh.command('mynewcommand',
[('r', 'rev', [], _('operate on these revisions'))],
_('-r REV...'),
- helpcategory=command.CATEGORY_XXX)
+ **compat.helpcategorykwargs('CATEGORY_XXX'))
def newcommand(ui, repo, *revs, **opts):
# implementation goes here
--- a/hgext3rd/evolve/genericcaches.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/genericcaches.py Sun Feb 02 13:28:47 2020 +0100
@@ -14,7 +14,7 @@
util,
)
-class incrementalcachebase(object):
+class incrementalcachebase(object): # pytype: disable=ignored-metaclass
"""base class for incremental cache from append only source
There are multiple append only data source we might want to cache
@@ -133,7 +133,7 @@
"""read the cachekey from bytes"""
return self._cachekeystruct.unpack(data)
-class changelogsourcebase(incrementalcachebase):
+class changelogsourcebase(incrementalcachebase): # pytype: disable=ignored-metaclass
"""an abstract class for cache sourcing data from the changelog
For this purpose it use a cache key covering changelog content.
--- a/hgext3rd/evolve/metadata.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/metadata.py Sun Feb 02 13:28:47 2020 +0100
@@ -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'9.2.3.dev'
+__version__ = b'9.3.0.dev'
testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3'
minimumhgversion = b'4.5'
buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obsexchange.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/obsexchange.py Sun Feb 02 13:28:47 2020 +0100
@@ -7,17 +7,11 @@
from __future__ import absolute_import
-try:
- from StringIO import StringIO
-except ImportError:
- from io import StringIO
-
from mercurial import (
bundle2,
error,
exchange,
extensions,
- lock as lockmod,
node,
obsolete,
pushkey,
@@ -35,7 +29,6 @@
eh = exthelper.exthelper()
eh.merge(obsdiscovery.eh)
obsexcmsg = utility.obsexcmsg
-obsexcprg = utility.obsexcprg
eh.configitem(b'experimental', b'verbose-obsolescence-exchange', False)
@@ -156,82 +149,6 @@
return _obscommon_capabilities(oldcap, repo, proto)
wireprotov1server.commands[b'capabilities'] = (newcap, args)
-def _pushobsmarkers(repo, data):
- tr = lock = None
- try:
- lock = repo.lock()
- tr = repo.transaction(b'pushkey: obsolete markers')
- new = repo.obsstore.mergemarkers(tr, data)
- if new is not None:
- obsexcmsg(repo.ui, b"%i obsolescence markers added\n" % new, True)
- tr.close()
- finally:
- lockmod.release(tr, lock)
- repo.hook(b'evolve_pushobsmarkers')
-
-def srv_pushobsmarkers(repo, proto):
- """wireprotocol command"""
- fp = StringIO()
- proto.redirect()
- proto.getfile(fp)
- data = fp.getvalue()
- fp.close()
- _pushobsmarkers(repo, data)
- try:
- from mercurial import wireprototypes
- wireprototypes.pushres # force demandimport
- except (ImportError, AttributeError):
- from mercurial import wireproto as wireprototypes
- return wireprototypes.pushres(0)
-
-def _getobsmarkersstream(repo, heads=None, common=None):
- """Get a binary stream for all markers relevant to `::<heads> - ::<common>`
- """
- revset = b''
- args = []
- repo = repo.unfiltered()
- if heads is None:
- revset = b'all()'
- elif heads:
- revset += b"(::%ln)"
- args.append(heads)
- else:
- assert False, b'pulling no heads?'
- if common:
- revset += b' - (::%ln)'
- args.append(common)
- nodes = [c.node() for c in repo.set(revset, *args)]
- markers = repo.obsstore.relevantmarkers(nodes)
- obsdata = StringIO()
- for chunk in obsolete.encodemarkers(markers, True):
- obsdata.write(chunk)
- obsdata.seek(0)
- return obsdata
-
-def srv_pullobsmarkers(repo, proto, others):
- """serves a binary stream of markers.
-
- Serves relevant to changeset between heads and common. The stream is prefix
- by a -string- representation of an integer. This integer is the size of the
- stream."""
- try:
- from mercurial import wireprototypes, wireprotov1server
- wireprototypes.pushres # force demandimport
- except (ImportError, AttributeError):
- from mercurial import wireproto as wireprototypes
- wireprotov1server = wireprototypes
- opts = wireprotov1server.options(b'', [b'heads', b'common'], others)
- for k, v in opts.items():
- if k in (b'heads', b'common'):
- opts[k] = wireprototypes.decodelist(v)
- obsdata = _getobsmarkersstream(repo, **opts)
- finaldata = StringIO()
- obsdata = obsdata.getvalue()
- finaldata.write(b'%20i' % len(obsdata))
- finaldata.write(obsdata)
- finaldata.seek(0)
- return wireprototypes.streamres(reader=finaldata, v1compressible=True)
-
abortmsg = b"won't exchange obsmarkers through pushkey"
hint = b"upgrade your client or server to use the bundle2 protocol"
--- a/hgext3rd/evolve/obshistory.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/obshistory.py Sun Feb 02 13:28:47 2020 +0100
@@ -42,6 +42,10 @@
item.default = True
efd.clear()
+@eh.extsetup
+def addtouchnoise(ui):
+ obsutil.METABLACKLIST.append(re.compile(br'^__touch-noise__$'))
+
@eh.command(
b'obslog|olog',
[(b'G', b'graph', True, _(b"show the revision DAG")),
@@ -50,7 +54,8 @@
(b'p', b'patch', False, _(b'show the patch between two obs versions')),
(b'f', b'filternonlocal', False, _(b'filter out non local commits')),
] + commands.formatteropts,
- _(b'hg olog [OPTION]... [[-r] REV]...'))
+ _(b'hg olog [OPTION]... [[-r] REV]...'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_NAVIGATION'))
def cmdobshistory(ui, repo, *revs, **opts):
"""show the obsolescence history of the specified revisions
@@ -85,55 +90,47 @@
revs = [b'.']
revs = scmutil.revrange(repo, revs)
+ # Use the default template unless the user provided one, but not if
+ # -f was given, because that doesn't work with templates yet. Note
+ # that --no-graph doesn't support -f (it ignores it), so we also
+ # don't use templating with --no-graph.
+ if not opts['template'] and not (opts['filternonlocal'] and opts['graph']):
+ opts['template'] = DEFAULT_TEMPLATE
+
if opts['graph']:
return _debugobshistorygraph(ui, repo, revs, opts)
revs.reverse()
_debugobshistoryrevs(ui, repo, revs, opts)
-def _successorsandmarkers(repo, ctx):
- """compute the raw data needed for computing obsfate
- Returns a list of dict, one dict per successors set
- """
- ssets = obsutil.successorssets(repo, ctx.node(), closest=True)
-
- # closestsuccessors returns an empty list for pruned revisions, remap it
- # into a list containing an empty list for future processing
- if ssets == []:
- ssets = [[]]
-
- # Try to recover pruned markers
- succsmap = repo.obsstore.successors
- fullsuccessorsets = [] # successor set + markers
- for sset in ssets:
- if sset:
- fullsuccessorsets.append(compat.wrap_succs(sset))
- else:
- # successorsset return an empty set() when ctx or one of its
- # successors is pruned.
- # In this case, walk the obs-markers tree again starting with ctx
- # and find the relevant pruning obs-makers, the ones without
- # successors.
- # Having these markers allow us to compute some information about
- # its fate, like who pruned this changeset and when.
-
- # XXX we do not catch all prune markers (eg rewritten then pruned)
- # (fix me later)
- foundany = False
- for mark in succsmap.get(ctx.node(), ()):
- if not mark[1]:
- foundany = True
- sset = compat._succs()
- sset.markers.add(mark)
- fullsuccessorsets.append(sset)
- if not foundany:
- fullsuccessorsets.append(compat._succs())
-
- values = []
- for sset in fullsuccessorsets:
- values.append({b'successors': sset, b'markers': sset.markers})
-
- return values
+TEMPLATE_MISSING_NODE = b"""{label("evolve.node evolve.missing_change_ctx", node|short)}"""
+TEMPLATE_PRESENT_NODE = b"""{label("evolve.node", node|short)} {label("evolve.rev", "({rev})")} {label("evolve.short_description", desc|firstline)}"""
+TEMPLATE_FIRST_LINE = b"""{if(rev, "%(presentnode)s", "%(missingnode)s")}""" % {
+ b"presentnode": TEMPLATE_PRESENT_NODE,
+ b"missingnode": TEMPLATE_MISSING_NODE
+}
+TEMPLATE_VERB = b"""{label("evolve.verb", verb)}"""
+TEMPLATE_SUCCNODES = b"""{label("evolve.node", join(succnodes % "{succnode|short}", ", "))}"""
+TEMPLATE_REWRITE = b"""{if(succnodes, "%(verb)s{if(effects, "({join(effects, ", ")})")} as %(succnodes)s", "pruned")}""" % {
+ b"verb": TEMPLATE_VERB,
+ b"succnodes": TEMPLATE_SUCCNODES
+}
+TEMPLATE_OPERATION = b"""{if(operation, "using {label("evolve.operation", operation)}")}"""
+TEMPLATE_USER = b"""by {label("evolve.user", user)}"""
+TEMPLATE_DATE = b"""{label("evolve.date", "({date(date, "%a %b %d %H:%M:%S %Y %1%2")})")}"""
+TEMPLATE_NOTE = b"""{if(note, "\n note: {label("evolve.note", note)}")}"""
+TEMPLATE_PATCH = b"""{if(patch, "{patch}")}{if(nopatchreason, "\n(No patch available, {nopatchreason})")}"""
+DEFAULT_TEMPLATE = (b"""%(firstline)s
+{markers %% " {separate(" ", "%(rewrite)s", "%(operation)s", "%(user)s", "%(date)s")}%(note)s{indent(descdiff, " ")}{indent("%(patch)s", " ")}\n"}
+""") % {
+ b"firstline": TEMPLATE_FIRST_LINE,
+ b"rewrite": TEMPLATE_REWRITE,
+ b"operation": TEMPLATE_OPERATION,
+ b"user": TEMPLATE_USER,
+ b"date": TEMPLATE_DATE,
+ b"note": TEMPLATE_NOTE,
+ b"patch": TEMPLATE_PATCH,
+}
class obsmarker_printer(compat.changesetprinter):
"""show (available) information about a node
@@ -178,23 +175,25 @@
succs = sorted(succs)
for successor in succs:
- _debugobshistorydisplaymarker(markerfm, successor,
+ _debugobshistorydisplaymarker(self.ui, markerfm, successor,
ctx.node(), self.repo,
self._includediff)
else:
- r = _successorsandmarkers(self.repo, ctx)
+ r = obsutil.successorsandmarkers(self.repo, ctx)
+ if r is None:
+ r = []
for succset in sorted(r):
markers = succset[b"markers"]
if not markers:
continue
successors = succset[b"successors"]
- _debugobshistorydisplaysuccsandmarkers(markerfm, successors, markers, ctx.node(), self.repo, self._includediff)
+ _debugobshistorydisplaysuccsandmarkers(self.ui, markerfm, successors, markers, ctx.node(), self.repo, self._includediff)
markerfm.end()
- markerfm.plain(b'\n')
+ fm.plain(b'\n')
fm.end()
self.hunk[ctx.node()] = self.ui.popbuffer()
@@ -454,8 +453,9 @@
markerfm = fm.nested(b"markers")
for successor in sorted(succs):
includediff = opts and opts.get("patch")
- _debugobshistorydisplaymarker(markerfm, successor, ctxnode, unfi, includediff)
+ _debugobshistorydisplaymarker(ui, markerfm, successor, ctxnode, unfi, includediff)
markerfm.end()
+ fm.plain(b'\n')
precs = precursors.get(ctxnode, ())
for p in sorted(precs):
@@ -477,12 +477,12 @@
shortdescription = shortdescription.splitlines()[0]
fm.startitem()
- fm.write(b'node', b'%s', bytes(ctx),
- label=b"evolve.node")
+ fm.context(ctx=ctx)
+ fm.data(node=ctx.hex())
+ fm.plain(b'%s' % bytes(ctx), label=b"evolve.node")
fm.plain(b' ')
- fm.write(b'rev', b'(%d)', ctx.rev(),
- label=b"evolve.rev")
+ fm.plain(b'(%d)' % ctx.rev(), label=b"evolve.rev")
fm.plain(b' ')
fm.write(b'shortdescription', b'%s', shortdescription,
@@ -490,19 +490,18 @@
fm.plain(b'\n')
def _debugobshistorydisplaymissingctx(fm, nodewithoutctx):
- hexnode = nodemod.short(nodewithoutctx)
fm.startitem()
- fm.write(b'node', b'%s', hexnode,
+ fm.data(node=nodemod.hex(nodewithoutctx))
+ fm.plain(nodemod.short(nodewithoutctx),
label=b"evolve.node evolve.missing_change_ctx")
fm.plain(b'\n')
-def _debugobshistorydisplaymarker(fm, marker, node, repo, includediff=False):
+def _debugobshistorydisplaymarker(ui, fm, marker, node, repo, includediff=False):
succnodes = marker[1]
date = marker[4]
metadata = dict(marker[3])
fm.startitem()
- fm.plain(b' ')
# Detect pruned revisions
if len(succnodes) == 0:
@@ -510,64 +509,29 @@
else:
verb = b'rewritten'
- fm.write(b'verb', b'%s', verb,
- label=b"evolve.verb")
-
- effectflag = metadata.get(b'ef1')
- if effectflag is not None:
- try:
- effectflag = int(effectflag)
- except ValueError:
- effectflag = None
- if effectflag:
- effect = []
+ fm.data(verb=verb)
- # XXX should be a dict
- if effectflag & DESCCHANGED:
- effect.append(b'description')
- if effectflag & METACHANGED:
- effect.append(b'meta')
- if effectflag & USERCHANGED:
- effect.append(b'user')
- if effectflag & DATECHANGED:
- effect.append(b'date')
- if effectflag & BRANCHCHANGED:
- effect.append(b'branch')
- if effectflag & PARENTCHANGED:
- effect.append(b'parent')
- if effectflag & DIFFCHANGED:
- effect.append(b'content')
-
- if effect:
- fmteffect = fm.formatlist(effect, b'effect', sep=b', ')
- fm.write(b'effect', b'(%s)', fmteffect)
+ effects = _markerseffects([marker])
+ if effects:
+ fmteffect = fm.formatlist(effects, b'effect', sep=b', ')
+ fm.write(b'effects', b'(%s)', fmteffect)
if len(succnodes) > 0:
- fm.plain(b' as ')
-
- shortsnodes = (nodemod.short(succnode) for succnode in sorted(succnodes))
- nodes = fm.formatlist(shortsnodes, b'succnodes', sep=b', ')
- fm.write(b'succnodes', b'%s', nodes,
- label=b"evolve.node")
+ hexnodes = (nodemod.hex(succnode) for succnode in sorted(succnodes))
+ nodes = fm.formatlist(hexnodes, b'succnode')
+ fm.write(b'succnodes', b'%s', nodes)
operation = metadata.get(b'operation')
if operation:
- fm.plain(b' using ')
- fm.write(b'operation', b'%s', operation, label=b"evolve.operation")
-
- fm.plain(b' by ')
+ fm.data(operation=operation)
- fm.write(b'user', b'%s', metadata[b'user'],
- label=b"evolve.user")
- fm.plain(b' ')
+ fm.data(user=metadata[b'user'])
- fm.write(b'date', b'(%s)', fm.formatdate(date),
- label=b"evolve.date")
+ fm.data(date=date)
# initial support for showing note
if metadata.get(b'note'):
- fm.plain(b'\n note: ')
- fm.write(b'note', b"%s", metadata[b'note'], label=b"evolve.note")
+ fm.data(note=metadata[b'note'])
# Patch display
if includediff is True:
@@ -592,15 +556,16 @@
def tolist(text):
return [text]
- fm.plain(b"\n")
+ ui.pushbuffer(labeled=True)
+ ui.write(b"\n")
for chunk, label in patch.difflabel(tolist, descriptionpatch):
chunk = chunk.strip(b'\t')
- if chunk and chunk != b'\n':
- fm.plain(b' ')
- fm.write(b'desc-diff', b'%s', chunk, label=label)
+ ui.write(chunk, label=label)
+ fm.write(b'descdiff', b'%s', ui.popbuffer())
# Content patch
+ ui.pushbuffer(labeled=True)
diffopts = patch.diffallopts(repo.ui, {})
matchfn = scmutil.matchall(repo)
firstline = True
@@ -608,23 +573,18 @@
for chunk, label in patch.diffui(repo, node, succ, matchfn,
opts=diffopts):
if firstline:
- fm.plain(b'\n')
+ ui.write(b'\n')
firstline = False
if linestart:
- fm.plain(b' ')
linestart = False
if chunk == b'\n':
linestart = True
- fm.write(b'patch', b'%s', chunk, label=label)
+ ui.write(chunk, label=label)
+ fm.data(patch=ui.popbuffer())
else:
- nopatch = b" (No patch available, %s)" % _patchavailable[1]
- fm.plain(b"\n")
- # TODO: should be in json too
- fm.plain(nopatch)
+ fm.data(nopatchreason=_patchavailable[1])
- fm.plain(b"\n")
-
-def _debugobshistorydisplaysuccsandmarkers(fm, succnodes, markers, node, repo, includediff=False):
+def _debugobshistorydisplaysuccsandmarkers(ui, fm, succnodes, markers, node, repo, includediff=False):
"""
This function is a duplication of _debugobshistorydisplaymarker modified
to accept multiple markers as input.
@@ -638,48 +598,21 @@
fm.write(b'verb', b'%s', verb,
label=b"evolve.verb")
- # Effect flag
- metadata = [dict(marker[3]) for marker in markers]
- ef1 = [data.get(b'ef1') for data in metadata]
-
- effectflag = 0
- for ef in ef1:
- if ef:
- effectflag |= int(ef)
-
- if effectflag:
- effect = []
-
- # XXX should be a dict
- if effectflag & DESCCHANGED:
- effect.append(b'description')
- if effectflag & METACHANGED:
- effect.append(b'meta')
- if effectflag & USERCHANGED:
- effect.append(b'user')
- if effectflag & DATECHANGED:
- effect.append(b'date')
- if effectflag & BRANCHCHANGED:
- effect.append(b'branch')
- if effectflag & PARENTCHANGED:
- effect.append(b'parent')
- if effectflag & DIFFCHANGED:
- effect.append(b'content')
-
- if effect:
- fmteffect = fm.formatlist(effect, b'effect', sep=b', ')
- fm.write(b'effect', b'(%s)', fmteffect)
+ effects = _markerseffects(markers)
+ if effects:
+ fmteffect = fm.formatlist(effects, b'effect', sep=b', ')
+ fm.write(b'effects', b'(%s)', fmteffect)
if len(succnodes) > 0:
fm.plain(b' as ')
shortsnodes = (nodemod.short(succnode) for succnode in sorted(succnodes))
- nodes = fm.formatlist(shortsnodes, b'succnodes', sep=b', ')
+ nodes = fm.formatlist(shortsnodes, b'succnode', sep=b', ')
fm.write(b'succnodes', b'%s', nodes,
label=b"evolve.node")
# Operations
- operations = compat.markersoperations(markers)
+ operations = obsutil.markersoperations(markers)
if operations:
fm.plain(b' using ')
fm.write(b'operation', b'%s', b", ".join(operations), label=b"evolve.operation")
@@ -687,13 +620,13 @@
fm.plain(b' by ')
# Users
- users = compat.markersusers(markers)
+ users = obsutil.markersusers(markers)
fm.write(b'user', b'%s', b", ".join(users),
label=b"evolve.user")
fm.plain(b' ')
# Dates
- dates = compat.markersdates(markers)
+ dates = obsutil.markersdates(markers)
if dates:
min_date = min(dates)
max_date = max(dates)
@@ -732,15 +665,18 @@
def tolist(text):
return [text]
- fm.plain(b"\n")
+ ui.pushbuffer(labeled=True)
+ ui.write(b"\n")
for chunk, label in patch.difflabel(tolist, descriptionpatch):
chunk = chunk.strip(b'\t')
if chunk and chunk != b'\n':
- fm.plain(b' ')
- fm.write(b'desc-diff', b'%s', chunk, label=label)
+ ui.write(b' ')
+ ui.write(chunk, label=label)
+ fm.write(b'descdiff', b'%s', ui.popbuffer())
# Content patch
+ ui.pushbuffer(labeled=True)
diffopts = patch.diffallopts(repo.ui, {})
matchfn = scmutil.matchall(repo)
firstline = True
@@ -748,50 +684,21 @@
for chunk, label in patch.diffui(repo, node, succ, matchfn,
opts=diffopts):
if firstline:
- fm.plain(b'\n')
+ ui.write(b'\n')
firstline = False
if linestart:
- fm.plain(b' ')
+ ui.write(b' ')
linestart = False
if chunk == b'\n':
linestart = True
- fm.write(b'patch', b'%s', chunk, label=label)
+ ui.write(chunk, label=label)
+ fm.write(b'patch', b'%s', ui.popbuffer())
else:
- nopatch = b" (No patch available, %s)" % _patchavailable[1]
- fm.plain(b"\n")
- # TODO: should be in json too
- fm.plain(nopatch)
+ fm.write(b'nopatchreason', b"\n (No patch available, %s)",
+ _patchavailable[1])
fm.plain(b"\n")
-# logic around storing and using effect flags
-DESCCHANGED = 1 << 0 # action changed the description
-METACHANGED = 1 << 1 # action change the meta
-PARENTCHANGED = 1 << 2 # action change the parent
-DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset
-USERCHANGED = 1 << 4 # the user changed
-DATECHANGED = 1 << 5 # the date changed
-BRANCHCHANGED = 1 << 6 # the branch changed
-
-METABLACKLIST = [
- re.compile(br'^__touch-noise__$'),
- re.compile(br'^branch$'),
- re.compile(br'^.*-source$'),
- re.compile(br'^.*_source$'),
- re.compile(br'^source$'),
-]
-
-def ismetablacklisted(metaitem):
- """ Check that the key of a meta item (extrakey, extravalue) does not
- match at least one of the blacklist pattern
- """
- metakey = metaitem[0]
- for pattern in METABLACKLIST:
- if pattern.match(metakey):
- return False
-
- return True
-
def _prepare_hunk(hunk):
"""Drop all information but the username and patch"""
cleanunk = []
@@ -810,40 +717,14 @@
return None
return _prepare_hunk(lines)
-def _getobsfate(successorssets):
- """ Compute a changeset obsolescence fate based on his successorssets.
- Successors can be the tipmost ones or the immediate ones.
- Returns one fate in the following list:
- - pruned
- - diverged
- - superseed
- - superseed_split
- """
-
- if len(successorssets) == 0:
- # The commit has been pruned
- return b'pruned'
- elif len(successorssets) > 1:
- return b'diverged'
- else:
- # No divergence, only one set of successors
- successors = successorssets[0]
-
- if len(successors) == 1:
- return b'superseed'
- else:
- return b'superseed_split'
-
-def _getobsfateandsuccs(repo, revnode, successorssets=None):
+def _getobsfateandsuccs(repo, revnode):
""" Return a tuple containing:
- - the reason a revision is obsolete (diverged, pruned or superseed)
+ - the reason a revision is obsolete (diverged, pruned or superseded)
- the list of successors short node if the revision is neither pruned
or has diverged
"""
- if successorssets is None:
- successorssets = obsutil.successorssets(repo, revnode)
-
- fate = _getobsfate(successorssets)
+ successorssets = obsutil.successorssets(repo, revnode)
+ fate = obsutil._getobsfate(successorssets)
# Apply node.short if we have no divergence
if len(successorssets) == 1:
@@ -855,42 +736,69 @@
return (fate, successors)
-def _successorsetdates(successorset, markers):
- """returns the max date and the min date of the markers list
- """
+EFFECTMAPPING = util.sortdict([
+ (obsutil.DESCCHANGED, b'description'),
+ (obsutil.METACHANGED, b'meta'),
+ (obsutil.USERCHANGED, b'user'),
+ (obsutil.DATECHANGED, b'date'),
+ (obsutil.BRANCHCHANGED, b'branch'),
+ (obsutil.PARENTCHANGED, b'parent'),
+ (obsutil.DIFFCHANGED, b'content'),
+])
- if not markers:
- return {}
-
- dates = [m[4] for m in markers]
+def _markerseffects(markers):
+ """ Return a list of effects as strings based on effect flags in markers
- return {
- b'min_date': min(dates),
- b'max_date': max(dates)
- }
-
-def _successorsetusers(successorset, markers):
- """ Returns a sorted list of markers users without duplicates
+ Return None if verb cannot be more precise than just "rewritten", i.e. when
+ markers collectively have more than one effect in the flags.
"""
- if not markers:
- return {}
+ metadata = [dict(marker[3]) for marker in markers]
+ ef1 = [data.get(b'ef1') for data in metadata]
+ effects = []
- # Check that user is present in meta
- markersmeta = [dict(m[3]) for m in markers]
- users = set(meta.get(b'user') for meta in markersmeta if meta.get(b'user'))
+ combined = 0
+ for ef in ef1:
+ if ef:
+ combined |= int(ef)
- return {b'users': sorted(users)}
+ if combined:
+ for key, value in EFFECTMAPPING.items():
+ if combined & key:
+ effects.append(value)
+
+ return effects
VERBMAPPING = {
- DESCCHANGED: b"reworded",
- METACHANGED: b"meta-changed",
- USERCHANGED: b"reauthored",
- DATECHANGED: b"date-changed",
- BRANCHCHANGED: b"branch-changed",
- PARENTCHANGED: b"rebased",
- DIFFCHANGED: b"amended"
+ obsutil.DESCCHANGED: b"reworded",
+ obsutil.METACHANGED: b"meta-changed",
+ obsutil.USERCHANGED: b"reauthored",
+ obsutil.DATECHANGED: b"date-changed",
+ obsutil.BRANCHCHANGED: b"branch-changed",
+ obsutil.PARENTCHANGED: b"rebased",
+ obsutil.DIFFCHANGED: b"amended"
}
+def _markerspreciseverb(markers):
+ """ Return a more precise verb based on effect flags in markers
+
+ Return None if verb cannot be more precise than just "rewritten", i.e. when
+ markers collectively have more than one effect in the flags.
+ """
+ metadata = [dict(marker[3]) for marker in markers]
+
+ if len(metadata) == 1 and metadata[0].get(b'fold-id') is not None:
+ return b'folded'
+
+ ef1 = [data.get(b'ef1') for data in metadata]
+ if all(ef1):
+ combined = 0
+ for ef in ef1:
+ combined |= int(ef)
+
+ # Combined will be in VERBMAPPING only if one bit is set
+ if combined in VERBMAPPING:
+ return VERBMAPPING[combined]
+
def _successorsetverb(successorset, markers):
""" Return the verb summarizing the successorset
"""
@@ -898,19 +806,7 @@
if not successorset:
verb = b'pruned'
elif len(successorset) == 1:
- # Check for effect flag
-
- metadata = [dict(marker[3]) for marker in markers]
- ef1 = [data.get(b'ef1') for data in metadata]
-
- if all(ef1):
- combined = 0
- for ef in ef1:
- combined |= int(ef)
-
- # Combined will be in VERBMAPPING only of one bit is set
- if combined in VERBMAPPING:
- verb = VERBMAPPING[combined]
+ verb = _markerspreciseverb(markers)
if verb is None:
verb = b'rewritten'
@@ -919,101 +815,6 @@
return {b'verb': verb}
# Use a more advanced version of obsfateverb that uses effect-flag
-if util.safehasattr(obsutil, 'obsfateverb'):
-
- @eh.wrapfunction(obsutil, 'obsfateverb')
- def obsfateverb(orig, *args, **kwargs):
- return _successorsetverb(*args, **kwargs)[b'verb']
-
-# Hijack callers of successorsetverb
-elif util.safehasattr(obsutil, 'obsfateprinter'):
-
- @eh.wrapfunction(obsutil, 'obsfateprinter')
- def obsfateprinter(orig, successors, markers, ui):
-
- def closure(successors):
- return _successorsetverb(successors, markers)[b'verb']
-
- if not util.safehasattr(obsutil, 'successorsetverb'):
- return orig(successors, markers, ui)
-
- # Save the old value
- old = obsutil.successorsetverb
-
- try:
- # Replace by own
- obsutil.successorsetverb = closure
-
- # Call the orig
- result = orig(successors, markers, ui)
-
- # And return result
- return result
- finally:
- # Replace the old one
- obsutil.successorsetverb = old
-
-FORMATSSETSFUNCTIONS = [
- _successorsetdates,
- _successorsetusers,
- _successorsetverb
-]
-
-def successorsetallmarkers(successorset, pathscache):
- """compute all successors of a successorset.
-
- pathscache must contains all successors starting from selected nodes
- or revision. This way, iterating on each successor, we can take all
- precursors and have the subgraph of all obsmarkers between roots to
- successors.
- """
-
- markers = set()
- seen = set()
-
- for successor in successorset:
- stack = [successor]
-
- while stack:
- element = stack.pop()
- seen.add(element)
- for prec, mark in pathscache.get(element, []):
- if prec not in seen:
- # Process element precursors
- stack.append(prec)
-
- if mark not in markers:
- markers.add(mark)
-
- return markers
-
-def preparesuccessorset(successorset, rawmarkers):
- """ For a successor set, get all related markers, compute the set of user,
- the min date and the max date
- """
- hex = nodemod.hex
-
- successorset = [hex(n) for n in successorset]
-
- # hex the binary nodes in the markers
- markers = []
- for m in rawmarkers:
- hexprec = hex(m[0])
- hexsucs = tuple(hex(n) for n in m[1])
- hexparents = None
- if m[5] is not None:
- hexparents = tuple(hex(n) for n in m[5])
- newmarker = (hexprec, hexsucs) + m[2:5] + (hexparents,) + m[6:]
- markers.append(newmarker)
-
- # Format basic data
- data = {
- b"successors": sorted(successorset),
- b"markers": sorted(markers)
- }
-
- # Call an extensible list of functions to override or add new data
- for function in FORMATSSETSFUNCTIONS:
- data.update(function(successorset, markers))
-
- return data
+@eh.wrapfunction(obsutil, 'obsfateverb')
+def obsfateverb(orig, *args, **kwargs):
+ return _successorsetverb(*args, **kwargs)[b'verb']
--- a/hgext3rd/evolve/rewind.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/rewind.py Sun Feb 02 13:28:47 2020 +0100
@@ -36,7 +36,8 @@
_(b"do not modify working directory during rewind")),
],
_(b'[--as-divergence] [--exact] [--keep] [--to REV]... [--from REV]...'),
- helpbasic=True)
+ helpbasic=True,
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_MANAGEMENT'))
def rewind(ui, repo, **opts):
"""rewind a stack of changesets to a previous state
--- a/hgext3rd/evolve/rewriteutil.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/rewriteutil.py Sun Feb 02 13:28:47 2020 +0100
@@ -21,7 +21,7 @@
lock as lockmod,
node,
obsolete,
- phases,
+ obsutil,
revset,
util,
)
@@ -76,6 +76,31 @@
msg %= (action, len(newunstable))
hint = _(b"see 'hg help evolution.instability'")
raise error.Abort(msg, hint=hint)
+ divrisk = revs_hascontentdivrisk(repo, revs)
+ allowdivergence = repo.ui.configbool(b'experimental',
+ b'evolution.allowdivergence')
+ if divrisk and not allowdivergence:
+ localdiv = repo[divrisk[0]]
+ otherdiv, base = repo[divrisk[1][0]], repo[divrisk[1][1]]
+ msg = _(b"%s of %s creates content-divergence "
+ b"with %s") % (action, localdiv, otherdiv)
+ if localdiv.rev() != base.rev():
+ msg += _(b', from %s') % base
+ hint = _(b"add --verbose for details or see "
+ b"'hg help evolution.instability'")
+ if repo.ui.verbose:
+ if localdiv.rev() != base.rev():
+ msg += _(b'\n changeset %s is an evolution of '
+ b'changeset %s') % (localdiv, base)
+ msg += _(b'\n changeset %s already have a successors as '
+ b'changeset %s\n'
+ b' rewriting changeset %s would create '
+ b'"content-divergence"\n'
+ b' set experimental.evolution.allowdivergence=True to '
+ b'overwrite this check') % (base, otherdiv, localdiv)
+ hint = _(b"see 'hg help evolution.instability' for details "
+ b"on content-divergence")
+ raise error.Abort(msg, hint=hint)
def bookmarksupdater(repo, oldid, tr):
"""Return a callable update(newid) updating the current bookmark
@@ -88,6 +113,14 @@
repo._bookmarks.applychanges(repo, tr, bmchanges)
return updatebookmarks
+def revs_hascontentdivrisk(repo, revs):
+ obsrevs = repo.revs(b'%ld and obsolete()', revs)
+ for r in obsrevs:
+ div = precheck_contentdiv(repo, repo[r])
+ if div:
+ return [r, div]
+ return []
+
def disallowednewunstable(repo, revs):
"""Check that editing <revs> will not create disallowed unstable
@@ -105,9 +138,6 @@
if len(roots) > 1:
raise error.Abort(_(b"cannot fold non-linear revisions "
b"(multiple roots given)"))
- root = repo[roots.first()]
- if root.phase() <= phases.public:
- raise error.Abort(_(b"cannot fold public revisions"))
heads = repo.revs(b'heads(%ld)', revs)
if len(heads) > 1:
raise error.Abort(_(b"cannot fold non-linear revisions "
@@ -124,6 +154,7 @@
hint = _(b'set experimental.evolution.allowdivergence=yes'
b' to allow folding them')
raise error.Abort(msg, hint=hint)
+ root = repo[roots.first()]
# root's p1 is already used as the target ctx p1
baseparents -= {root.p1().rev()}
p2 = repo[baseparents.first()]
@@ -254,3 +285,31 @@
return newid, created
finally:
lockmod.release(tr, lock, wlock)
+
+def precheck_contentdiv(repo, ctx):
+ """return divergent revision if rewriting an obsolete cset (ctx) will
+ create divergence"""
+ # We need to check two cases that can cause divergence:
+ # case 1: the rev being rewritten has a non-obsolete successor (easily
+ # detected by successorssets)
+ divergent = [] # contains [divergent_cset, common_precursor]
+ sset = obsutil.successorssets(repo, ctx.node())
+ nodivergencerisk = (len(sset) == 0
+ or (len(sset) == 1
+ and len(sset[0]) == 1
+ and repo[sset[0][0]].rev() == ctx.rev()
+ ))
+ if nodivergencerisk:
+ # case 2: one of the precursors of the rev being revived has a
+ # non-obsolete successor (we need divergentsets for this)
+ from . import evolvecmd
+ divsets = evolvecmd.divergentsets(repo, ctx)
+ if divsets:
+ nsuccset = divsets[0][b'divergentnodes']
+ divergent.append(nsuccset[0])
+ prec = divsets[0][b'commonprecursor']
+ divergent.append(prec)
+ else:
+ divergent.append(sset[0][0])
+ divergent.append(ctx.node())
+ return divergent
--- a/hgext3rd/evolve/templatekw.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/templatekw.py Sun Feb 02 13:28:47 2020 +0100
@@ -11,7 +11,6 @@
from . import (
error,
exthelper,
- obshistory
)
from mercurial import (
@@ -24,7 +23,7 @@
### template keywords
if util.safehasattr(templatekw, 'compatlist'):
- @eh.templatekeyword(b'instabilities', requires=set([b'ctx', b'templ']))
+ @eh.templatekeyword(b'instabilities', requires={b'ctx', b'templ'})
def showinstabilities(context, mapping):
"""List of strings. Evolution instabilities affecting the changeset
(zero or more of "orphan", "content-divergent" or "phase-divergent")."""
@@ -33,7 +32,7 @@
ctx.instabilities(),
plural=b'instabilities')
- @eh.templatekeyword(b'troubles', requires=set([b'ctx', b'templ']))
+ @eh.templatekeyword(b'troubles', requires={b'ctx', b'templ'})
def showtroubles(context, mapping): # legacy name for instabilities
ctx = context.resource(mapping, b'ctx')
return templatekw.compatlist(context, mapping, b'trouble',
@@ -87,192 +86,6 @@
except error.Abort: # no easy way to avoid ui raising Abort here :-/
return None
-def obsfatedefaulttempl(ui):
- """ Returns a dict with the default templates for obs fate
- """
- # Prepare templates
- verbtempl = b'{verb}'
- usertempl = b'{if(users, " by {join(users, ", ")}")}'
- succtempl = b'{if(successors, " as ")}{successors}' # Bypass if limitation
- datetempleq = b' (at {min_date|isodate})'
- datetemplnoteq = b' (between {min_date|isodate} and {max_date|isodate})'
- datetempl = b'{if(max_date, "{ifeq(min_date, max_date, "%s", "%s")}")}' % (datetempleq, datetemplnoteq)
-
- optionalusertempl = usertempl
- username = _getusername(ui)
- if username is not None:
- optionalusertempl = (b'{ifeq(join(users, "\0"), "%s", "", "%s")}'
- % (username, usertempl))
-
- # Assemble them
- return {
- b'obsfate_quiet': verbtempl + succtempl,
- b'obsfate': verbtempl + succtempl + optionalusertempl,
- b'obsfate_verbose': verbtempl + succtempl + usertempl + datetempl,
- }
-
-def obsfatedata(repo, ctx):
- """compute the raw data needed for computing obsfate
- Returns a list of dict
- """
- if not ctx.obsolete():
- return None
-
- successorssets, pathcache = closestsuccessors(repo, ctx.node())
-
- # closestsuccessors returns an empty list for pruned revisions, remap it
- # into a list containing en empty list for future processing
- if successorssets == []:
- successorssets = [[]]
-
- succsmap = repo.obsstore.successors
- fullsuccessorsets = [] # successor set + markers
- for sset in successorssets:
- if sset:
- markers = obshistory.successorsetallmarkers(sset, pathcache)
- fullsuccessorsets.append((sset, markers))
- else:
- # XXX we do not catch all prune markers (eg rewritten then pruned)
- # (fix me later)
- foundany = False
- for mark in succsmap.get(ctx.node(), ()):
- if not mark[1]:
- foundany = True
- fullsuccessorsets.append((sset, [mark]))
- if not foundany:
- fullsuccessorsets.append(([], []))
-
- values = []
- for sset, rawmarkers in fullsuccessorsets:
- raw = obshistory.preparesuccessorset(sset, rawmarkers)
- values.append(raw)
-
- return values
-
-def obsfatelineprinter(obsfateline, ui):
- quiet = ui.quiet
- verbose = ui.verbose
- normal = not verbose and not quiet
-
- # Build the line step by step
- line = []
-
- # Verb
- line.append(obsfateline[b'verb'])
-
- # Successors
- successors = obsfateline[b"successors"]
-
- if successors:
- fmtsuccessors = map(lambda s: s[:12], successors)
- line.append(b" as %s" % b", ".join(fmtsuccessors))
-
- # Users
- if (verbose or normal) and b'users' in obsfateline:
- users = obsfateline[b'users']
-
- if not verbose:
- # If current user is the only user, do not show anything if not in
- # verbose mode
- username = _getusername(ui)
- if len(users) == 1 and users[0] == username:
- users = None
-
- if users:
- line.append(b" by %s" % b", ".join(users))
-
- # Date
- if verbose:
- min_date = obsfateline[b'min_date']
- max_date = obsfateline[b'max_date']
-
- if min_date == max_date:
- fmtmin_date = util.datestr(min_date, b'%Y-%m-%d %H:%M %1%2')
- line.append(b" (at %s)" % fmtmin_date)
- else:
- fmtmin_date = util.datestr(min_date, b'%Y-%m-%d %H:%M %1%2')
- fmtmax_date = util.datestr(max_date, b'%Y-%m-%d %H:%M %1%2')
- line.append(b" (between %s and %s)" % (fmtmin_date, fmtmax_date))
-
- return b"".join(line)
-
-def obsfateprinter(obsfate, ui, prefix=b""):
- lines = []
- for raw in obsfate:
- lines.append(obsfatelineprinter(raw, ui))
-
- if prefix:
- lines = [prefix + line for line in lines]
-
- return b"\n".join(lines)
-
-if not util.safehasattr(templatekw, 'obsfateverb'): # <= hg-4.5
- @eh.templatekeyword(b"obsfatedata")
- def showobsfatedata(repo, ctx, **args):
- # Get the needed obsfate data
- values = obsfatedata(repo, ctx)
-
- if values is None:
- return templatekw.showlist(b"obsfatedata", [], args)
-
- return _showobsfatedata(repo, ctx, values, **args)
-
-def _showobsfatedata(repo, ctx, values, **args):
-
- # Format each successorset successors list
- for raw in values:
- # As we can't do something like
- # "{join(map(nodeshort, successors), ', '}" in template, manually
- # create a correct textual representation
- gen = b', '.join(n[:12] for n in raw[b'successors'])
-
- makemap = lambda x: {b'successor': x}
- joinfmt = lambda d: b"%s" % d[b'successor']
- raw[b'successors'] = templatekw._hybrid(gen, raw[b'successors'], makemap,
- joinfmt)
-
- # And then format them
- # Insert default obsfate templates
- args[b'templ'].cache.update(obsfatedefaulttempl(repo.ui))
-
- if repo.ui.quiet:
- name = b"obsfate_quiet"
- elif repo.ui.verbose:
- name = b"obsfate_verbose"
- elif repo.ui.debugflag:
- name = b"obsfate_debug"
- else:
- name = b"obsfate"
-
- # Format a single value
- def fmt(d):
- nargs = args.copy()
- nargs.update(d[name])
- templ = args[b'templ']
- # HG 4.6
- if hasattr(templ, "generate"):
- return templ.generate(name, nargs)
- else:
- return args[b'templ'](name, **nargs)
-
- # Generate a good enough string representation using templater
- gen = []
- for d in values:
- chunk = fmt({name: d})
- chunkstr = []
-
- # Empty the generator
- try:
- while True:
- chunkstr.append(next(chunk))
- except StopIteration:
- pass
-
- gen.append(b"".join(chunkstr))
- gen = b"; ".join(gen)
-
- return templatekw._hybrid(gen, values, lambda x: {name: x}, fmt)
-
# copy from mercurial.obsolete with a small change to stop at first known changeset.
def directsuccessorssets(repo, initialnode, cache=None):
--- a/hgext3rd/evolve/utility.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/evolve/utility.py Sun Feb 02 13:28:47 2020 +0100
@@ -13,10 +13,6 @@
from mercurial.node import nullrev
-from . import (
- compat,
-)
-
shorttemplate = b"[{label('evolve.rev', rev)}] {desc|firstline}\n"
stacktemplate = b"""[{label('evolve.rev', if(topicidx, "s{topicidx}", rev))}] {desc|firstline}\n"""
@@ -27,12 +23,6 @@
if important or verbose:
ui.status(message)
-def obsexcprg(ui, *args, **kwargs):
- topic = b'obsmarkers exchange'
- if ui.configbool(b'experimental', b'verbose-obsolescence-exchange'):
- topic = b'OBSEXC'
- compat.progress(ui, topic, *args, **kwargs)
-
def filterparents(parents):
"""filter nullrev parents
@@ -85,6 +75,8 @@
def __init__(self, successorssets):
self.successorssets = successorssets
+ self.divergenceflag = len(successorssets) > 1
+ self.splitflag = len(successorssets[0]) > 1
def builddependencies(repo, revs):
"""returns dependency graphs giving an order to solve instability of revs
@@ -126,13 +118,41 @@
ui.debug(b"stabilize target %s is plain dead,"
b" trying to stabilize on its parent\n" %
obs)
- obs = obs.parents()[0]
+ obs = obs.p1()
newer = obsutil.successorssets(repo, obs.node())
if len(newer) > 1 or len(newer[0]) > 1:
raise MultipleSuccessorsError(newer)
return repo[newer[0][0]].rev()
+def picksplitsuccessor(ui, repo, ctx, evolvecand):
+ """choose a successor of ctx from split targets
+
+ 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.
+
+ 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, '.')
+ """
+ targets = obsutil.successorssets(repo, ctx.node())[0]
+ assert targets
+ targetrevs = [repo[r].rev() for r in targets]
+ roots = repo.revs(b'roots(%ld)', targetrevs)
+ heads = repo.revs(b'heads(%ld)', targetrevs)
+ if len(roots) > 1 or len(heads) > 1:
+ cheader = (_(b"ancestor '%s' split over multiple topological"
+ b" branches.\nchoose an evolve destination:") %
+ evolvecand)
+ selectedrev = revselectionprompt(ui, repo, list(heads), cheader)
+ if selectedrev is None:
+ return (False, '.')
+ succ = repo[selectedrev]
+ else:
+ succ = repo[heads.first()]
+ return (True, repo[succ].rev())
+
def _successorrevs(repo, ctx):
try:
return {_singlesuccessor(repo, ctx)}
--- a/hgext3rd/pullbundle.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/pullbundle.py Sun Feb 02 13:28:47 2020 +0100
@@ -87,6 +87,7 @@
node as nodemod,
registrar,
scmutil,
+ ui as uimod,
util,
)
@@ -508,7 +509,7 @@
if 1 < min_cache:
repo.ui.write(b" not caching ranges smaller than %d changesets\n" % min_cache)
for i in range(count):
- repo.ui.progress(b'gathering data', i, total=count)
+ progress(repo.ui, b'gathering data', i, total=count)
outgoing = takeonesample(repo, actionrevs)
ranges = sliceoutgoing(repo, outgoing)
hitranges = 0
@@ -532,7 +533,7 @@
hitranges,
)
pullstats.append(stats)
- repo.ui.progress(b'gathering data', None)
+ progress(repo.ui, b'gathering data', None)
sizes = []
changesmissing = []
@@ -591,6 +592,7 @@
def takeonesample(repo, revs):
node = repo.changelog.node
+ revs = list(revs)
pulled = random.sample(revs, max(4, len(revs) // 1000))
pulled = repo.revs(b'%ld::%ld', pulled, pulled)
nodes = [node(r) for r in pulled]
@@ -610,19 +612,32 @@
b'max': data[-1],
}
-STATSFORMAT = b"""{name}:
- min: {min}
- 10%: {10%}
- 25%: {25%}
- 50%: {50%}
- 75%: {75%}
- 90%: {90%}
- 95%: {95%}
- max: {max}
+STATSFORMAT = b"""%(name)s:
+ min: %(min)r
+ 10%%: %(10%)r
+ 25%%: %(25%)r
+ 50%%: %(50%)r
+ 75%%: %(75%)r
+ 90%%: %(90%)r
+ 95%%: %(95%)r
+ max: %(max)r
"""
def fmtdist(name, data):
- return STATSFORMAT.format(name=name, **data)
+ data[b'name'] = name
+ return STATSFORMAT % data
+
+# hg <= 4.6 (bec1212eceaa)
+if util.safehasattr(uimod.ui, 'makeprogress'):
+ def progress(ui, topic, pos, item=b"", unit=b"", total=None):
+ progress = ui.makeprogress(topic, unit, total)
+ if pos is not None:
+ progress.update(pos, item=item)
+ else:
+ progress.complete()
+else:
+ def progress(ui, topic, pos, item=b"", unit=b"", total=None):
+ ui.progress(topic, pos, item, unit, total)
# nodemap.get and index.[has_node|rev|get_rev]
# hg <= 5.3 (02802fa87b74)
--- a/hgext3rd/serverminitopic.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/serverminitopic.py Sun Feb 02 13:28:47 2020 +0100
@@ -23,10 +23,11 @@
util,
)
+# hg <= 4.5 (b4d85bc122bd)
try:
- from mercurial import wireproto
+ from mercurial import wireproto # pytype: disable=import-error
wireproto.branchmap
-except ImportError: # <= hg-4.5
+except ImportError:
from mercurial import wireprotov1server as wireproto
if util.safehasattr(registrar, 'configitem'):
--- a/hgext3rd/topic/__init__.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/topic/__init__.py Sun Feb 02 13:28:47 2020 +0100
@@ -135,6 +135,7 @@
namespaces,
node,
obsolete,
+ obsutil,
patch,
phases,
pycompat,
@@ -187,7 +188,7 @@
b'topic.active': b'green',
}
-__version__ = b'0.17.3.dev'
+__version__ = b'0.18.0.dev'
testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0 5.1 5.2 5.3'
minimumhgversion = b'4.5'
@@ -384,14 +385,14 @@
return caps
def commit(self, *args, **kwargs):
- backup = self.ui.backupconfig(b'ui', b'allowemptycommit')
- try:
- if self.currenttopic != self[b'.'].topic():
- # bypass the core "nothing changed" logic
- self.ui.setconfig(b'ui', b'allowemptycommit', True)
+ configoverride = util.nullcontextmanager()
+ if self.currenttopic != self[b'.'].topic():
+ # bypass the core "nothing changed" logic
+ configoverride = self.ui.configoverride({
+ (b'ui', b'allowemptycommit'): True
+ })
+ with configoverride:
return super(topicrepo, self).commit(*args, **kwargs)
- finally:
- self.ui.restoreconfig(backup)
def commitctx(self, ctx, *args, **kwargs):
topicfilter = topicmap.topicfilter(self.filtername)
@@ -634,7 +635,8 @@
(b'', b'age', False, b'show when you last touched the topics'),
(b'', b'current', None, b'display the current topic only'),
] + commands.formatteropts,
- _(b'hg topics [OPTION]... [-r REV]... [TOPIC]'))
+ _(b'hg topics [OPTION]... [-r REV]... [TOPIC]'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_ORGANIZATION'))
def topics(ui, repo, topic=None, **opts):
"""View current topic, set current topic, change topic for a set of revisions, or see all topics.
@@ -777,7 +779,8 @@
(b'c', b'children', None,
_(b'display data about children outside of the stack'))
] + commands.formatteropts,
- _(b'hg stack [TOPIC]'))
+ _(b'hg stack [TOPIC]'),
+ **compat.helpcategorykwargs('CATEGORY_CHANGE_NAVIGATION'))
def cmdstack(ui, repo, topic=b'', **opts):
"""list all changesets in a topic and other information
@@ -1115,7 +1118,7 @@
user = repo[revs].user()
# looking on the markers also to get more information and accurate
# last touch time.
- obsmarkers = compat.getmarkers(repo, [repo[revs].node()])
+ obsmarkers = obsutil.getmarkers(repo, [repo[revs].node()])
for marker in obsmarkers:
rt = marker.date()
if rt[0] > maxtime[0]:
@@ -1258,14 +1261,13 @@
def checkt0(orig, ui, repo, node=None, rev=None, *args, **kwargs):
thezeros = set([b't0', b'b0', b's0'])
- backup = repo.ui.backupconfig(b'_internal', b'keep-topic')
- try:
- if node in thezeros or rev in thezeros:
- repo.ui.setconfig(b'_internal', b'keep-topic', b'yes',
- source=b'topic-extension')
+ configoverride = util.nullcontextmanager()
+ if node in thezeros or rev in thezeros:
+ configoverride = repo.ui.configoverride({
+ (b'_internal', b'keep-topic'): b'yes'
+ }, source=b'topic-extension')
+ with configoverride:
return orig(ui, repo, node=node, rev=rev, *args, **kwargs)
- finally:
- repo.ui.restoreconfig(backup)
def _fixrebase(loaded):
if not loaded:
--- a/hgext3rd/topic/compat.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/topic/compat.py Sun Feb 02 13:28:47 2020 +0100
@@ -8,25 +8,11 @@
from __future__ import absolute_import
from mercurial import (
- obsolete,
pycompat,
+ registrar,
util,
)
-getmarkers = None
-successorssets = None
-try:
- from mercurial import obsutil
- getmarkers = getattr(obsutil, 'getmarkers', None)
- successorssets = getattr(obsutil, 'successorssets', None)
-except ImportError:
- pass
-
-if getmarkers is None:
- getmarkers = obsolete.getmarkers
-if successorssets is None:
- successorssets = obsolete.successorssets
-
if pycompat.ispy3:
def branchmapitems(branchmap):
return branchmap.items()
@@ -36,6 +22,15 @@
return branchmap.iteritems()
# py3-transform: on
+# help category compatibility
+# hg <= 4.7 (c303d65d2e34)
+def helpcategorykwargs(categoryname):
+ """Backwards-compatible specification of the helpategory argument."""
+ category = getattr(registrar.command, categoryname, None)
+ if not category:
+ return {}
+ return {'helpcategory': category}
+
# nodemap.get and index.[has_node|rev|get_rev]
# hg <= 5.3 (02802fa87b74)
def getgetrev(cl):
--- a/hgext3rd/topic/discovery.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/topic/discovery.py Sun Feb 02 13:28:47 2020 +0100
@@ -17,10 +17,11 @@
compat,
)
+# hg <= 4.5 (b4d85bc122bd)
try:
- from mercurial import wireproto
+ from mercurial import wireproto # pytype: disable=import-error
wireproto.branchmap
-except (AttributeError, ImportError): # <= hg-4.5
+except (AttributeError, ImportError):
from mercurial import wireprotov1server as wireproto
def _headssummary(orig, pushop, *args, **kwargs):
--- a/hgext3rd/topic/evolvebits.py Sun Feb 02 13:25:23 2020 +0100
+++ b/hgext3rd/topic/evolvebits.py Sun Feb 02 13:28:47 2020 +0100
@@ -81,7 +81,7 @@
ui.debug(b"stabilize target %s is plain dead,"
b" trying to stabilize on its parent\n" %
obs)
- obs = obs.parents()[0]
+ obs = obs.p1()
newer = obsutil.successorssets(repo, obs.node())
if 1 < len(newer):
# divergence case
--- a/tests/test-amend.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-amend.t Sun Feb 02 13:28:47 2020 +0100
@@ -121,6 +121,9 @@
update: (current)
phases: 3 draft
+setting the user after we have performed the test with no username
+ $ HGUSER=test
+
Check the help
$ hg amend -h
hg amend [OPTION]... [FILE]...
@@ -170,3 +173,63 @@
$ hg amend --patch --extract
abort: cannot use both --patch and --extract
[255]
+
+ $ cd ..
+
+Check the pre-check logic for content-divergence
+ $ hg init precheckrepo
+ $ cd precheckrepo
+ $ echo a > a
+ $ hg ci -Am "added a"
+ adding a
+ $ echo newchanges > a
+ $ hg amend
+ $ hg up 0 --hidden -q
+ updated to hidden changeset 9092f1db7931
+ (hidden revision '9092f1db7931' was rewritten as: aafaf407b00d)
+ working directory parent is obsolete! (9092f1db7931)
+
+when rewritting an already rewritten changeset (i.e cset being rewritten will
+be the base of divergence)
+ $ hg amend -m "i am gonna create divergence"
+ abort: amend of 9092f1db7931 creates content-divergence with aafaf407b00d
+ (add --verbose for details or see 'hg help evolution.instability')
+ [255]
+ $ hg amend -m "i am gonna create divergence" --verbose
+ abort: amend of 9092f1db7931 creates content-divergence with aafaf407b00d
+ changeset 9092f1db7931 already have a successors as changeset aafaf407b00d
+ rewriting changeset 9092f1db7931 would create "content-divergence"
+ set experimental.evolution.allowdivergence=True to overwrite this check
+ (see 'hg help evolution.instability' for details on content-divergence)
+ [255]
+
+when rewritting a cset which has a predecessor with non-obsolete successor
+
+to prepare the repo
+1) create content-divergence
+2) remove divergence by pruning one of the divergent cset
+ $ echo edited_a > a
+ $ hg ci -m "edited a"
+ 1 new orphan changesets
+ $ hg debugobsolete $(hg id -ir 0 --debug) $(hg id -ir 2 --debug)
+ 1 new obsolescence markers
+ 2 new content-divergent changesets
+
+remove divergence by pruning one side of divergenence
+ $ hg debugobsolete $(hg id -ir 2 --debug)
+ 1 new obsolescence markers
+ obsoleted 1 changesets
+
+ $ hg evolve -l
+ $ hg amend -m "i am gonna create divergence"
+ abort: amend of f8c05838af90 creates content-divergence with aafaf407b00d, from 9092f1db7931
+ (add --verbose for details or see 'hg help evolution.instability')
+ [255]
+ $ hg amend -m "i am gonna create divergence" --verbose
+ abort: amend of f8c05838af90 creates content-divergence with aafaf407b00d, from 9092f1db7931
+ changeset f8c05838af90 is an evolution of changeset 9092f1db7931
+ changeset 9092f1db7931 already have a successors as changeset aafaf407b00d
+ rewriting changeset f8c05838af90 would create "content-divergence"
+ set experimental.evolution.allowdivergence=True to overwrite this check
+ (see 'hg help evolution.instability' for details on content-divergence)
+ [255]
--- a/tests/test-evolve-content-divergent-basic.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-basic.t Sun Feb 02 13:28:47 2020 +0100
@@ -21,6 +21,8 @@
> unified = 0
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline} [{instabilities}]\n
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
--- a/tests/test-evolve-content-divergent-corner-cases.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-corner-cases.t Sun Feb 02 13:28:47 2020 +0100
@@ -21,6 +21,8 @@
> unified = 0
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline} [{instabilities}]\n
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
--- a/tests/test-evolve-content-divergent-first-changeset.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-first-changeset.t Sun Feb 02 13:28:47 2020 +0100
@@ -1,6 +1,11 @@
$ . $TESTDIR/testlib/pythonpath.sh
- $ echo "[extensions]" >> $HGRCPATH
- $ echo "evolve=" >> $HGRCPATH
+ $ cat >> $HGRCPATH << EOF
+ > [extensions]
+ > evolve=
+ > [experimental]
+ > evolution.allowdivergence = True
+ > EOF
+
This test file tests the case of content-divergence resolution of changesets
that have the null revision as the parent.
--- a/tests/test-evolve-content-divergent-interrupted.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-interrupted.t Sun Feb 02 13:28:47 2020 +0100
@@ -24,6 +24,8 @@
> publish = False
> [alias]
> glog = log -GT "{rev}:{node|short} {desc}\n ({bookmarks}) {phase}"
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
--- a/tests/test-evolve-content-divergent-meta.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-meta.t Sun Feb 02 13:28:47 2020 +0100
@@ -12,8 +12,11 @@
> glog = log -GT "{rev}:{node|short} {desc|firstline}\n {phase} {instabilities}\n\n"
> [phases]
> publish = False
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> rebase =
+ > strip =
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
@@ -157,3 +160,213 @@
user: baruser, foouser
$ cd ..
+
+Test the content-divergence resolution involving date update
+------------------------------------------------------------
+
+ $ hg init divergingdate
+ $ cd divergingdate
+ $ unset HGUSER
+ $ echo "[ui]" >> ./.hg/hgrc
+ $ echo "username = test" >> ./.hg/hgrc
+
+ $ echo hi > r0
+ $ hg ci -qAm 'add r0'
+ $ echo hi > foo.txt
+ $ hg ci -qAm 'add foo.txt'
+ $ hg metaedit -r . -d '0 2'
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+date: updated on both side to the same value
+
+ $ echo hi > bar.txt
+ $ hg add -q bar.txt
+ $ hg amend -q
+ $ hg metaedit -r 1 -d '0 1' --hidden
+ 2 new content-divergent changesets
+ $ hg log -G
+ * changeset: 4:c17bf400a278
+ | tag: tip
+ | parent: 0:a24ed8ad918c
+ | user: test
+ | date: Wed Dec 31 23:59:59 1969 -0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ | @ changeset: 3:a25dd7af6cf6
+ |/ parent: 0:a24ed8ad918c
+ | user: test
+ | date: Wed Dec 31 23:59:58 1969 -0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ o changeset: 0:a24ed8ad918c
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add r0
+
+ $ hg evolve --list --rev .
+ a25dd7af6cf6: add foo.txt
+ content-divergent: c17bf400a278 (draft) (precursor cc71ffbc7c00)
+
+ $ hg log --hidden -r cc71ffbc7c00 -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 1 cc71ffbc7c00 1970-01-01 00:00 +0000: date-changed using metaedit as 4:c17bf400a278; date-changed using metaedit as 2:0065551bd38f
+ $ hg log -r 'desc("add foo.txt")' -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 3 a25dd7af6cf6 1969-12-31 23:59 -0000:
+ 4 c17bf400a278 1969-12-31 23:59 -0000:
+ $ hg evolve --content-divergent
+ merge:[3] add foo.txt
+ with: [4] add foo.txt
+ base: [1] add foo.txt
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 6c144bb30333
+ $ hg log -r 'desc("add foo.txt")' -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 5 6c144bb30333 1969-12-31 23:59 -0000:
+
+date: updated one one side to an older value
+
+ $ hg strip .
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/divergingdate/.hg/strip-backup/6c144bb30333-72e26b88-backup.hg
+ 2 new content-divergent changesets
+ $ hg up tip
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg amend --date "0 3"
+ $ hg log -G
+ @ changeset: 5:6189a9adfff0
+ | tag: tip
+ | parent: 0:a24ed8ad918c
+ | user: test
+ | date: Wed Dec 31 23:59:57 1969 -0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ | * changeset: 3:a25dd7af6cf6
+ |/ parent: 0:a24ed8ad918c
+ | user: test
+ | date: Wed Dec 31 23:59:58 1969 -0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ o changeset: 0:a24ed8ad918c
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add r0
+
+ $ hg evolve --list -r .
+ 6189a9adfff0: add foo.txt
+ content-divergent: a25dd7af6cf6 (draft) (precursor cc71ffbc7c00)
+
+ $ hg log -r cc71ffbc7c00+6189a9adfff0+a25dd7af6cf6 --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 1 cc71ffbc7c00 1970-01-01 00:00 +0000: date-changed using metaedit as 4:c17bf400a278; date-changed using metaedit as 2:0065551bd38f
+ 5 6189a9adfff0 1969-12-31 23:59 -0000:
+ 3 a25dd7af6cf6 1969-12-31 23:59 -0000:
+ $ hg evolve --content-divergent
+ merge:[3] add foo.txt
+ with: [5] add foo.txt
+ base: [1] add foo.txt
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 806d0024c04d
+ $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 6 806d0024c04d 1969-12-31 23:59 -0000:
+
+date: updated one side to an newer value
+
+ $ hg strip .
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/divergingdate/.hg/strip-backup/806d0024c04d-24cb28ad-backup.hg
+ 2 new content-divergent changesets
+ $ hg update a25dd7af6cf6 --hidden
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg amend --date "120 0"
+ $ hg log -G
+ @ changeset: 6:5199d0bc13d4
+ | tag: tip
+ | parent: 0:a24ed8ad918c
+ | user: test
+ | date: Thu Jan 01 00:02:00 1970 +0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ | * changeset: 5:6189a9adfff0
+ |/ parent: 0:a24ed8ad918c
+ | user: test
+ | date: Wed Dec 31 23:59:57 1969 -0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ o changeset: 0:a24ed8ad918c
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add r0
+
+ $ hg evolve --list -r .
+ 5199d0bc13d4: add foo.txt
+ content-divergent: 6189a9adfff0 (draft) (precursor cc71ffbc7c00)
+
+ $ hg up 6189a9adfff0
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg log -r cc71ffbc7c00+6189a9adfff0+5199d0bc13d4 --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 1 cc71ffbc7c00 1970-01-01 00:00 +0000: date-changed using metaedit as 4:c17bf400a278; date-changed using metaedit as 2:0065551bd38f
+ 5 6189a9adfff0 1969-12-31 23:59 -0000:
+ 6 5199d0bc13d4 1970-01-01 00:02 +0000:
+ $ hg evolve --content-divergent
+ merge:[5] add foo.txt
+ with: [6] add foo.txt
+ base: [1] add foo.txt
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 51e08ac59670
+ $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 7 51e08ac59670 1970-01-01 00:02 +0000:
+
+date: updated each side to a different value, newer should win
+
+ $ hg strip .
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/divergingdate/.hg/strip-backup/51e08ac59670-d8a3c2ca-backup.hg
+ 2 new content-divergent changesets
+ $ hg up tip
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg amend --date "235 0"
+ $ hg update 6189a9adfff0 --hidden
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg amend --date "784 0"
+ $ hg log -G
+ @ changeset: 8:75254fb3164b
+ | tag: tip
+ | parent: 0:a24ed8ad918c
+ | user: test
+ | date: Thu Jan 01 00:13:04 1970 +0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ | * changeset: 7:5421a7efcc6e
+ |/ parent: 0:a24ed8ad918c
+ | user: test
+ | date: Thu Jan 01 00:03:55 1970 +0000
+ | instability: content-divergent
+ | summary: add foo.txt
+ |
+ o changeset: 0:a24ed8ad918c
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: add r0
+
+ $ hg evolve --list -r .
+ 75254fb3164b: add foo.txt
+ content-divergent: 5421a7efcc6e (draft) (precursor cc71ffbc7c00)
+
+ $ hg log -r 6189a9adfff0+5421a7efcc6e+75254fb3164b --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 5 6189a9adfff0 1969-12-31 23:59 -0000: date-changed using amend as 8:75254fb3164b
+ 7 5421a7efcc6e 1970-01-01 00:03 +0000:
+ 8 75254fb3164b 1970-01-01 00:13 +0000:
+ $ hg evolve --content-divergent
+ merge:[7] add foo.txt
+ with: [8] add foo.txt
+ base: [1] add foo.txt
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at ab7c0a425dc9
+ $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
+ 9 ab7c0a425dc9 1970-01-01 00:13 +0000:
+
+ $ cd ..
--- a/tests/test-evolve-content-divergent-stack.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-content-divergent-stack.t Sun Feb 02 13:28:47 2020 +0100
@@ -10,6 +10,7 @@
> [phases]
> publish = False
> [extensions]
+ > strip =
> rebase =
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
@@ -348,6 +349,386 @@
| () [default] draft
o 0:8fa14d15e168 added hgignore
() [default] draft
+
+when "divergent" and "other" both hit merge conflict in relocating
+------------------------------------------------------------------
+
+ $ hg strip 14: --hidden
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/74fbf3e6a0b6-f3612603-backup.hg
+ 8 new content-divergent changesets
+
+Prepare repo to have merge conflicts
+ $ hg up -r "max(desc('added a'))"
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg evolve -r . --content-divergent
+ merge:[10] added a
+ with: [5] watbar to a
+ base: [1] added a
+ rebasing "other" content-divergent changeset 8e222f257bbf on 2228e3b74514
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ 6 new orphan changesets
+ working directory is now at 74fbf3e6a0b6
+ $ echo b_conflict > b
+ $ hg amend -A
+ adding b
+
+Let's try to evolve stack
+ $ hg evolve --content-divergent
+ merge:[11] added b
+ with: [6] added b
+ base: [2] added b
+ rebasing "divergent" content-divergent changeset 6eb54b5af3fb on 119989a4317e
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+
+ $ echo b > b
+ $ hg res -m
+ (no more unresolved files)
+ continue: hg evolve --continue
+ $ hg evolve --continue
+ evolving 11:6eb54b5af3fb "added b"
+ rebasing "other" content-divergent changeset d5f148423c16 on 119989a4317e
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+
+ $ echo b > b
+ $ hg res -m
+ (no more unresolved files)
+ continue: hg evolve --continue
+ $ hg evolve --continue
+ evolving 6:d5f148423c16 "added b"
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ merge:[12] added c
+ with: [7] added c
+ base: [3] added c
+ rebasing "divergent" content-divergent changeset 8ed612937375 on 646bd3372ee7
+ rebasing "other" content-divergent changeset 3ce4be6d8e5e on 646bd3372ee7
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ merge:[13] added d
+ with: [8] added d
+ base: [4] added d
+ rebasing "divergent" content-divergent changeset d45f050514c2 on 67abc597e636
+ rebasing "other" content-divergent changeset c72d2885eb51 on 67abc597e636
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 119989a4317e
+ $ hg glog
+ o 25:5e2572194f59 added d
+ | () [default] draft
+ o 22:67abc597e636 added c
+ | () [default] draft
+ o 19:646bd3372ee7 added b
+ | () [default] draft
+ @ 16:119989a4317e watbar to a
+ | () [default] draft
+ o 9:2228e3b74514 add newfile
+ | () [default] draft
+ o 0:8fa14d15e168 added hgignore
+ () [default] draft
+
+when relocating "other" hit merge conflict but not "divergent"
+--------------------------------------------------------------
+ $ hg strip 14: --hidden
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/stackrepo1/.hg/strip-backup/74fbf3e6a0b6-15474722-backup.hg
+ 8 new content-divergent changesets
+
+Insert conflicting changes in between the stack of content-div csets
+ $ hg up -r "max(desc('added b'))"
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ echo b_diverging_local > b
+ $ hg amend
+ 2 new orphan changesets
+ $ hg evolve
+ move:[12] added c
+ atop:[14] added b
+ move:[13] added d
+ $ hg up -r d5f148423c16
+ 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo b_diverging_other > b
+ $ hg amend
+ 2 new orphan changesets
+ $ hg evolve
+ move:[7] added c
+ atop:[17] added b
+ move:[8] added d
+
+ $ hg log -r tip
+ changeset: 19:c351be27f199
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ instability: content-divergent
+ summary: added d
+
+Now let's try to evolve stack
+ $ hg evolve --content-divergent
+ merge:[10] added a
+ with: [5] watbar to a
+ base: [1] added a
+ rebasing "other" content-divergent changeset 8e222f257bbf on 2228e3b74514
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ merge:[14] added b
+ with: [17] added b
+ base: [2] added b
+ rebasing "divergent" content-divergent changeset 2a955e808c53 on 74fbf3e6a0b6
+ rebasing "other" content-divergent changeset 509103439e5e on 74fbf3e6a0b6
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ 4 new orphan changesets
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+
+As now we have interrupted evolution of stack of content-divergent cset (when
+relocation of "divergent" also included) let's test --abort and --stop
+test --abort:
+ $ hg evolve --abort
+ 2 new content-divergent changesets
+ evolve aborted
+ working directory is now at 509103439e5e
+
+confirm that tip is same as it was before we started --content-div resolution
+ $ hg log -r tip
+ changeset: 19:c351be27f199
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ instability: content-divergent
+ summary: added d
+
+test --stop:
+ $ hg log -G
+ * changeset: 19:c351be27f199
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | instability: content-divergent
+ | summary: added d
+ |
+ * changeset: 18:eaf34afe4df3
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | instability: content-divergent
+ | summary: added c
+ |
+ @ changeset: 17:509103439e5e
+ | parent: 5:8e222f257bbf
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | instability: content-divergent
+ | summary: added b
+ |
+ | * changeset: 16:91c8ccb9c241
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: content-divergent
+ | | summary: added d
+ | |
+ | * changeset: 15:48b0f803817a
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: content-divergent
+ | | summary: added c
+ | |
+ | * changeset: 14:2a955e808c53
+ | | parent: 10:c04ff147ef79
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: content-divergent
+ | | summary: added b
+ | |
+ | * changeset: 10:c04ff147ef79
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: content-divergent
+ | | summary: added a
+ | |
+ | o changeset: 9:2228e3b74514
+ | | parent: 0:8fa14d15e168
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | summary: add newfile
+ | |
+ * | changeset: 5:8e222f257bbf
+ |/ parent: 0:8fa14d15e168
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | instability: content-divergent
+ | summary: watbar to a
+ |
+ o changeset: 0:8fa14d15e168
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: added hgignore
+
+ $ hg evolve --content-divergent
+ merge:[10] added a
+ with: [5] watbar to a
+ base: [1] added a
+ rebasing "other" content-divergent changeset 8e222f257bbf on 2228e3b74514
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ merge:[14] added b
+ with: [17] added b
+ base: [2] added b
+ rebasing "divergent" content-divergent changeset 2a955e808c53 on 74fbf3e6a0b6
+ rebasing "other" content-divergent changeset 509103439e5e on 74fbf3e6a0b6
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ 4 new orphan changesets
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+
+ $ hg evolve --stop
+ 2 new orphan changesets
+ stopped the interrupted evolve
+ working directory is now at 2a955e808c53
+ $ hg log -G
+ o changeset: 21:74fbf3e6a0b6
+ | tag: tip
+ | parent: 9:2228e3b74514
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: watbar to a
+ |
+ | * changeset: 19:c351be27f199
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: orphan, content-divergent
+ | | summary: added d
+ | |
+ | * changeset: 18:eaf34afe4df3
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: orphan, content-divergent
+ | | summary: added c
+ | |
+ | * changeset: 17:509103439e5e
+ | | parent: 5:8e222f257bbf
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | instability: orphan, content-divergent
+ | | summary: added b
+ | |
+ | | * changeset: 16:91c8ccb9c241
+ | | | user: test
+ | | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | instability: orphan, content-divergent
+ | | | summary: added d
+ | | |
+ | | * changeset: 15:48b0f803817a
+ | | | user: test
+ | | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | instability: orphan, content-divergent
+ | | | summary: added c
+ | | |
+ | | @ changeset: 14:2a955e808c53
+ | | | parent: 10:c04ff147ef79
+ | | | user: test
+ | | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | instability: orphan, content-divergent
+ | | | summary: added b
+ | | |
+ +---x changeset: 10:c04ff147ef79
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten using evolve as 21:74fbf3e6a0b6
+ | | summary: added a
+ | |
+ o | changeset: 9:2228e3b74514
+ | | parent: 0:8fa14d15e168
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | summary: add newfile
+ | |
+ | x changeset: 5:8e222f257bbf
+ |/ parent: 0:8fa14d15e168
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rebased using evolve as 21:74fbf3e6a0b6
+ | summary: watbar to a
+ |
+ o changeset: 0:8fa14d15e168
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: added hgignore
+
+ $ hg obslog -r 'desc("watbar to a")' --all
+ o 74fbf3e6a0b6 (21) watbar to a
+ |\
+ x | 186bdc2cdfa2 (20) watbar to a
+ | | rewritten as 74fbf3e6a0b6 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+ | |
+ | x c04ff147ef79 (10) added a
+ | | rewritten(description, content) as 74fbf3e6a0b6 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+ | |
+ x | 8e222f257bbf (5) watbar to a
+ |/ rewritten(parent) as 186bdc2cdfa2 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+ |
+ x c7586e2a9264 (1) added a
+ rewritten(description, content) as 8e222f257bbf using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+ rewritten(parent) as c04ff147ef79 using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+
+ $ hg obslog -r 'desc("added b")' --all
+ @ 2a955e808c53 (14) added b
+ |
+ | * 509103439e5e (17) added b
+ | |
+ x | 6eb54b5af3fb (11) added b
+ | | rewritten(content) as 2a955e808c53 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+ | |
+ | x d5f148423c16 (6) added b
+ |/ rewritten(content) as 509103439e5e using amend by test (Thu Jan 01 00:00:00 1970 +0000)
+ |
+ x b1661037fa25 (2) added b
+ rewritten(parent) as 6eb54b5af3fb using rebase by test (Thu Jan 01 00:00:00 1970 +0000)
+ rewritten(parent) as d5f148423c16 using evolve by test (Thu Jan 01 00:00:00 1970 +0000)
+
+
+Again, let's evolve the stack
+ $ hg evolve --content-divergent
+ merge:[14] added b
+ with: [17] added b
+ base: [2] added b
+ rebasing "divergent" content-divergent changeset 2a955e808c53 on 74fbf3e6a0b6
+ rebasing "other" content-divergent changeset 509103439e5e on 74fbf3e6a0b6
+ merging b
+ warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+
+ $ echo foo > b
+ $ hg res -m
+ (no more unresolved files)
+ continue: hg evolve --continue
+ $ hg evolve --continue
+ merge:[15] added c
+ with: [18] added c
+ base: [3] added c
+ rebasing "divergent" content-divergent changeset 48b0f803817a on 4e29776e83a5
+ rebasing "other" content-divergent changeset eaf34afe4df3 on 4e29776e83a5
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ merge:[16] added d
+ with: [19] added d
+ base: [4] added d
+ rebasing "divergent" content-divergent changeset 91c8ccb9c241 on 77126af93a25
+ rebasing "other" content-divergent changeset c351be27f199 on 77126af93a25
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 4e29776e83a5
+
+ $ hg evolve -l
+
$ cd ..
Make sure that content-divergent resolution doesn't undo a change (issue6203)
--- a/tests/test-evolve-continue.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-continue.t Sun Feb 02 13:28:47 2020 +0100
@@ -434,3 +434,31 @@
M c
A d
? c.orig
+
+ $ cd ..
+ $ hg init transitive-renames
+ $ cd transitive-renames
+ $ echo 1 > a
+ $ echo 1 > b
+ $ hg ci -Aqm initial
+ $ echo 2 > a
+ $ hg mv b c
+ $ hg ci -m 'rename b to c'
+ $ echo 3 > a
+ $ hg mv c d
+ $ hg ci -m 'rename c to d'
+ $ hg prev -q
+ $ echo 2b > a
+ $ hg amend -q
+ 1 new orphan changesets
+ $ hg ev -q
+ warning: conflicts while merging a! (edit, then use 'hg resolve --mark')
+ unresolved merge conflicts
+ (see 'hg help evolve.interrupted')
+ [1]
+ $ hg st -C
+ M a
+ A d
+ c
+ R c
+ ? a.orig
--- a/tests/test-evolve-cycles.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-cycles.t Sun Feb 02 13:28:47 2020 +0100
@@ -300,21 +300,20 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "0da815c333f6"
+ "0da815c333f6364b46c86b0a897c00eb617397b6"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "868d2e0eb19c",
- "rev": 4,
+ "node": "868d2e0eb19c2b55a2894d37e1c435c221384d48",
"shortdescription": "D"
},
{
@@ -324,21 +323,20 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "868d2e0eb19c"
+ "868d2e0eb19c2b55a2894d37e1c435c221384d48"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "d9f908fde1a1",
- "rev": 6,
+ "node": "d9f908fde1a10ad198a462a3ec8b440bb397fc9c",
"shortdescription": "F"
},
{
@@ -348,21 +346,20 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "d9f908fde1a1"
+ "d9f908fde1a10ad198a462a3ec8b440bb397fc9c"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "0da815c333f6",
- "rev": 5,
+ "node": "0da815c333f6364b46c86b0a897c00eb617397b6",
"shortdescription": "E"
},
{
@@ -372,22 +369,21 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "2a34000d3544",
- "868d2e0eb19c"
+ "2a34000d35446022104f7a091c06fe21ff2b5912",
+ "868d2e0eb19c2b55a2894d37e1c435c221384d48"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "a8df460dbbfe",
- "rev": 3,
+ "node": "a8df460dbbfe9ef0c1e5ab4fff02e9514672e379",
"shortdescription": "C"
},
{
@@ -397,21 +393,20 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "a8df460dbbfe"
+ "a8df460dbbfe9ef0c1e5ab4fff02e9514672e379"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "c473644ee0e9",
- "rev": 2,
+ "node": "c473644ee0e988d7f537e31423831bbc409f12f7",
"shortdescription": "B"
},
{
@@ -421,21 +416,20 @@
*, (glob)
0
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "prune",
"succnodes": [
- "c473644ee0e9"
+ "c473644ee0e988d7f537e31423831bbc409f12f7"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "2a34000d3544",
- "rev": 1,
+ "node": "2a34000d35446022104f7a091c06fe21ff2b5912",
"shortdescription": "A"
}
]
--- a/tests/test-evolve-issue5958.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-issue5958.t Sun Feb 02 13:28:47 2020 +0100
@@ -22,8 +22,6 @@
(Make changes in unrelated files so that we don't have any merge conflicts
during the rebase, but the two touched revisions aren't identical)
-date: updated on both side to the same value
-
$ echo hi > bar.txt
$ hg add -q bar.txt
$ hg amend -q
@@ -81,15 +79,6 @@
rewritten(date) as 0065551bd38f using metaedit by test (Thu Jan 01 00:00:00 1970 +0000)
rewritten(date) as c17bf400a278 using metaedit by test (Thu Jan 01 00:00:00 1970 +0000)
- $ hg evolve --list --rev .
- 08bc7ba82799: add foo.txt
- content-divergent: c17bf400a278 (draft) (precursor cc71ffbc7c00)
-
- $ hg log --hidden -r cc71ffbc7c00 -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 1 cc71ffbc7c00 1970-01-01 00:00 +0000: date-changed using metaedit as 4:c17bf400a278; date-changed using metaedit as 2:0065551bd38f
- $ hg log -r 'desc("add foo.txt")' -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 4 c17bf400a278 1969-12-31 23:59 -0000:
- 6 08bc7ba82799 1969-12-31 23:59 -0000:
$ hg evolve --content-divergent
merge:[6] add foo.txt
with: [4] add foo.txt
@@ -97,160 +86,3 @@
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1 new orphan changesets
working directory is now at 459c64f7eaad
- $ hg log -r 'desc("add foo.txt")' -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 4 c17bf400a278 1969-12-31 23:59 -0000: rewritten using evolve as 7:459c64f7eaad
- 7 459c64f7eaad 1969-12-31 23:59 -0000:
-
-date: updated one one side to an older value
-
- $ hg evolve -r .
- move:[7] add foo.txt
- atop:[0] add r0
- working directory is now at 545776b4e79f
- $ hg update --hidden --rev 'predecessors(.)'
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updated to hidden changeset 459c64f7eaad
- (hidden revision '459c64f7eaad' was rewritten as: 545776b4e79f)
- working directory parent is obsolete! (459c64f7eaad)
- (use 'hg evolve' to update to its successor: 545776b4e79f)
- $ hg amend --date "0 3"
- 1 new orphan changesets
- 2 new content-divergent changesets
- $ hg rebase -r . -d 0
- rebasing 9:c117f15338e6 "add foo.txt" (tip)
- $ hg log -G
- @ changeset: 10:7a09c7a39546
- | tag: tip
- | parent: 0:a24ed8ad918c
- | user: test
- | date: Wed Dec 31 23:59:57 1969 -0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- | * changeset: 8:545776b4e79f
- |/ parent: 0:a24ed8ad918c
- | user: test
- | date: Wed Dec 31 23:59:58 1969 -0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- o changeset: 0:a24ed8ad918c
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: add r0
-
- $ hg evolve --list -r .
- 7a09c7a39546: add foo.txt
- content-divergent: 545776b4e79f (draft) (precursor 459c64f7eaad)
-
- $ hg log -r 459c64f7eaad+7a09c7a39546+545776b4e79f --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 7 459c64f7eaad 1969-12-31 23:59 -0000: date-changed using amend as 9:c117f15338e6; rebased using evolve as 8:545776b4e79f
- 10 7a09c7a39546 1969-12-31 23:59 -0000:
- 8 545776b4e79f 1969-12-31 23:59 -0000:
- $ hg evolve --content-divergent
- merge:[8] add foo.txt
- with: [10] add foo.txt
- base: [7] add foo.txt
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory is now at 39c4200c0d94
- $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 11 39c4200c0d94 1969-12-31 23:59 -0000:
-
-date: updated one side to an newer value
-
- $ hg update --hidden --rev 'predecessors(.)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updated to hidden changeset 7a09c7a39546
- (hidden revision '7a09c7a39546' was rewritten as: 39c4200c0d94)
- working directory parent is obsolete! (7a09c7a39546)
- (use 'hg evolve' to update to its successor: 39c4200c0d94)
- $ hg amend --date "120 0"
- 2 new content-divergent changesets
- $ hg log -G
- @ changeset: 12:da3be3d72fe2
- | tag: tip
- | parent: 0:a24ed8ad918c
- | user: test
- | date: Thu Jan 01 00:02:00 1970 +0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- | * changeset: 11:39c4200c0d94
- |/ parent: 0:a24ed8ad918c
- | user: test
- | date: Wed Dec 31 23:59:57 1969 -0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- o changeset: 0:a24ed8ad918c
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: add r0
-
- $ hg evolve --list -r .
- da3be3d72fe2: add foo.txt
- content-divergent: 39c4200c0d94 (draft) (precursor 7a09c7a39546)
-
- $ hg up 39c4200c0d94
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log -r 7a09c7a39546+39c4200c0d94+da3be3d72fe2 --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 10 7a09c7a39546 1969-12-31 23:59 -0000: date-changed using amend as 12:da3be3d72fe2; rewritten using evolve as 11:39c4200c0d94
- 11 39c4200c0d94 1969-12-31 23:59 -0000:
- 12 da3be3d72fe2 1970-01-01 00:02 +0000:
- $ hg evolve --content-divergent
- merge:[11] add foo.txt
- with: [12] add foo.txt
- base: [10] add foo.txt
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory is now at 06cde6010a51
- $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 13 06cde6010a51 1970-01-01 00:02 +0000:
-
-date: updated each side to a different value, newer should win
-
- $ hg amend --date "235 0"
- $ hg update --hidden --rev 'predecessors(.)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- updated to hidden changeset 06cde6010a51
- (hidden revision '06cde6010a51' was rewritten as: a7412ff9bfb3)
- working directory parent is obsolete! (06cde6010a51)
- (use 'hg evolve' to update to its successor: a7412ff9bfb3)
- $ hg amend --date "784 0"
- 2 new content-divergent changesets
- $ hg log -G
- @ changeset: 15:e3077936ec52
- | tag: tip
- | parent: 0:a24ed8ad918c
- | user: test
- | date: Thu Jan 01 00:13:04 1970 +0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- | * changeset: 14:a7412ff9bfb3
- |/ parent: 0:a24ed8ad918c
- | user: test
- | date: Thu Jan 01 00:03:55 1970 +0000
- | instability: content-divergent
- | summary: add foo.txt
- |
- o changeset: 0:a24ed8ad918c
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: add r0
-
- $ hg evolve --list -r .
- e3077936ec52: add foo.txt
- content-divergent: a7412ff9bfb3 (draft) (precursor 06cde6010a51)
-
- $ hg log -r 39c4200c0d94+a7412ff9bfb3+e3077936ec52 --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 11 39c4200c0d94 1969-12-31 23:59 -0000: date-changed using evolve as 13:06cde6010a51
- 14 a7412ff9bfb3 1970-01-01 00:03 +0000:
- 15 e3077936ec52 1970-01-01 00:13 +0000:
- $ hg evolve --content-divergent
- merge:[14] add foo.txt
- with: [15] add foo.txt
- base: [13] add foo.txt
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory is now at 1a39f3901288
- $ hg log -r . --hidden -T '{rev} {node|short} {date|isodate}: {join(obsfate, "; ")}\n'
- 16 1a39f3901288 1970-01-01 00:13 +0000:
--- a/tests/test-evolve-obshistory-amend-then-fold.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-amend-then-fold.t Sun Feb 02 13:28:47 2020 +0100
@@ -57,7 +57,7 @@
| | parent: 1:471f378eab4c
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 4:eb5a0daa2192
+ | | obsolete: folded using fold as 4:eb5a0daa2192
| | summary: B1
| |
| | x changeset: 2:0dec01379d3b
@@ -69,7 +69,7 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
- | obsolete: rewritten using fold as 4:eb5a0daa2192
+ | obsolete: folded using fold as 4:eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -152,8 +152,7 @@
[
{
"markers": [],
- "node": "eb5a0daa2192",
- "rev": 4,
+ "node": "eb5a0daa21923bbf8caeb2c42085b9e463861fd0",
"shortdescription": "C0"
},
{
@@ -163,21 +162,20 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
*, (glob)
*, (glob)
"content"
],
"operation": "fold",
"succnodes": [
- "eb5a0daa2192"
+ "eb5a0daa21923bbf8caeb2c42085b9e463861fd0"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "b7ea6d14e664",
- "rev": 3,
+ "node": "b7ea6d14e664bdc8922221f7992631b50da3fb07",
"shortdescription": "B1"
},
{
@@ -187,19 +185,18 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "b7ea6d14e664"
+ "b7ea6d14e664bdc8922221f7992631b50da3fb07"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "0dec01379d3b",
- "rev": 2,
+ "node": "0dec01379d3be6318c470ead31b1fe7ae7cb53d5",
"shortdescription": "B0"
},
{
@@ -209,20 +206,19 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description",
"content"
],
"operation": "fold",
"succnodes": [
- "eb5a0daa2192"
+ "eb5a0daa21923bbf8caeb2c42085b9e463861fd0"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
--- a/tests/test-evolve-obshistory-amend.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-amend.t Sun Feb 02 13:28:47 2020 +0100
@@ -92,6 +92,7 @@
$ hg obslog --no-graph --patch 4ae3a4151de9
4ae3a4151de9 (2) A1
+
471f378eab4c (1) A0
rewritten(description, content) as 4ae3a4151de9 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
diff -r 471f378eab4c -r 4ae3a4151de9 changeset-description
@@ -109,8 +110,32 @@
@@ -1,1 +1,2 @@
A0
+42
-
+
+
+Test that content diff works with templating
+ $ hg obslog --color=debug --patch 4ae3a4151de9 \
+ > -T '{node|short} {desc|firstline}\n{markers % "patch:\n```{patch}```\n"}'
+ @ 4ae3a4151de9 A1
+ |
+ x 471f378eab4c A0
+ patch:
+ ```
+ [diff.diffline|diff -r 471f378eab4c -r 4ae3a4151de9 A0]
+ [diff.file_a|--- a/A0 Thu Jan 01 00:00:00 1970 +0000]
+ [diff.file_b|+++ b/A0 Thu Jan 01 00:00:00 1970 +0000]
+ [diff.hunk|@@ -1,1 +1,2 @@]
+ A0
+ [diff.inserted|+42]
+ ```
+
+ $ hg obslog 4ae3a4151de9 --graph -T'{label("log.summary", desc|firstline)} {if(markers, join(markers % "at {date|hgdate} by {user|person} ", " also "))}'
+ @ A1
+ |
+ x A0 at 0 0 by test
+
+
+Check that the same thing works with the old {shortdescription} form
$ hg obslog 4ae3a4151de9 --graph -T'{label("log.summary", shortdescription)} {if(markers, join(markers % "at {date|hgdate} by {user|person} ", " also "))}'
@ A1
|
@@ -120,8 +145,7 @@
[
{
"markers": [],
- "node": "4ae3a4151de9",
- "rev": 2,
+ "node": "4ae3a4151de9aa872113f0b196e28323308981e8",
"shortdescription": "A1"
},
{
@@ -131,20 +155,19 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description",
"content"
],
"operation": "amend",
"succnodes": [
- "4ae3a4151de9"
+ "4ae3a4151de9aa872113f0b196e28323308981e8"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
@@ -177,20 +200,19 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
*, (glob)
"content"
],
"operation": "amend",
"succnodes": [
- "4ae3a4151de9"
+ "4ae3a4151de9aa872113f0b196e28323308981e8"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
@@ -220,15 +242,19 @@
$ hg obslog -R $TESTTMP/server --no-graph --patch 4ae3a4151de9
4ae3a4151de9 (1) A1
+
471f378eab4c
rewritten(description, content) as 4ae3a4151de9 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
$ hg obslog -R $TESTTMP/server --no-graph -f --patch 4ae3a4151de9
4ae3a4151de9 (1) A1
+
471f378eab4c
rewritten(description, content) as 4ae3a4151de9 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
Amend two more times
====================
@@ -347,6 +373,50 @@
+42
+Test that description diff works with templating
+ $ hg obslog --color=debug --patch 92210308515b \
+ > -T '{node|short} {desc|firstline}\n{markers % "description diff:\n```{descdiff}```\n"}'
+ @ 92210308515b A3
+ |
+ x 4f1685185907 A2
+ | description diff:
+ | ```
+ | [diff.diffline|diff -r 4f1685185907 -r 92210308515b changeset-description]
+ | [diff.file_a|--- a/changeset-description]
+ | [diff.file_b|+++ b/changeset-description]
+ | [diff.hunk|@@ -1,3 +1,3 @@]
+ | [diff.deleted|-A2]
+ | [diff.inserted|+A3]
+ |
+ | [diff.deleted|-Better better commit message]
+ | [diff.inserted|+Better better better commit message]
+ | ```
+ x 4ae3a4151de9 A1
+ | description diff:
+ | ```
+ | [diff.diffline|diff -r 4ae3a4151de9 -r 4f1685185907 changeset-description]
+ | [diff.file_a|--- a/changeset-description]
+ | [diff.file_b|+++ b/changeset-description]
+ | [diff.hunk|@@ -1,3 +1,3 @@]
+ | [diff.deleted|-A1]
+ | [diff.inserted|+A2]
+ |
+ | [diff.deleted|-Better commit message]
+ | [diff.inserted|+Better better commit message]
+ | ```
+ x 471f378eab4c A0
+ description diff:
+ ```
+ [diff.diffline|diff -r 471f378eab4c -r 4ae3a4151de9 changeset-description]
+ [diff.file_a|--- a/changeset-description]
+ [diff.file_b|+++ b/changeset-description]
+ [diff.hunk|@@ -1,1 +1,3 @@]
+ [diff.deleted|-A0]
+ [diff.inserted|+A1]
+ [diff.inserted|+]
+ [diff.inserted|+Better commit message]
+ ```
+
Check the output on the server
------------------------------
@@ -383,24 +453,32 @@
$ hg obslog -R $TESTTMP/server --no-graph --patch 92210308515b
92210308515b (2) A3
+
4f1685185907
rewritten(description) as 92210308515b using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
4ae3a4151de9 (1) A1
rewritten(description) as 4f1685185907 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, successor is unknown locally)
+
471f378eab4c
rewritten(description, content) as 4ae3a4151de9 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
$ hg obslog -R $TESTTMP/server --no-graph -f --patch 92210308515b
92210308515b (2) A3
+
4f1685185907
rewritten(description) as 92210308515b using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
4ae3a4151de9 (1) A1
rewritten(description) as 4f1685185907 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, successor is unknown locally)
+
471f378eab4c
rewritten(description, content) as 4ae3a4151de9 using amend by test (Thu Jan 01 00:00:00 1970 +0000)
(No patch available, context is not local)
+
--- a/tests/test-evolve-obshistory-complex.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-complex.t Sun Feb 02 13:28:47 2020 +0100
@@ -110,25 +110,25 @@
x | | changeset: 4:868d2e0eb19c
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
- | | | obsolete: rewritten using fold as 8:d15d0ffc75f6
+ | | | obsolete: folded using fold as 8:d15d0ffc75f6
| | | summary: D
| | |
x | | changeset: 3:a8df460dbbfe
|/ / user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 8:d15d0ffc75f6
+ | | obsolete: folded using fold as 8:d15d0ffc75f6
| | summary: C
| |
x | changeset: 2:c473644ee0e9
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 7:b868bc49b0a4
+ | | obsolete: folded using fold as 7:b868bc49b0a4
| | summary: B
| |
x | changeset: 1:2a34000d3544
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
- | obsolete: rewritten using fold as 7:b868bc49b0a4
+ | obsolete: folded using fold as 7:b868bc49b0a4
| summary: A
|
o changeset: 0:ea207398892e
--- a/tests/test-evolve-obshistory-content-divergent.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-content-divergent.t Sun Feb 02 13:28:47 2020 +0100
@@ -5,6 +5,10 @@
============
$ . $TESTDIR/testlib/obshistory_setup.sh
+ $ cat >> $HGRCPATH << EOF
+ > [experimental]
+ > evolution.allowdivergence = True
+ > EOF
Test output with content-divergence
===================================
@@ -129,12 +133,12 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "65b757b745b9"
+ "65b757b745b935093c87a2bccd877521cccffcbd"
],
"user": "test",
"verb": "rewritten"
@@ -144,19 +148,18 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "fdf9bde5129a"
+ "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
@@ -284,8 +287,7 @@
[
{
"markers": [],
- "node": "65b757b745b9",
- "rev": 3,
+ "node": "65b757b745b935093c87a2bccd877521cccffcbd",
"shortdescription": "A2"
},
{
@@ -295,12 +297,12 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "65b757b745b9"
+ "65b757b745b935093c87a2bccd877521cccffcbd"
],
"user": "test",
"verb": "rewritten"
@@ -310,25 +312,23 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "fdf9bde5129a"
+ "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
},
{
"markers": [],
- "node": "fdf9bde5129a",
- "rev": 2,
+ "node": "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e",
"shortdescription": "A1"
}
]
--- a/tests/test-evolve-obshistory-fold.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-fold.t Sun Feb 02 13:28:47 2020 +0100
@@ -50,13 +50,13 @@
| x changeset: 2:0dec01379d3b
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 3:eb5a0daa2192
+ | | obsolete: folded using fold as 3:eb5a0daa2192
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
- | obsolete: rewritten using fold as 3:eb5a0daa2192
+ | obsolete: folded using fold as 3:eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -172,8 +172,7 @@
[
{
"markers": [],
- "node": "eb5a0daa2192",
- "rev": 3,
+ "node": "eb5a0daa21923bbf8caeb2c42085b9e463861fd0",
"shortdescription": "C0"
},
{
@@ -183,20 +182,19 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description",
"content"
],
"operation": "fold",
"succnodes": [
- "eb5a0daa2192"
+ "eb5a0daa21923bbf8caeb2c42085b9e463861fd0"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
},
{
@@ -206,21 +204,20 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description",
"parent",
"content"
],
"operation": "fold",
"succnodes": [
- "eb5a0daa2192"
+ "eb5a0daa21923bbf8caeb2c42085b9e463861fd0"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "0dec01379d3b",
- "rev": 2,
+ "node": "0dec01379d3be6318c470ead31b1fe7ae7cb53d5",
"shortdescription": "B0"
}
]
@@ -275,7 +272,7 @@
o eb5a0daa2192 (2) C0
|
x 471f378eab4c (1) A0
- rewritten(description, content) as eb5a0daa2192 using fold by test (at Thu Jan 01 00:00:00 1970 +0000)
+ folded(description, content) as eb5a0daa2192 using fold by test (at Thu Jan 01 00:00:00 1970 +0000)
diff -r 471f378eab4c -r eb5a0daa2192 changeset-description
--- a/changeset-description
+++ b/changeset-description
@@ -318,7 +315,7 @@
o eb5a0daa2192 (2) C0
|
x 471f378eab4c (1) A0
- rewritten(description, content) as eb5a0daa2192 using fold by test (at Thu Jan 01 00:00:00 1970 +0000)
+ folded(description, content) as eb5a0daa2192 using fold by test (at Thu Jan 01 00:00:00 1970 +0000)
diff -r 471f378eab4c -r eb5a0daa2192 changeset-description
--- a/changeset-description
+++ b/changeset-description
--- a/tests/test-evolve-obshistory-lots-of-splits.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-lots-of-splits.t Sun Feb 02 13:28:47 2020 +0100
@@ -201,23 +201,22 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"parent",
"content"
],
"operation": "split",
"succnodes": [
- "1ae8bc733a14",
- "337fec4d2edc",
- "c7f044602e9b",
- "f257fde29c7a"
+ "1ae8bc733a14e374f11767d2ad128d4c891dc43f",
+ "337fec4d2edcf0e7a467e35f818234bc620068b5",
+ "c7f044602e9bd5dec6528b33114df3d0221e6359",
+ "f257fde29c7a847c9b607f6e958656d0df0fb15c"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "de7290d8b885",
- "rev": 1,
+ "node": "de7290d8b885925115bb9e88887252dfc20ef2a8",
"shortdescription": "A0"
}
]
@@ -232,8 +231,7 @@
[
{
"markers": [],
- "node": "c7f044602e9b",
- "rev": 5,
+ "node": "c7f044602e9bd5dec6528b33114df3d0221e6359",
"shortdescription": "A0"
},
{
@@ -243,23 +241,22 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"parent",
"content"
],
"operation": "split",
"succnodes": [
- "1ae8bc733a14",
- "337fec4d2edc",
- "c7f044602e9b",
- "f257fde29c7a"
+ "1ae8bc733a14e374f11767d2ad128d4c891dc43f",
+ "337fec4d2edcf0e7a467e35f818234bc620068b5",
+ "c7f044602e9bd5dec6528b33114df3d0221e6359",
+ "f257fde29c7a847c9b607f6e958656d0df0fb15c"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "de7290d8b885",
- "rev": 1,
+ "node": "de7290d8b885925115bb9e88887252dfc20ef2a8",
"shortdescription": "A0"
}
]
--- a/tests/test-evolve-obshistory-phase-divergent.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-phase-divergent.t Sun Feb 02 13:28:47 2020 +0100
@@ -102,19 +102,18 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "fdf9bde5129a"
+ "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
@@ -196,30 +195,28 @@
[
{
"markers": [],
- "node": "fdf9bde5129a",
- "rev": 2,
+ "node": "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e",
"shortdescription": "A1"
},
{
"markers": [
{
"date": [
- 0,
+ 0.0,
0
],
- "effect": [
+ "effects": [
"description"
],
"operation": "amend",
"succnodes": [
- "fdf9bde5129a"
+ "fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
--- a/tests/test-evolve-obshistory-prune.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-prune.t Sun Feb 02 13:28:47 2020 +0100
@@ -82,8 +82,7 @@
"verb": "pruned"
}
],
- "node": "0dec01379d3b",
- "rev": 2,
+ "node": "0dec01379d3be6318c470ead31b1fe7ae7cb53d5",
"shortdescription": "B0"
}
]
@@ -94,8 +93,7 @@
[
{
"markers": [],
- "node": "471f378eab4c",
- "rev": 1,
+ "node": "471f378eab4c5e25f6c77f785b27c936efb22874",
"shortdescription": "A0"
}
]
--- a/tests/test-evolve-obshistory-split.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory-split.t Sun Feb 02 13:28:47 2020 +0100
@@ -119,22 +119,21 @@
*, (glob)
0 (glob)
],
- "effect": [
+ "effects": [
"parent",
"content"
],
"note": "testing split",
"operation": "split",
"succnodes": [
- "337fec4d2edc",
- "f257fde29c7a"
+ "337fec4d2edcf0e7a467e35f818234bc620068b5",
+ "f257fde29c7a847c9b607f6e958656d0df0fb15c"
],
"user": "test",
"verb": "rewritten"
}
],
- "node": "471597cad322",
- "rev": 1,
+ "node": "471597cad322d1f659bb169751be9133dad92ef3",
"shortdescription": "A0"
}
]
@@ -245,14 +244,18 @@
$ hg obslog -R $TESTTMP/server --no-graph -f --all --patch tip
f257fde29c7a (2) A0
+
471597cad322
rewritten(parent, content) as 337fec4d2edc, f257fde29c7a using split by test (Thu Jan 01 00:00:00 1970 +0000)
note: testing split
(No patch available, context is not local)
+
$ hg obslog -R $TESTTMP/server --no-graph -f --all --patch tip
f257fde29c7a (2) A0
+
471597cad322
rewritten(parent, content) as 337fec4d2edc, f257fde29c7a using split by test (Thu Jan 01 00:00:00 1970 +0000)
note: testing split
(No patch available, context is not local)
+
--- a/tests/test-evolve-obshistory.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-obshistory.t Sun Feb 02 13:28:47 2020 +0100
@@ -168,3 +168,12 @@
[evolve.verb|rewritten](description) as [evolve.node|fdf9bde5129a] using [evolve.operation|amend] by [evolve.user|test] [evolve.date|(Thu Jan 01 00:00:00 1970 +0000)]
(No patch available, successor is unknown locally)
+
+ $ hg obslog 7a230b46bf61 --graph \
+ > -T '{node|short} {rev} {desc|firstline}\n{markers % "rewritten using {operation}"}\n'
+ o 7a230b46bf61 2 A2
+ |
+ x fdf9bde5129a
+ | rewritten using amend
+ @ 471f378eab4c 1 A0
+ rewritten using amend
--- a/tests/test-evolve-order.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-order.t Sun Feb 02 13:28:47 2020 +0100
@@ -15,6 +15,8 @@
> unified = 0
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
--- a/tests/test-evolve-orphan-merge.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-orphan-merge.t Sun Feb 02 13:28:47 2020 +0100
@@ -134,11 +134,18 @@
date: Thu Jan 01 00:00:00 1970 +0000
summary: merging a and b
+
+Clean up to prepare for next test case
+ $ hg prune -r 64370c9805e7 -r 3d41537b44ca -r 968d205ba4d8
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ working directory is now at 8fa14d15e168
+ 3 changesets pruned
+
2) When merging both the parents resulted in conflicts
------------------------------------------------------
$ hg up 8fa14d15e168
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo foo > c
$ hg ci -Aqm "foo to c"
$ hg prev
@@ -152,24 +159,6 @@
| () draft
| o 8:1c165c673853 foo to c
|/ () draft
- | o 7:968d205ba4d8 merging a and b
- | |\ () draft
- +---o 6:3d41537b44ca added a
- | | () draft
- | o 4:64370c9805e7 added b
- |/ () draft
- o 0:8fa14d15e168 added hgignore
- () draft
-
-Prune old test changesets to have clear graph view
- $ hg prune -r 64370c9805e7 -r 3d41537b44ca -r 968d205ba4d8
- 3 changesets pruned
-
- $ hg glog
- @ 9:d0f84b25d4e3 bar to c
- | () draft
- | o 8:1c165c673853 foo to c
- |/ () draft
o 0:8fa14d15e168 added hgignore
() draft
@@ -529,28 +518,19 @@
case where merge commit becomes orphan with its ancestors pruned up until a
point where the other parent of merge is the first non-pruned ancestor.
-Note: allowing an empty commit here to have the same output on all hg versions.
-In newer versions or Mercurial this command would not create a new commit.
-hg <= 5.2 (32d11a23c9cf)
-
- $ hg evolve -r . --config ui.allowemptycommit=true
+ $ hg evolve -r .
move:[28] merged l and x
atop:[0] added hgignore
- working directory is now at * (glob)
+ evolution of 28:fb8fe870ae7d created no changes to commit
+ working directory is now at 8fa14d15e168
$ hg glog
- @ 29:* merged l and x (glob)
- | () draft
- o 0:8fa14d15e168 added hgignore
+ @ 0:8fa14d15e168 added hgignore
() draft
7) When one parent is pruned without successor and has no parent
----------------------------------------------------------------
- $ hg prune -r .
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory is now at 8fa14d15e168
- 1 changesets pruned
$ hg up null
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -564,9 +544,9 @@
(branch merge, don't forget to commit)
$ hg ci -m "merge commit"
$ hg glog
- @ 31:32beb84b9dbc merge commit
+ @ 30:32beb84b9dbc merge commit
|\ () draft
- | o 30:f3ba8b99bb6f added foo
+ | o 29:f3ba8b99bb6f added foo
| () draft
o 0:8fa14d15e168 added hgignore
() draft
@@ -576,9 +556,9 @@
1 new orphan changesets
$ hg glog
- @ 31:32beb84b9dbc merge commit
+ @ 30:32beb84b9dbc merge commit
|\ () draft
- | x 30:f3ba8b99bb6f added foo
+ | x 29:f3ba8b99bb6f added foo
| () draft
o 0:8fa14d15e168 added hgignore
() draft
@@ -596,12 +576,12 @@
just remove that chain.
$ hg evolve -r .
- move:[31] merge commit
+ move:[30] merge commit
atop:[-1]
working directory is now at d2a03dd8c951
$ hg glog
- @ 32:d2a03dd8c951 merge commit
+ @ 31:d2a03dd8c951 merge commit
| () draft
o 0:8fa14d15e168 added hgignore
() draft
--- a/tests/test-evolve-progress.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-progress.t Sun Feb 02 13:28:47 2020 +0100
@@ -42,8 +42,6 @@
move:[2] third
hg rebase -r 769574b07a96 -d 5f16d91ecde0
evolve: 2/3 changesets (66.67%)
- unmatched files in other:
- b
resolving manifests
branchmerge: True, force: True, partial: False
ancestor: 4f60c78b6d58, local: 5f16d91ecde0+, remote: 769574b07a96
@@ -154,8 +152,6 @@
atop:[11] second
hg rebase -r 53c0008d98a0 -d 60a86497fbfe
evolve: 2/3 changesets (66.67%)
- unmatched files in other:
- b
resolving manifests
branchmerge: True, force: True, partial: False
ancestor: 5f16d91ecde0, local: 60a86497fbfe+, remote: 53c0008d98a0
--- a/tests/test-evolve-public-content-divergent-corner-cases.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-public-content-divergent-corner-cases.t Sun Feb 02 13:28:47 2020 +0100
@@ -12,6 +12,8 @@
> glog = log -GT "{rev}:{node|short} {desc|firstline}\n {phase} {instabilities}\n\n"
> [phases]
> publish = False
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> rebase =
> EOF
--- a/tests/test-evolve-public-content-divergent-discard.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-public-content-divergent-discard.t Sun Feb 02 13:28:47 2020 +0100
@@ -17,6 +17,8 @@
> glog = log -GT "{rev}:{node|short} {desc|firstline}\n {phase} {instabilities}\n\n"
> [phases]
> publish = False
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> rebase =
> EOF
--- a/tests/test-evolve-public-content-divergent-main.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-public-content-divergent-main.t Sun Feb 02 13:28:47 2020 +0100
@@ -15,6 +15,8 @@
> glog = log -GT "{rev}:{node|short} {desc|firstline}\n {phase} {instabilities}\n\n"
> [phases]
> publish = False
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> rebase =
> EOF
--- a/tests/test-evolve-templates.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve-templates.t Sun Feb 02 13:28:47 2020 +0100
@@ -1,4 +1,4 @@
-This test file test the various templates for precursors and successors.
+This test file test the various templates for predecessors and successors.
Global setup
============
@@ -9,12 +9,14 @@
> interactive = true
> [phases]
> publish=False
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> evolve =
> [alias]
> tlog = log -G -T '{node|short}\
- > {if(precursors, "\n Precursors: {precursors}")}\
- > {if(precursors, "\n semi-colon: {join(precursors, "; ")}")}\
+ > {if(predecessors, "\n Predecessors: {predecessors}")}\
+ > {if(predecessors, "\n semi-colon: {join(predecessors, "; ")}")}\
> {if(successors, "\n Successors: {successors}")}\
> {if(successors, "\n semi-colon: {join(successors, "; ")}")}\
> {if(obsfate, "\n Fate: {join(obsfate, "\n Fate: ")}\n")}\n'
@@ -69,7 +71,7 @@
working directory parent is obsolete! (471f378eab4c)
(use 'hg evolve' to update to its successor: d004c8f274b9)
-Precursors template should show current revision as it is the working copy
+Predecessors template should show current revision as it is the working copy
$ hg olog tip
o d004c8f274b9 (3) A2
|
@@ -81,7 +83,7 @@
$ hg tlog
o d004c8f274b9
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Successors: 3:d004c8f274b9
@@ -139,7 +141,7 @@
(check json)
- $ hg log -GT '{precursors|json}\n'
+ $ hg log -GT '{predecessors|json}\n'
o ["471f378eab4c5e25f6c77f785b27c936efb22874"]
|
| @ []
@@ -162,10 +164,10 @@
working directory parent is obsolete! (a468dc9b3633)
(use 'hg evolve' to update to its successor: d004c8f274b9)
-Precursors template should show current revision as it is the working copy
+Predecessors template should show current revision as it is the working copy
$ hg tlog
o d004c8f274b9
- | Precursors: 2:a468dc9b3633
+ | Predecessors: 2:a468dc9b3633
| semi-colon: 2:a468dc9b3633
| @ a468dc9b3633
|/ Successors: 3:d004c8f274b9
@@ -174,14 +176,14 @@
|
o ea207398892e
-Precursors template should show the precursor as we force its display with
+Predecessors template should show the precursor as we force its display with
--hidden
$ hg tlog --hidden
o d004c8f274b9
- | Precursors: 2:a468dc9b3633
+ | Predecessors: 2:a468dc9b3633
| semi-colon: 2:a468dc9b3633
| @ a468dc9b3633
- |/ Precursors: 1:471f378eab4c
+ |/ Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| Successors: 3:d004c8f274b9
| semi-colon: 3:d004c8f274b9
@@ -211,10 +213,10 @@
$ hg tlog --hidden
@ d004c8f274b9
- | Precursors: 2:a468dc9b3633
+ | Predecessors: 2:a468dc9b3633
| semi-colon: 2:a468dc9b3633
| x a468dc9b3633
- |/ Precursors: 1:471f378eab4c
+ |/ Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| Successors: 3:d004c8f274b9
| semi-colon: 3:d004c8f274b9
@@ -343,13 +345,13 @@
working directory parent is obsolete! (471597cad322)
(use 'hg evolve' to update to its tipmost successor: 337fec4d2edc, f257fde29c7a)
-Precursors template should show current revision as it is the working copy
+Predecessors template should show current revision as it is the working copy
$ hg tlog
o f257fde29c7a
- | Precursors: 1:471597cad322
+ | Predecessors: 1:471597cad322
| semi-colon: 1:471597cad322
o 337fec4d2edc
- | Precursors: 1:471597cad322
+ | Predecessors: 1:471597cad322
| semi-colon: 1:471597cad322
| @ 471597cad322
|/ Successors: 2:337fec4d2edc 3:f257fde29c7a
@@ -372,7 +374,7 @@
$ hg up f257fde29c7a
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-Precursors template should not show a precursor as it's not displayed in the
+Predecessors template should not show a precursor as it's not displayed in the
log
$ hg tlog
@ f257fde29c7a
@@ -381,14 +383,14 @@
|
o ea207398892e
-Precursors template should show the precursor as we force its display with
+Predecessors template should show the precursor as we force its display with
--hidden
$ hg tlog --hidden
@ f257fde29c7a
- | Precursors: 1:471597cad322
+ | Predecessors: 1:471597cad322
| semi-colon: 1:471597cad322
o 337fec4d2edc
- | Precursors: 1:471597cad322
+ | Predecessors: 1:471597cad322
| semi-colon: 1:471597cad322
| x 471597cad322
|/ Successors: 2:337fec4d2edc 3:f257fde29c7a
@@ -450,13 +452,13 @@
| x changeset: 2:0dec01379d3b
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 3:eb5a0daa2192
+ | | obsolete: folded using fold as 3:eb5a0daa2192
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
- | obsolete: rewritten using fold as 3:eb5a0daa2192
+ | obsolete: folded using fold as 3:eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -474,15 +476,15 @@
working directory parent is obsolete! (471f378eab4c)
(use 'hg evolve' to update to its successor: eb5a0daa2192)
-Precursors template should show current revision as it is the working copy
+Predecessors template should show current revision as it is the working copy
$ hg tlog
o eb5a0daa2192
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Successors: 3:eb5a0daa2192
| semi-colon: 3:eb5a0daa2192
- | Fate: rewritten using fold as 3:eb5a0daa2192
+ | Fate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -490,7 +492,7 @@
o eb5a0daa2192
|
| @ 471f378eab4c
- |/ Obsfate: rewritten using fold as 3:eb5a0daa2192
+ |/ Obsfate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -501,21 +503,21 @@
working directory parent is obsolete! (0dec01379d3b)
(use 'hg evolve' to update to its successor: eb5a0daa2192)
-Precursors template should show both precursors as they should be both
+Predecessors template should show both predecessors as they should be both
displayed
$ hg tlog
o eb5a0daa2192
- | Precursors: 2:0dec01379d3b 1:471f378eab4c
+ | Predecessors: 2:0dec01379d3b 1:471f378eab4c
| semi-colon: 2:0dec01379d3b; 1:471f378eab4c
| @ 0dec01379d3b
| | Successors: 3:eb5a0daa2192
| | semi-colon: 3:eb5a0daa2192
- | | Fate: rewritten using fold as 3:eb5a0daa2192
+ | | Fate: folded using fold as 3:eb5a0daa2192
| |
| x 471f378eab4c
|/ Successors: 3:eb5a0daa2192
| semi-colon: 3:eb5a0daa2192
- | Fate: rewritten using fold as 3:eb5a0daa2192
+ | Fate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -523,10 +525,10 @@
o eb5a0daa2192
|
| @ 0dec01379d3b
- | | Obsfate: rewritten using fold as 3:eb5a0daa2192
+ | | Obsfate: folded using fold as 3:eb5a0daa2192
| |
| x 471f378eab4c
- |/ Obsfate: rewritten using fold as 3:eb5a0daa2192
+ |/ Obsfate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -534,28 +536,28 @@
$ hg up 'desc(C0)'
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-Precursors template should not show precursors as it's not displayed in the
+Predecessors template should not show predecessors as it's not displayed in the
log
$ hg tlog
@ eb5a0daa2192
|
o ea207398892e
-Precursors template should show both precursors as we force its display with
+Predecessors template should show both predecessors as we force its display with
--hidden
$ hg tlog --hidden
@ eb5a0daa2192
- | Precursors: 2:0dec01379d3b 1:471f378eab4c
+ | Predecessors: 2:0dec01379d3b 1:471f378eab4c
| semi-colon: 2:0dec01379d3b; 1:471f378eab4c
| x 0dec01379d3b
| | Successors: 3:eb5a0daa2192
| | semi-colon: 3:eb5a0daa2192
- | | Fate: rewritten using fold as 3:eb5a0daa2192
+ | | Fate: folded using fold as 3:eb5a0daa2192
| |
| x 471f378eab4c
|/ Successors: 3:eb5a0daa2192
| semi-colon: 3:eb5a0daa2192
- | Fate: rewritten using fold as 3:eb5a0daa2192
+ | Fate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -563,10 +565,10 @@
@ eb5a0daa2192
|
| x 0dec01379d3b
- | | Obsfate: rewritten using fold as 3:eb5a0daa2192
+ | | Obsfate: folded using fold as 3:eb5a0daa2192
| |
| x 471f378eab4c
- |/ Obsfate: rewritten using fold as 3:eb5a0daa2192
+ |/ Obsfate: folded using fold as 3:eb5a0daa2192
|
o ea207398892e
@@ -649,13 +651,13 @@
working directory parent is obsolete! (471f378eab4c)
(471f378eab4c has diverged, use 'hg evolve --list --content-divergent' to resolve the issue)
-Precursors template should show current revision as it is the working copy
+Predecessors template should show current revision as it is the working copy
$ hg tlog
* 019fadeab383
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| * fdf9bde5129a
- |/ Precursors: 1:471f378eab4c
+ |/ Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Successors: 2:fdf9bde5129a; 4:019fadeab383
@@ -678,7 +680,7 @@
$ hg up 'desc(A1)'
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-Precursors template should not show precursors as it's not displayed in the
+Predecessors template should not show predecessors as it's not displayed in the
log
$ hg tlog
* 019fadeab383
@@ -695,20 +697,20 @@
|/
o ea207398892e
-Precursors template should a precursor as we force its display with --hidden
+Predecessors template should a precursor as we force its display with --hidden
$ hg tlog --hidden
* 019fadeab383
- | Precursors: 3:65b757b745b9
+ | Predecessors: 3:65b757b745b9
| semi-colon: 3:65b757b745b9
| x 65b757b745b9
- |/ Precursors: 1:471f378eab4c
+ |/ Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| Successors: 4:019fadeab383
| semi-colon: 4:019fadeab383
| Fate: reworded using amend as 4:019fadeab383
|
| @ fdf9bde5129a
- |/ Precursors: 1:471f378eab4c
+ |/ Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| x 471f378eab4c
|/ Successors: 2:fdf9bde5129a; 3:65b757b745b9
@@ -783,7 +785,7 @@
| | parent: 1:471f378eab4c
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
- | | obsolete: rewritten using fold as 4:eb5a0daa2192
+ | | obsolete: folded using fold as 4:eb5a0daa2192
| | summary: B1
| |
| | x changeset: 2:0dec01379d3b
@@ -795,7 +797,7 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
- | obsolete: rewritten using fold as 4:eb5a0daa2192
+ | obsolete: folded using fold as 4:eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -814,12 +816,12 @@
(use 'hg evolve' to update to its successor: eb5a0daa2192)
$ hg tlog
o eb5a0daa2192
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Successors: 4:eb5a0daa2192
| semi-colon: 4:eb5a0daa2192
- | Fate: rewritten using fold as 4:eb5a0daa2192
+ | Fate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -827,7 +829,7 @@
o eb5a0daa2192
|
| @ 471f378eab4c
- |/ Obsfate: rewritten using fold as 4:eb5a0daa2192
+ |/ Obsfate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -839,7 +841,7 @@
(use 'hg evolve' to update to its successor: eb5a0daa2192)
$ hg tlog
o eb5a0daa2192
- | Precursors: 2:0dec01379d3b 1:471f378eab4c
+ | Predecessors: 2:0dec01379d3b 1:471f378eab4c
| semi-colon: 2:0dec01379d3b; 1:471f378eab4c
| @ 0dec01379d3b
| | Successors: 4:eb5a0daa2192
@@ -849,7 +851,7 @@
| x 471f378eab4c
|/ Successors: 4:eb5a0daa2192
| semi-colon: 4:eb5a0daa2192
- | Fate: rewritten using fold as 4:eb5a0daa2192
+ | Fate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -860,7 +862,7 @@
| | Obsfate: rewritten using amend, fold as 4:eb5a0daa2192
| |
| x 471f378eab4c
- |/ Obsfate: rewritten using fold as 4:eb5a0daa2192
+ |/ Obsfate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -873,17 +875,17 @@
(use 'hg evolve' to update to its successor: eb5a0daa2192)
$ hg tlog
o eb5a0daa2192
- | Precursors: 1:471f378eab4c 3:b7ea6d14e664
+ | Predecessors: 1:471f378eab4c 3:b7ea6d14e664
| semi-colon: 1:471f378eab4c; 3:b7ea6d14e664
| @ b7ea6d14e664
| | Successors: 4:eb5a0daa2192
| | semi-colon: 4:eb5a0daa2192
- | | Fate: rewritten using fold as 4:eb5a0daa2192
+ | | Fate: folded using fold as 4:eb5a0daa2192
| |
| x 471f378eab4c
|/ Successors: 4:eb5a0daa2192
| semi-colon: 4:eb5a0daa2192
- | Fate: rewritten using fold as 4:eb5a0daa2192
+ | Fate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -891,10 +893,10 @@
o eb5a0daa2192
|
| @ b7ea6d14e664
- | | Obsfate: rewritten using fold as 4:eb5a0daa2192
+ | | Obsfate: folded using fold as 4:eb5a0daa2192
| |
| x 471f378eab4c
- |/ Obsfate: rewritten using fold as 4:eb5a0daa2192
+ |/ Obsfate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -908,14 +910,14 @@
$ hg tlog --hidden
@ eb5a0daa2192
- | Precursors: 1:471f378eab4c 3:b7ea6d14e664
+ | Predecessors: 1:471f378eab4c 3:b7ea6d14e664
| semi-colon: 1:471f378eab4c; 3:b7ea6d14e664
| x b7ea6d14e664
- | | Precursors: 2:0dec01379d3b
+ | | Predecessors: 2:0dec01379d3b
| | semi-colon: 2:0dec01379d3b
| | Successors: 4:eb5a0daa2192
| | semi-colon: 4:eb5a0daa2192
- | | Fate: rewritten using fold as 4:eb5a0daa2192
+ | | Fate: folded using fold as 4:eb5a0daa2192
| |
| | x 0dec01379d3b
| |/ Successors: 3:b7ea6d14e664
@@ -925,7 +927,7 @@
| x 471f378eab4c
|/ Successors: 4:eb5a0daa2192
| semi-colon: 4:eb5a0daa2192
- | Fate: rewritten using fold as 4:eb5a0daa2192
+ | Fate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -933,13 +935,13 @@
@ eb5a0daa2192
|
| x b7ea6d14e664
- | | Obsfate: rewritten using fold as 4:eb5a0daa2192
+ | | Obsfate: folded using fold as 4:eb5a0daa2192
| |
| | x 0dec01379d3b
| |/ Obsfate: reworded using amend as 3:b7ea6d14e664
| |
| x 471f378eab4c
- |/ Obsfate: rewritten using fold as 4:eb5a0daa2192
+ |/ Obsfate: folded using fold as 4:eb5a0daa2192
|
o ea207398892e
@@ -1037,7 +1039,7 @@
$ hg tlog
o 7a230b46bf61
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Successors: 2:7a230b46bf61
@@ -1068,7 +1070,7 @@
$ hg tlog --hidden
@ 7a230b46bf61
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| x 471f378eab4c
|/ Successors: 2:7a230b46bf61
@@ -1135,10 +1137,10 @@
(use 'hg evolve' to update to its parent successor)
$ hg tlog
o f897c6137566
- | Precursors: 2:0dec01379d3b
+ | Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| @ 0dec01379d3b
- | | Precursors: 1:471f378eab4c
+ | | Predecessors: 1:471f378eab4c
| | semi-colon: 1:471f378eab4c
| | Successors: 3:f897c6137566; 1:471f378eab4c
| | semi-colon: 3:f897c6137566; 1:471f378eab4c
@@ -1146,7 +1148,7 @@
| | Fate: rewritten as 1:471f378eab4c
| |
| x 471f378eab4c
- |/ Precursors: 2:0dec01379d3b
+ |/ Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| Successors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
@@ -1171,7 +1173,7 @@
(use 'hg evolve' to update to its parent successor)
$ hg tlog
o f897c6137566
- | Precursors: 1:471f378eab4c
+ | Predecessors: 1:471f378eab4c
| semi-colon: 1:471f378eab4c
| @ 471f378eab4c
|/ Fate: pruned
@@ -1201,10 +1203,10 @@
$ hg tlog --hidden
o f897c6137566
- | Precursors: 2:0dec01379d3b
+ | Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| x 0dec01379d3b
- | | Precursors: 1:471f378eab4c
+ | | Predecessors: 1:471f378eab4c
| | semi-colon: 1:471f378eab4c
| | Successors: 3:f897c6137566; 1:471f378eab4c
| | semi-colon: 3:f897c6137566; 1:471f378eab4c
@@ -1212,7 +1214,7 @@
| | Fate: rewritten as 1:471f378eab4c
| |
| x 471f378eab4c
- |/ Precursors: 2:0dec01379d3b
+ |/ Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| Successors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
@@ -1388,10 +1390,10 @@
$ hg tlog
@ 0b997eb7ceee
- | Precursors: 6:4a004186e638
+ | Predecessors: 6:4a004186e638
| semi-colon: 6:4a004186e638
| * b18bc8331526
- |/ Precursors: 6:4a004186e638
+ |/ Predecessors: 6:4a004186e638
| semi-colon: 6:4a004186e638
| * ba2ed02b0c9a
| |
@@ -1425,16 +1427,16 @@
$ hg tlog --hidden
@ 0b997eb7ceee
- | Precursors: 6:4a004186e638
+ | Predecessors: 6:4a004186e638
| semi-colon: 6:4a004186e638
| * b18bc8331526
- |/ Precursors: 6:4a004186e638
+ |/ Predecessors: 6:4a004186e638
| semi-colon: 6:4a004186e638
| * ba2ed02b0c9a
- | | Precursors: 4:9bd10a0775e4
+ | | Predecessors: 4:9bd10a0775e4
| | semi-colon: 4:9bd10a0775e4
| x 4a004186e638
- |/ Precursors: 4:9bd10a0775e4
+ |/ Predecessors: 4:9bd10a0775e4
| semi-colon: 4:9bd10a0775e4
| Successors: 8:b18bc8331526; 9:0b997eb7ceee
| semi-colon: 8:b18bc8331526; 9:0b997eb7ceee
@@ -1442,7 +1444,7 @@
| Fate: reworded using amend as 9:0b997eb7ceee
|
* dd800401bd8c
- | Precursors: 4:9bd10a0775e4
+ | Predecessors: 4:9bd10a0775e4
| semi-colon: 4:9bd10a0775e4
| x 9bd10a0775e4
|/ Successors: 5:dd800401bd8c 6:4a004186e638 7:ba2ed02b0c9a
@@ -1450,10 +1452,10 @@
| Fate: split as 5:dd800401bd8c, 6:4a004186e638, 7:ba2ed02b0c9a
|
o f897c6137566
- | Precursors: 2:0dec01379d3b
+ | Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| x 0dec01379d3b
- | | Precursors: 1:471f378eab4c
+ | | Predecessors: 1:471f378eab4c
| | semi-colon: 1:471f378eab4c
| | Successors: 3:f897c6137566; 1:471f378eab4c
| | semi-colon: 3:f897c6137566; 1:471f378eab4c
@@ -1461,7 +1463,7 @@
| | Fate: rewritten as 1:471f378eab4c
| |
| x 471f378eab4c
- |/ Precursors: 2:0dec01379d3b
+ |/ Predecessors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
| Successors: 2:0dec01379d3b
| semi-colon: 2:0dec01379d3b
@@ -1504,16 +1506,16 @@
rebasing 7:ba2ed02b0c9a "Add A,B,C"
$ hg tlog
* eceed8f98ffc
- | Precursors: 4:9bd10a0775e4
+ | Predecessors: 4:9bd10a0775e4
| semi-colon: 4:9bd10a0775e4
| * 0b997eb7ceee
- | | Precursors: 4:9bd10a0775e4
+ | | Predecessors: 4:9bd10a0775e4
| | semi-colon: 4:9bd10a0775e4
* | b18bc8331526
- |/ Precursors: 4:9bd10a0775e4
+ |/ Predecessors: 4:9bd10a0775e4
| semi-colon: 4:9bd10a0775e4
* dd800401bd8c
- | Precursors: 4:9bd10a0775e4
+ | Predecessors: 4:9bd10a0775e4
| semi-colon: 4:9bd10a0775e4
| @ 9bd10a0775e4
|/ Successors: 5:dd800401bd8c 9:0b997eb7ceee 10:eceed8f98ffc; 5:dd800401bd8c 8:b18bc8331526 10:eceed8f98ffc
--- a/tests/test-evolve.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-evolve.t Sun Feb 02 13:28:47 2020 +0100
@@ -781,19 +781,22 @@
more than 2 successors: 0
available keys:
ef1: 10
+ fold-id: 5
+ fold-idx: 5
+ fold-size: 5
operation: 10
user: 10
marker size:
format v1:
smallest length: 90
- longer length: 92
- median length: 91
- mean length: 90
+ longer length: 131
+ median length: 130
+ mean length: 110
format v0:
- smallest length: * (glob)
- longer length: * (glob)
- median length: * (glob)
- mean length: * (glob)
+ smallest length: * (glob)
+ longer length: * (glob)
+ median length: * (glob)
+ mean length: * (glob)
disconnected clusters: 1
any known node: 1
smallest length: 10
--- a/tests/test-fold.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-fold.t Sun Feb 02 13:28:47 2020 +0100
@@ -95,6 +95,10 @@
$ hg fold --from -r 'desc("r5")'
3 changesets folded
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg debugobsolete -r 'desc("r5")' --exclusive
+ 4de32a90b66cd083ebf3c00b41277aa7abca51dd 198b5c405d01a50c41a81a00fc61677b81981a5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '37', 'fold-id': '25cb328e', 'fold-idx': '3', 'fold-size': '3', 'operation': 'fold', 'user': 'test'}
+ c8d03c1b5e94af74b772900c58259d2e08917735 198b5c405d01a50c41a81a00fc61677b81981a5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '33', 'fold-id': '25cb328e', 'fold-idx': '1', 'fold-size': '3', 'operation': 'fold', 'user': 'test'}
+ f69452c5b1af6cbaaa56ef50cf94fff5bcc6ca23 198b5c405d01a50c41a81a00fc61677b81981a5f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '37', 'fold-id': '25cb328e', 'fold-idx': '2', 'fold-size': '3', 'operation': 'fold', 'user': 'test'}
Checking whether the bookmarks are moved or not
@@ -405,8 +409,8 @@
$ hg fold --exact -r 'desc("A")::desc("B")' -m 'second fold' \
> --config experimental.evolution.allowdivergence=no
- abort: folding obsolete revisions may cause divergence
- (set experimental.evolution.allowdivergence=yes to allow folding them)
+ abort: fold of 4b34ecfb0d56 creates content-divergence with fcfd42a7fa46
+ (add --verbose for details or see 'hg help evolution.instability')
[255]
but if we allow divergence, this should work and should create new content-divergent changesets
--- a/tests/test-metaedit.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-metaedit.t Sun Feb 02 13:28:47 2020 +0100
@@ -146,6 +146,9 @@
x 587528abfffe (7) F
rewritten(user) as 212b2a2b87cd using metaedit by test (Thu Jan 01 00:00:00 1970 +0000)
+ $ hg debugobsolete --rev . --exclusive
+ 212b2a2b87cdbae992f001e9baba64db389fbce7 a08d35fd7d9d0f8cb33d5bd2074e9bafb5cbc70f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '29', 'fold-id': 'c5832a81', 'fold-idx': '2', 'fold-size': '2', 'note': 'folding changesets using metaedit', 'operation': 'metaedit', 'user': 'test'}
+ c2bd843aa2468b30bb56d69d4f5fef95b85986f2 a08d35fd7d9d0f8cb33d5bd2074e9bafb5cbc70f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'fold-id': 'c5832a81', 'fold-idx': '1', 'fold-size': '2', 'note': 'folding changesets using metaedit', 'operation': 'metaedit', 'user': 'test'}
no new commit is created here because the date is the same
$ HGEDITOR=cat hg metaedit
@@ -205,6 +208,8 @@
1 changesets folded
$ hg log -r "tip" --template '{rev}: {author}\n'
12: foobar3
+ $ hg debugobsolete --rev 'tip' --exclusive
+ f3d001339afd30d27fcd91e713274a78233528c8 07a6525ddaf5de1ab33352806abb5724a0954f3f 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '16', 'operation': 'metaedit', 'user': 'foobar3'}
working on merge commits too
--- a/tests/test-pullbundle.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-pullbundle.t Sun Feb 02 13:28:47 2020 +0100
@@ -1158,3 +1158,14 @@
02-e469a7aa5cce57653b6b02ff46c80b2d94d62629-0000000912skip-0000000016size.hg
02-e74670ea99533967c5d90da3ddbc0318cc1fd502-0000001280skip-0000000256size.hg
02-fb6c210a224903e81e5a8d2ee099cb0c9526ba8c-0000001512skip-0000000004size.hg
+
+ $ hg debugpullbundlecacheoverlap -R server 'all()' | grep -v '^ '
+ gathering 100 sample pulls within 2131 revisions
+ pull size:
+ non-cached changesets:
+ ratio of cached changesets:
+ bundle count:
+ ratio of cached bundles:
+ changesets served:
+ size of cached bundles:
+ hit on cached bundles:
--- a/tests/test-push-checkheads-pruned-B6.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-push-checkheads-pruned-B6.t Sun Feb 02 13:28:47 2020 +0100
@@ -9,7 +9,7 @@
This case is part of a series of tests checking this behavior.
Category B: simple case involving pruned changesets
-TestCase 6: single changesets, pruned then superseeded (on a new changeset)
+TestCase 6: single changesets, pruned then superseded (on a new changeset)
.. old-state:
..
--- a/tests/test-push-checkheads-pruned-B7.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-push-checkheads-pruned-B7.t Sun Feb 02 13:28:47 2020 +0100
@@ -9,7 +9,7 @@
This case is part of a series of tests checking this behavior.
Category B: simple case involving pruned changesets
-TestCase 7: single changesets, pruned then superseeded (on an existing changeset)
+TestCase 7: single changesets, pruned then superseded (on an existing changeset)
.. old-state:
..
--- a/tests/test-push-checkheads-unpushed-D6.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-push-checkheads-unpushed-D6.t Sun Feb 02 13:28:47 2020 +0100
@@ -9,7 +9,7 @@
This case is part of a series of tests checking this behavior.
Category D: remote head is "obs-affected" locally, but result is not part of the push
-TestCase 6: single changeset, superseeded then pruned (on a new changeset unpushed) changeset
+TestCase 6: single changeset, superseded then pruned (on a new changeset unpushed) changeset
This is a partial push variation of case B-6
--- a/tests/test-push-checkheads-unpushed-D7.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-push-checkheads-unpushed-D7.t Sun Feb 02 13:28:47 2020 +0100
@@ -9,7 +9,7 @@
This case is part of a series of tests checking this behavior.
Category D: remote head is "obs-affected" locally, but result is not part of the push
-TestCase 7: single changesets, superseeded multiple time then pruned (on a new changeset unpushed) changeset
+TestCase 7: single changesets, superseded multiple time then pruned (on a new changeset unpushed) changeset
This is a partial push variation of B6
--- a/tests/test-topic-stack-complex.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-topic-stack-complex.t Sun Feb 02 13:28:47 2020 +0100
@@ -7,6 +7,7 @@
$ cat << EOF >> $HGRCPATH
> [experimental]
> evolution = all
+ > evolution.allowdivergence = True
> [ui]
> interactive = True
> [extensions]
--- a/tests/test-topic.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-topic.t Sun Feb 02 13:28:47 2020 +0100
@@ -122,10 +122,15 @@
list of commands:
- stack list all changesets in a topic and other information
+ Change organization:
+
topics View current topic, set current topic, change topic for a set
of revisions, or see all topics.
+ Change navigation:
+
+ stack list all changesets in a topic and other information
+
(use 'hg help -v topic' to show built-in aliases and global options)
$ hg help topics
hg topics [OPTION]... [-r REV]... [TOPIC]
--- a/tests/test-touch.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-touch.t Sun Feb 02 13:28:47 2020 +0100
@@ -6,6 +6,8 @@
> amend=-d "0 0"
> [alias]
> glog = log -GT "{rev}: {desc}"
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> hgext.rebase=
> EOF
--- a/tests/test-uncommit.t Sun Feb 02 13:25:23 2020 +0100
+++ b/tests/test-uncommit.t Sun Feb 02 13:28:47 2020 +0100
@@ -1,4 +1,6 @@
$ cat >> $HGRCPATH <<EOF
+ > [experimental]
+ > evolution.allowdivergence = True
> [extensions]
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH