Mercurial > evolve
changeset 4029:a01783a0468c
branching: merge with stable
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 28 Aug 2018 11:18:58 +0200 |
parents | 9ec77b6f2626 (diff) e8ce05aa9138 (current diff) |
children | 36225eb4d307 |
files | hgext3rd/evolve/obsdiscovery.py hgext3rd/evolve/stablerangecache.py tests/test-discovery-obshashrange.t |
diffstat | 16 files changed, 372 insertions(+), 268 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/dagutil.py Tue Aug 28 11:18:58 2018 +0200 @@ -0,0 +1,287 @@ +# dagutil.py - dag utilities for mercurial +# +# Copyright 2010 Benoit Boissinot <bboissin@gmail.com> +# and Peter Arrenbrecht <peter@arrenbrecht.ch> +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +# +# Imported from Mercurial code at cee9043c7dba + +from __future__ import absolute_import + +from mercurial.i18n import _ +from mercurial.node import nullrev + +class basedag(object): + '''generic interface for DAGs + + terms: + "ix" (short for index) identifies a nodes internally, + "id" identifies one externally. + + All params are ixs unless explicitly suffixed otherwise. + Pluralized params are lists or sets. + ''' + + def __init__(self): + self._inverse = None + + def nodeset(self): + '''set of all node ixs''' + raise NotImplementedError + + def heads(self): + '''list of head ixs''' + raise NotImplementedError + + def parents(self, ix): + '''list of parents ixs of ix''' + raise NotImplementedError + + def inverse(self): + '''inverse DAG, where parents becomes children, etc.''' + raise NotImplementedError + + def ancestorset(self, starts, stops=None): + ''' + set of all ancestors of starts (incl), but stop walk at stops (excl) + ''' + raise NotImplementedError + + def descendantset(self, starts, stops=None): + ''' + set of all descendants of starts (incl), but stop walk at stops (excl) + ''' + return self.inverse().ancestorset(starts, stops) + + def headsetofconnecteds(self, ixs): + ''' + subset of connected list of ixs so that no node has a descendant in it + + By "connected list" we mean that if an ancestor and a descendant are in + the list, then so is at least one path connecting them. + ''' + raise NotImplementedError + + def externalize(self, ix): + '''return a node id''' + return self._externalize(ix) + + def externalizeall(self, ixs): + '''return a list of (or set if given a set) of node ids''' + ids = self._externalizeall(ixs) + if isinstance(ixs, set): + return set(ids) + return list(ids) + + def internalize(self, id): + '''return a node ix''' + return self._internalize(id) + + def internalizeall(self, ids, filterunknown=False): + '''return a list of (or set if given a set) of node ixs''' + ixs = self._internalizeall(ids, filterunknown) + if isinstance(ids, set): + return set(ixs) + return list(ixs) + +class genericdag(basedag): + '''generic implementations for DAGs''' + + def ancestorset(self, starts, stops=None): + if stops: + stops = set(stops) + else: + stops = set() + seen = set() + pending = list(starts) + while pending: + n = pending.pop() + if n not in seen and n not in stops: + seen.add(n) + pending.extend(self.parents(n)) + return seen + + def headsetofconnecteds(self, ixs): + hds = set(ixs) + if not hds: + return hds + for n in ixs: + for p in self.parents(n): + hds.discard(p) + assert hds + return hds + +class revlogbaseddag(basedag): + '''generic dag interface to a revlog''' + + def __init__(self, revlog, nodeset): + basedag.__init__(self) + self._revlog = revlog + self._heads = None + self._nodeset = nodeset + + def nodeset(self): + return self._nodeset + + def heads(self): + if self._heads is None: + self._heads = self._getheads() + return self._heads + + def _externalize(self, ix): + return self._revlog.index[ix][7] + + def _externalizeall(self, ixs): + idx = self._revlog.index + return [idx[i][7] for i in ixs] + + def _internalize(self, id): + ix = self._revlog.rev(id) + if ix == nullrev: + raise LookupError(id, self._revlog.indexfile, _('nullid')) + return ix + + def _internalizeall(self, ids, filterunknown): + rl = self._revlog + if filterunknown: + return [r for r in map(rl.nodemap.get, ids) + if (r is not None + and r != nullrev + and r not in rl.filteredrevs)] + return [self._internalize(i) for i in ids] + +class revlogdag(revlogbaseddag): + '''dag interface to a revlog''' + + def __init__(self, revlog, localsubset=None): + revlogbaseddag.__init__(self, revlog, set(revlog)) + self._heads = localsubset + + def _getheads(self): + return [r for r in self._revlog.headrevs() if r != nullrev] + + def parents(self, ix): + rlog = self._revlog + idx = rlog.index + revdata = idx[ix] + prev = revdata[5] + if prev != nullrev: + prev2 = revdata[6] + if prev2 == nullrev: + return [prev] + return [prev, prev2] + prev2 = revdata[6] + if prev2 != nullrev: + return [prev2] + return [] + + def inverse(self): + if self._inverse is None: + self._inverse = inverserevlogdag(self) + return self._inverse + + def ancestorset(self, starts, stops=None): + rlog = self._revlog + idx = rlog.index + if stops: + stops = set(stops) + else: + stops = set() + seen = set() + pending = list(starts) + while pending: + rev = pending.pop() + if rev not in seen and rev not in stops: + seen.add(rev) + revdata = idx[rev] + for i in [5, 6]: + prev = revdata[i] + if prev != nullrev: + pending.append(prev) + return seen + + def headsetofconnecteds(self, ixs): + if not ixs: + return set() + rlog = self._revlog + idx = rlog.index + headrevs = set(ixs) + for rev in ixs: + revdata = idx[rev] + for i in [5, 6]: + prev = revdata[i] + if prev != nullrev: + headrevs.discard(prev) + assert headrevs + return headrevs + + def linearize(self, ixs): + '''linearize and topologically sort a list of revisions + + The linearization process tries to create long runs of revs where + a child rev comes immediately after its first parent. This is done by + visiting the heads of the given revs in inverse topological order, + and for each visited rev, visiting its second parent, then its first + parent, then adding the rev itself to the output list. + ''' + sorted = [] + visit = list(self.headsetofconnecteds(ixs)) + visit.sort(reverse=True) + finished = set() + + while visit: + cur = visit.pop() + if cur < 0: + cur = -cur - 1 + if cur not in finished: + sorted.append(cur) + finished.add(cur) + else: + visit.append(-cur - 1) + visit += [p for p in self.parents(cur) + if p in ixs and p not in finished] + assert len(sorted) == len(ixs) + return sorted + +class inverserevlogdag(revlogbaseddag, genericdag): + '''inverse of an existing revlog dag; see revlogdag.inverse()''' + + def __init__(self, orig): + revlogbaseddag.__init__(self, orig._revlog, orig._nodeset) + self._orig = orig + self._children = {} + self._roots = [] + self._walkfrom = len(self._revlog) - 1 + + def _walkto(self, walkto): + rev = self._walkfrom + cs = self._children + roots = self._roots + idx = self._revlog.index + while rev >= walkto: + data = idx[rev] + isroot = True + for prev in [data[5], data[6]]: # parent revs + if prev != nullrev: + cs.setdefault(prev, []).append(rev) + isroot = False + if isroot: + roots.append(rev) + rev -= 1 + self._walkfrom = rev + + def _getheads(self): + self._walkto(nullrev) + return self._roots + + def parents(self, ix): + if ix is None: + return [] + if ix <= self._walkfrom: + self._walkto(ix) + return self._children.get(ix, []) + + def inverse(self): + return self._orig
--- a/hgext3rd/evolve/depthcache.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/depthcache.py Tue Aug 28 11:18:58 2018 +0200 @@ -10,11 +10,9 @@ from __future__ import absolute_import import array -import weakref from mercurial import ( localrepo, - util, scmutil, ) @@ -85,30 +83,12 @@ self.depthcache.clear() super(depthcacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.depthcache.update(self) - self.depthcache.save(self) - super(depthcacherepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(depthcacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.depthcache.update(repo) - repo.depthcache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-00depthcache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.depthcache.update(self) + self.depthcache.save(self) + super(depthcacherepo, self).updatecaches(tr, **kwargs) repo.__class__ = depthcacherepo
--- a/hgext3rd/evolve/exthelper.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/exthelper.py Tue Aug 28 11:18:58 2018 +0200 @@ -11,12 +11,6 @@ util, ) -if util.safehasattr(registrar, 'command'): - command = registrar.command -else: # compat with hg < 4.3 - from mercurial import cmdutil - command = cmdutil.command - configitem = None dynamicdefault = None if util.safehasattr(registrar, 'configitem'): @@ -44,7 +38,7 @@ self._functionwrappers = [] self._duckpunchers = [] self.cmdtable = {} - self.command = command(self.cmdtable) + self.command = registrar.command(self.cmdtable) self.configtable = {} self._configitem = None
--- a/hgext3rd/evolve/firstmergecache.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/firstmergecache.py Tue Aug 28 11:18:58 2018 +0200 @@ -10,12 +10,10 @@ from __future__ import absolute_import import array -import weakref from mercurial import ( localrepo, node as nodemod, - util, ) from . import ( @@ -47,30 +45,12 @@ self.firstmergecache.clear() super(firstmergecacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.firstmergecache.update(self) - self.firstmergecache.save(self) - super(firstmergecacherepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(firstmergecacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.firstmergecache.update(repo) - repo.firstmergecache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-01-firstparentcache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.firstmergecache.update(self) + self.firstmergecache.save(self) + super(firstmergecacherepo, self).updatecaches(tr, **kwargs) repo.__class__ = firstmergecacherepo
--- a/hgext3rd/evolve/hack/drophack.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/hack/drophack.py Tue Aug 28 11:18:58 2018 +0200 @@ -21,12 +21,7 @@ cmdtable = {} -if util.safehasattr(registrar, 'command'): - command = registrar.command(cmdtable) -else: # compat with hg < 4.3 - from mercurial import cmdutil - command = cmdutil.command(cmdtable) - +command = registrar.command(cmdtable) @contextlib.contextmanager def timed(ui, caption):
--- a/hgext3rd/evolve/legacy.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/legacy.py Tue Aug 28 11:18:58 2018 +0200 @@ -36,11 +36,7 @@ # compat with hg < 4.6 from mercurial.util import makedate -if util.safehasattr(registrar, 'command'): - commandfunc = registrar.command -else: # compat with hg < 4.3 - from mercurial import cmdutil - commandfunc = cmdutil.command +commandfunc = registrar.command ##################################################################### ### Older format management ###
--- a/hgext3rd/evolve/metadata.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/metadata.py Tue Aug 28 11:18:58 2018 +0200 @@ -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__ = '8.1.2.dev' +__version__ = '8.2.0.dev' testedwith = '4.3.2 4.4.2 4.5.2 4.6.2 4.7' minimumhgversion = '4.3' buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obscache.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/obscache.py Tue Aug 28 11:18:58 2018 +0200 @@ -10,7 +10,6 @@ import errno import hashlib import struct -import weakref from mercurial import ( localrepo, @@ -478,31 +477,10 @@ self.obsstore.obscache.clear() super(obscacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - super(obscacherepo, self).updatecaches(tr, **kwargs) - self.obsstore.obscache.update(self) - self.obsstore.obscache.save(self) - - else: - def transaction(self, *args, **kwargs): - tr = super(obscacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - # As pointed in 'obscache.update', we could have the changelog - # and the obsstore in charge of updating the cache when new - # items goes it. The tranaction logic would then only be - # involved for the 'pending' and final writing on disk. - self.obsstore.obscache.update(repo) - self.obsstore.obscache.save(repo) - - tr.addpostclose('warmcache-obscache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + super(obscacherepo, self).updatecaches(tr, **kwargs) + self.obsstore.obscache.update(self) + self.obsstore.obscache.save(self) repo.__class__ = obscacherepo
--- a/hgext3rd/evolve/obsdiscovery.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/obsdiscovery.py Tue Aug 28 11:18:58 2018 +0200 @@ -29,7 +29,6 @@ import weakref from mercurial import ( - dagutil, error, exchange, extensions, @@ -60,6 +59,12 @@ wireprotov1server = wireprototypes from mercurial.wireproto import wirepeer, encodelist, decodelist +try: + from mercurial import dagutil + dagutil.revlogdag +except (ImportError, AttributeError): # <= hg-4.7 + from . import dagutil + _pack = struct.pack _unpack = struct.unpack _calcsize = struct.calcsize @@ -662,30 +667,12 @@ self.obsstore.rangeobshashcache.clear() super(obshashrepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.obsstore.rangeobshashcache.update(self) - self.obsstore.rangeobshashcache.save(self) - super(obshashrepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(obshashrepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.obsstore.rangeobshashcache.update(repo) - repo.obsstore.rangeobshashcache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-20obshashrange', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.obsstore.rangeobshashcache.update(self) + self.obsstore.rangeobshashcache.save(self) + super(obshashrepo, self).updatecaches(tr, **kwargs) repo.__class__ = obshashrepo
--- a/hgext3rd/evolve/stablerangecache.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/stablerangecache.py Tue Aug 28 11:18:58 2018 +0200 @@ -12,7 +12,6 @@ import random import sqlite3 import time -import weakref from mercurial import ( error, @@ -403,30 +402,12 @@ del self.stablerange super(stablerangerepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.stablerange.update(self) - self.stablerange.save(self) - super(stablerangerepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(stablerangerepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.stablerange.update(repo) - repo.stablerange.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-10stablerange', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.stablerange.update(self) + self.stablerange.save(self) + super(stablerangerepo, self).updatecaches(tr, **kwargs) repo.__class__ = stablerangerepo
--- a/hgext3rd/evolve/stablesort.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/stablesort.py Tue Aug 28 11:18:58 2018 +0200 @@ -10,7 +10,6 @@ import array import collections import struct -import weakref from mercurial import ( commands, @@ -18,7 +17,6 @@ error, node as nodemod, scmutil, - util, ) from mercurial.i18n import _ @@ -669,30 +667,12 @@ self.stablesort.clear() super(stablesortrepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.stablesort.update(self) - self.stablesort.save(self) - super(stablesortrepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(stablesortrepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.stablesort.update(repo) - repo.stablesort.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-02stablesort', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.stablesort.update(self) + self.stablesort.save(self) + super(stablesortrepo, self).updatecaches(tr, **kwargs) repo.__class__ = stablesortrepo
--- a/hgext3rd/evolve/templatekw.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/evolve/templatekw.py Tue Aug 28 11:18:58 2018 +0200 @@ -24,17 +24,6 @@ eh = exthelper.exthelper() ### template keywords -# XXX it does not handle troubles well :-/ - -if not util.safehasattr(templatekw, 'showobsolete'): - # hg < 4.2 - @eh.templatekw('obsolete') - def obsoletekw(repo, ctx, templ, **args): - """String. Whether the changeset is ``obsolete``. - """ - if ctx.obsolete(): - return 'obsolete' - return '' if util.safehasattr(templatekw, 'compatlist'): @eh.templatekw('troubles', requires=set(['ctx', 'templ']))
--- a/hgext3rd/topic/__init__.py Tue Aug 28 10:24:18 2018 +0200 +++ b/hgext3rd/topic/__init__.py Tue Aug 28 11:18:58 2018 +0200 @@ -132,7 +132,6 @@ registrar, scmutil, templatefilters, - templatekw, util, ) @@ -149,13 +148,8 @@ topicmap, ) -if util.safehasattr(registrar, 'command'): - commandfunc = registrar.command -else: # compat with hg < 4.3 - commandfunc = cmdutil.command - cmdtable = {} -command = commandfunc(cmdtable) +command = registrar.command(cmdtable) colortable = {'topic.active': 'green', 'topic.list.troubledcount': 'red', 'topic.list.headcount.multiple': 'yellow', @@ -181,7 +175,7 @@ 'topic.active': 'green', } -__version__ = '0.10.1.dev' +__version__ = '0.11.0.dev' testedwith = '4.3.3 4.4.2 4.5.2 4.6.2 4.7' minimumhgversion = '4.3' @@ -231,6 +225,8 @@ default=None, ) +templatekeyword = registrar.templatekeyword() + def _contexttopic(self, force=False): if not (force or self.mutable()): return '' @@ -338,7 +334,6 @@ cmdutil.summaryhooks.add('topic', summaryhook) - templatekw.keywords['topic'] = topickw # Wrap workingctx extra to return the topic name extensions.wrapfunction(context.workingctx, '__init__', wrapinit) # Wrap changelog.add to drop empty topic @@ -510,9 +505,11 @@ 'topics', 'topic', namemap=_namemap, nodemap=_nodemap, listnames=lambda repo: repo.topics)) -def topickw(**args): +@templatekeyword('topic', requires={'ctx'}) +def topickw(context, mapping): """:topic: String. The topic of the changeset""" - return args['ctx'].topic() + ctx = context.resource(mapping, 'ctx') + return ctx.topic() def wrapinit(orig, self, repo, *args, **kwargs): orig(self, repo, *args, **kwargs)
--- a/tests/test-discovery-obshashrange.t Tue Aug 28 10:24:18 2018 +0200 +++ b/tests/test-discovery-obshashrange.t Tue Aug 28 11:18:58 2018 +0200 @@ -1118,3 +1118,31 @@ 5 c8d03c1b5e94 5 1 6 446c2dc3bce5 6 f69452c5b1af 6 1 7 000000000000 +Cache warming capabilities +-------------------------- + + $ hg config experimental.obshashrange + 1 + $ hg config experimental.obshashrange.warm-cache + [1] + $ hg debugupdatecache + $ ls -1 .hg/cache/evoext* + .hg/cache/evoext-depthcache-00 + .hg/cache/evoext-firstmerge-00 + .hg/cache/evoext-obscache-00 + .hg/cache/evoext-stablesortcache-00 + .hg/cache/evoext_obshashrange_v2.sqlite + .hg/cache/evoext_stablerange_v2.sqlite + $ rm -f .hg/cache/evoext* + $ ls -1 .hg/cache/ | grep evoext + [1] + $ hg debugupdatecache --debug + updating the branch cache + invalid branchheads cache (served): tip differs + $ f -s .hg/cache/evoext* + .hg/cache/evoext-depthcache-00: size=96 + .hg/cache/evoext-firstmerge-00: size=96 + .hg/cache/evoext-obscache-00: size=73 + .hg/cache/evoext-stablesortcache-00: size=100 + .hg/cache/evoext_obshashrange_v2.sqlite: size=??* (glob) + .hg/cache/evoext_stablerange_v2.sqlite: size=??* (glob)
--- a/tests/test-evolve.t Tue Aug 28 10:24:18 2018 +0200 +++ b/tests/test-evolve.t Tue Aug 28 11:18:58 2018 +0200 @@ -1164,55 +1164,11 @@ > EOF $ hg next hg: unknown command 'next' - Mercurial Distributed SCM - - basic commands: - - add add the specified files on the next commit - annotate show changeset information by line for each file - clone make a copy of an existing repository - commit commit the specified files or all outstanding changes - diff diff repository (or selected files) - export dump the header and diffs for one or more changesets - forget forget the specified files on the next commit - init create a new repository in the given directory - log show revision history of entire repository or files - merge merge another revision into working directory - pull pull changes from the specified source - push push changes to the specified destination - remove remove the specified files on the next commit - serve start stand-alone webserver - status show changed files in the working directory - summary summarize working directory state - update update working directory (or switch revisions) - - (use 'hg help' for the full list of commands or 'hg -v' for details) + (use 'hg help' for a list of commands) [255] $ hg fold hg: unknown command 'fold' - Mercurial Distributed SCM - - basic commands: - - add add the specified files on the next commit - annotate show changeset information by line for each file - clone make a copy of an existing repository - commit commit the specified files or all outstanding changes - diff diff repository (or selected files) - export dump the header and diffs for one or more changesets - forget forget the specified files on the next commit - init create a new repository in the given directory - log show revision history of entire repository or files - merge merge another revision into working directory - pull pull changes from the specified source - push push changes to the specified destination - remove remove the specified files on the next commit - serve start stand-alone webserver - status show changed files in the working directory - summary summarize working directory state - update update working directory (or switch revisions) - - (use 'hg help' for the full list of commands or 'hg -v' for details) + (use 'hg help' for a list of commands) [255] Enabling commands selectively, only fold enabled, next is still unknown $ cat >> $HGRCPATH <<EOF @@ -1225,30 +1181,7 @@ [255] $ hg next hg: unknown command 'next' - Mercurial Distributed SCM - - basic commands: - - add add the specified files on the next commit - annotate show changeset information by line for each file - clone make a copy of an existing repository - commit commit the specified files or all outstanding changes - diff diff repository (or selected files) - export dump the header and diffs for one or more changesets - fold fold multiple revisions into a single one - forget forget the specified files on the next commit - init create a new repository in the given directory - log show revision history of entire repository or files - merge merge another revision into working directory - pull pull changes from the specified source - push push changes to the specified destination - remove remove the specified files on the next commit - serve start stand-alone webserver - status show changed files in the working directory - summary summarize working directory state - update update working directory (or switch revisions) - - (use 'hg help' for the full list of commands or 'hg -v' for details) + (use 'hg help' for a list of commands) [255] Shows "use 'hg evolve' to..." hints iff the evolve command is enabled