--- a/.hgtags Fri Oct 12 15:15:05 2018 +0200
+++ b/.hgtags Thu Oct 25 13:03:30 2018 +0200
@@ -72,3 +72,4 @@
f1cde4c97806fc6d6cc4c1e09ea2f4081a3ebaec 8.1.2
8d8f08245f9715adf48d6f0f59772b04fd7de1f7 8.2.0
c6362c4abd695fb96e2fd63c150c051852303c7e 8.2.1
+45d4b49d81d9ed23e40126f72bfc3fb339522356 8.3.0
--- a/CHANGELOG Fri Oct 12 15:15:05 2018 +0200
+++ b/CHANGELOG Thu Oct 25 13:03:30 2018 +0200
@@ -1,7 +1,15 @@
Changelog
=========
-8.3.0 - in progress
+
+8.3.1 - in progress
+-------------------
+
+ * evolve+topic: fix possible crash during content-divergence evolution
+ * use "new" unstabilities vocabulary in help
+ * compat: compatibility with Mercurial 4.8rc0
+
+8.3.0 -- 2018-10-12
-------------------
* evolve: avoid redundant output when handling linear orphans
@@ -11,6 +19,11 @@
* caches: skip warming the stablerange cache on strip in "auto" mode
* topic: properly register the '{topicidx}' for mercurial <= 4.5
+ * pullbundle: experimental extension to slice pull in multiple slices whose
+ associated bundle can be cached. The extensions is shipped
+ alongside evolve only for convenience. It it requires data
+ structures that currently live in the evolve extensions.
+
8.2.1 -- 2018-09-14
-------------------
--- a/debian/changelog Fri Oct 12 15:15:05 2018 +0200
+++ b/debian/changelog Thu Oct 25 13:03:30 2018 +0200
@@ -1,3 +1,9 @@
+mercurial-evolve (8.3.0-1) unstable; urgency=medium
+
+ * new upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org> Fri, 12 Oct 2018 16:19:17 +0200
+
mercurial-evolve (8.2.1-1) unstable; urgency=medium
* new upstream release
--- a/hgext3rd/evolve/__init__.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/__init__.py Thu Oct 25 13:03:30 2018 +0200
@@ -1043,14 +1043,15 @@
return target, bookmark
@eh.command(
- '^previous',
+ 'previous',
[('B', 'move-bookmark', False,
_('move active bookmark after update')),
('m', 'merge', False, _('bring uncommitted change along')),
('', 'no-topic', False, _('ignore topic and move topologically')),
('n', 'dry-run', False,
_('do not perform actions, just print what would be done'))],
- '[OPTION]...')
+ '[OPTION]...',
+ helpbasic=True)
def cmdprevious(ui, repo, **opts):
"""update to parent revision
@@ -1104,7 +1105,7 @@
lockmod.release(wlock)
@eh.command(
- '^next',
+ 'next',
[('B', 'move-bookmark', False,
_('move active bookmark after update')),
('m', 'merge', False, _('bring uncommitted change along')),
@@ -1112,7 +1113,8 @@
('', 'no-topic', False, _('ignore topic and move topologically')),
('n', 'dry-run', False,
_('do not perform actions, just print what would be done'))],
- '[OPTION]...')
+ '[OPTION]...',
+ helpbasic=True)
def cmdnext(ui, repo, **opts):
"""update to next child revision
--- a/hgext3rd/evolve/cmdrewrite.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/cmdrewrite.py Thu Oct 25 13:03:30 2018 +0200
@@ -95,7 +95,7 @@
interactiveopt = [['i', 'interactive', None, _('use interactive mode')]]
@eh.command(
- '^amend|refresh',
+ 'amend|refresh',
[('A', 'addremove', None,
_('mark new/missing files as added/removed before committing')),
('a', 'all', False, _("match all files")),
@@ -107,7 +107,8 @@
('s', 'secret', None, _('use the secret phase for committing')),
('n', 'note', '', _('store a note on amend')),
] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
- _('[OPTION]... [FILE]...'))
+ _('[OPTION]... [FILE]...'),
+ helpbasic=True)
def amend(ui, repo, *pats, **opts):
"""combine a changeset with updates and replace it with a new one
@@ -660,13 +661,14 @@
return newcm
@eh.command(
- '^fold|squash',
+ 'fold|squash',
[('r', 'rev', [], _("revision to fold")),
('', 'exact', None, _("only fold specified revisions")),
('', 'from', None, _("fold revisions linearly to working copy parent")),
('n', 'note', '', _('store a note on fold')),
] + commitopts + commitopts2 + commitopts3,
- _('hg fold [OPTION]... [-r] REV'))
+ _('hg fold [OPTION]... [-r] REV'),
+ helpbasic=True)
def fold(ui, repo, *revs, **opts):
"""fold multiple revisions into a single one
@@ -937,7 +939,7 @@
return metadata
@eh.command(
- '^prune|obsolete',
+ 'prune|obsolete',
[('n', 'new', [], _("successor changeset (DEPRECATED)")),
('s', 'succ', [], _("successor changeset")),
('r', 'rev', [], _("revisions to prune")),
@@ -952,7 +954,8 @@
_("record a split (on precursor, multiple successors)")),
('B', 'bookmark', [], _("remove revs only reachable from given"
" bookmark"))] + metadataopts,
- _('[OPTION] [-r] REV...'))
+ _('[OPTION] [-r] REV...'),
+ helpbasic=True)
# 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
@@ -1128,11 +1131,12 @@
lockmod.release(tr, lock, wlock)
@eh.command(
- '^split',
+ 'split',
[('r', 'rev', [], _("revision to split")),
('n', 'note', '', _("store a note on split")),
] + commitopts + commitopts2 + commitopts3,
- _('hg split [OPTION]... [-r] REV'))
+ _('hg split [OPTION]... [-r] REV'),
+ helpbasic=True)
def cmdsplit(ui, repo, *revs, **opts):
"""split a changeset into smaller changesets
--- a/hgext3rd/evolve/evolvecmd.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/evolvecmd.py Thu Oct 25 13:03:30 2018 +0200
@@ -1332,7 +1332,7 @@
return divergence
@eh.command(
- '^evolve|stabilize|solve',
+ 'evolve|stabilize|solve',
[('n', 'dry-run', False,
_('do not perform actions, just print what would be done')),
('', 'confirm', False,
@@ -1341,11 +1341,11 @@
_('also consider troubled changesets unrelated to current working '
'directory')),
('r', 'rev', [], _('solves troubles of these revisions')),
- ('', 'bumped', False, _('solves only bumped changesets')),
+ ('', 'bumped', False, _('solves only bumped changesets (DEPRECATED)')),
('', 'phase-divergent', False, _('solves only phase-divergent changesets')),
- ('', 'divergent', False, _('solves only divergent changesets')),
+ ('', 'divergent', False, _('solves only divergent changesets (DEPRECATED)')),
('', 'content-divergent', False, _('solves only content-divergent changesets')),
- ('', 'unstable', False, _('solves only unstable changesets')),
+ ('', 'unstable', False, _('solves only unstable changesets (DEPRECATED)')),
('', 'orphan', False, _('solves only orphan changesets (default)')),
('a', 'all', False, _('evolve all troubled changesets related to the '
'current working directory and its descendants')),
@@ -1356,26 +1356,27 @@
('l', 'list', False, _('provide details on troubled changesets'
' in the repo')),
] + mergetoolopts,
- _('[OPTIONS]...')
+ _('[OPTIONS]...'),
+ helpbasic=True
)
def evolve(ui, repo, **opts):
"""solve troubled changesets in your repository
Modifying history can lead to various types of troubled changesets:
- unstable, bumped, or divergent. The evolve command resolves your troubles
- by executing one of the following actions:
+ orphan, phase-divergent, or content-divergent. The evolve command resolves
+ your troubles by executing one of the following actions:
- update working copy to a successor
- - rebase an unstable changeset
- - extract the desired changes from a bumped changeset
- - fuse divergent changesets back together
+ - rebase an orphan changeset
+ - extract the desired changes from a phase-divergent changeset
+ - fuse content-divergent changesets back together
If you pass no arguments, evolve works in automatic mode: it will execute a
single action to reduce instability related to your working copy. There are
two cases for this action. First, if the parent of your working copy is
obsolete, evolve updates to the parent's successor. Second, if the working
copy parent is not obsolete but has obsolete predecessors, then evolve
- determines if there is an unstable changeset that can be rebased onto the
+ determines if there is an orphan changeset that can be rebased onto the
working copy parent in order to reduce instability.
If so, evolve rebases that changeset. If not, evolve refuses to guess your
intention, and gives a hint about what you might want to do next.
@@ -1385,24 +1386,24 @@
as well; this may change in future.)
Automatic mode only handles common use cases. For example, it avoids taking
- action in the case of ambiguity, and it ignores unstable changesets that
- are not related to your working copy.
- It also refuses to solve bumped or divergent changesets unless you
- explicitly request such behavior (see below).
+ action in the case of ambiguity, and it ignores orphan changesets that are
+ not related to your working copy.
+ It also refuses to solve phase-divergent or content-divergent changesets
+ unless you explicitly request such behavior (see below).
Eliminating all instability around your working copy may require multiple
invocations of :hg:`evolve`. Alternately, use ``--all`` to recursively
- select and evolve all unstable changesets that can be rebased onto the
+ select and evolve all orphan changesets that can be rebased onto the
working copy parent.
This is more powerful than successive invocations, since ``--all`` handles
- ambiguous cases (e.g. unstable changesets with multiple children) by
- evolving all branches.
+ ambiguous cases (e.g. orphan changesets with multiple children) by evolving
+ all branches.
When your repository cannot be handled by automatic mode, you might need to
use ``--rev`` to specify a changeset to evolve. For example, if you have
- an unstable changeset that is not related to the working copy parent,
+ an orphan changeset that is not related to the working copy parent,
you could use ``--rev`` to evolve it. Or, if some changeset has multiple
- unstable children, evolve in automatic mode refuses to guess which one to
+ orphan children, evolve in automatic mode refuses to guess which one to
evolve; you have to use ``--rev`` in that case.
Alternately, ``--any`` makes evolve search for the next evolvable changeset
@@ -1410,22 +1411,23 @@
You can supply multiple revisions to evolve multiple troubled changesets
in a single invocation. In revset terms, ``--any`` is equivalent to ``--rev
- first(unstable())``. ``--rev`` and ``--all`` are mutually exclusive, as are
+ first(orphan())``. ``--rev`` and ``--all`` are mutually exclusive, as are
``--rev`` and ``--any``.
``hg evolve --any --all`` is useful for cleaning up instability across all
branches, letting evolve figure out the appropriate order and destination.
- When you have troubled changesets that are not unstable, :hg:`evolve`
- refuses to consider them unless you specify the category of trouble you
- wish to resolve, with ``--bumped`` or ``--divergent``. These options are
- currently mutually exclusive with each other and with ``--unstable``
- (the default). You can combine ``--bumped`` or ``--divergent`` with
- ``--rev``, ``--all``, or ``--any``.
+ When you have troubled changesets that are not orphan, :hg:`evolve` refuses
+ to consider them unless you specify the category of trouble you
+ wish to resolve, with ``--phase-divergent`` or ``--content-divergent``.
+ These options are currently mutually exclusive with each other and with
+ ``--orphan`` (the default). You can combine ``--phase-divergent`` or
+ ``--content-divergent`` with ``--rev``, ``--all``, or ``--any``.
You can also use the evolve command to list the troubles affecting your
repository by using the --list flag. You can choose to display only some
- categories of troubles with the --unstable, --divergent or --bumped flags.
+ categories of troubles with the --orphan, --content-divergent or
+ --phase-divergent flags.
Interrupted
===========
--- a/hgext3rd/evolve/exthelper.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/exthelper.py Thu Oct 25 13:03:30 2018 +0200
@@ -39,6 +39,14 @@
self._duckpunchers = []
self.cmdtable = {}
self.command = registrar.command(self.cmdtable)
+ if '^init' in commands.table:
+ olddoregister = self.command._doregister
+
+ def _newdoregister(self, name, *args, **kwargs):
+ if kwargs.pop('helpbasic', False):
+ name = '^' + name
+ return olddoregister(self, name, *args, **kwargs)
+ self.command._doregister = _newdoregister
self.configtable = {}
self._configitem = None
--- a/hgext3rd/evolve/metadata.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/metadata.py Thu Oct 25 13:03:30 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.3.0.dev'
+__version__ = '8.3.1.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/rewind.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/evolve/rewind.py Thu Oct 25 13:03:30 2018 +0200
@@ -26,13 +26,14 @@
identicalflag = 4
@eh.command(
- '^rewind|undo',
+ 'rewind|undo',
[('', 'to', [], _("rewind to these revisions")),
('', 'as-divergence', None, _("preserve current latest successors")),
('', 'exact', None, _("only rewind explicitly selected revisions")),
('', 'from', [], _("rewind these revisions to their predecessors")),
],
- _(''))
+ _(''),
+ helpbasic=True)
def rewind(ui, repo, **opts):
"""rewind a stack of changesets to a previous state
--- a/hgext3rd/pullbundle.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/pullbundle.py Thu Oct 25 13:03:30 2018 +0200
@@ -92,9 +92,9 @@
from mercurial.i18n import _
-__version__ = '0.1.0.dev'
-testedwith = '4.7.1'
-# minimumhgversion = ''
+__version__ = '0.1.1'
+testedwith = '4.4 4.5 4.6 4.7.1'
+minimumhgversion = '4.4'
buglink = 'https://bz.mercurial-scm.org/'
cmdtable = {}
@@ -480,7 +480,7 @@
partdata = (cachedata, nbchanges, pversion)
return _makepartfromstream(newpart, repo, *partdata)
-@command('^debugpullbundlecacheoverlap',
+@command('debugpullbundlecacheoverlap',
[('', 'count', 100, _('of "client" pulling')),
('', 'min-cache', 1, _('minimum size of cached bundle')),
],
--- a/hgext3rd/serverminitopic.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/serverminitopic.py Thu Oct 25 13:03:30 2018 +0200
@@ -67,7 +67,7 @@
if 'branchinfo' in vars(self):
del self.branchinfo
- def branchinfo(self, rev):
+ def branchinfo(self, rev, changelog=None):
"""return branch name and close flag for rev, using and updating
persistent cache."""
phase = self._repo._phasecache.phase(self._repo, rev)
--- a/hgext3rd/topic/__init__.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/topic/__init__.py Thu Oct 25 13:03:30 2018 +0200
@@ -143,7 +143,6 @@
constants,
destination,
discovery,
- evolvebits,
flow,
randomname,
revset as topicrevset,
@@ -178,7 +177,7 @@
'topic.active': 'green',
}
-__version__ = '0.12.0.dev'
+__version__ = '0.12.1.dev'
testedwith = '4.3.3 4.4.2 4.5.2 4.6.2 4.7'
minimumhgversion = '4.3'
@@ -240,19 +239,13 @@
def _contexttopicidx(self):
topic = self.topic()
- if not topic:
+ if not topic or self.obsolete():
# XXX we might want to include s0 here,
# however s0 is related to 'currenttopic' which has no place here.
return None
revlist = stack.stack(self._repo, topic=topic)
try:
return revlist.index(self.rev())
- except ValueError:
- if self.obsolete():
- succ = evolvebits._singlesuccessor(self._repo, self)
- if succ not in revlist:
- return None
- return revlist.index(succ)
except IndexError:
# Lets move to the last ctx of the current topic
return None
--- a/hgext3rd/topic/discovery.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/topic/discovery.py Thu Oct 25 13:03:30 2018 +0200
@@ -81,9 +81,11 @@
def revbranchcache(self):
rbc = super(repocls, self).revbranchcache()
- changelog = self.changelog
+ localchangelog = self.changelog
- def branchinfo(rev):
+ def branchinfo(rev, changelog=None):
+ if changelog is None:
+ changelog = localchangelog
branch, close = changelog.branchinfo(rev)
if rev in publishedset:
return branch, close
--- a/hgext3rd/topic/topicmap.py Fri Oct 12 15:15:05 2018 +0200
+++ b/hgext3rd/topic/topicmap.py Thu Oct 25 13:03:30 2018 +0200
@@ -203,7 +203,7 @@
unfi = repo.unfiltered()
oldgetbranchinfo = unfi.revbranchcache().branchinfo
- def branchinfo(r):
+ def branchinfo(r, changelog=None):
info = oldgetbranchinfo(r)
topic = ''
ctx = unfi[r]
--- a/tests/test-topic-stack-complex.t Fri Oct 12 15:15:05 2018 +0200
+++ b/tests/test-topic-stack-complex.t Thu Oct 25 13:03:30 2018 +0200
@@ -134,3 +134,46 @@
s2@ split1 (current)
s1: Added a and b
s0^ Added foo (base)
+
+Test case with divergence
+-------------------------
+
+ $ hg evolve --all
+ move:[s3] split2
+ atop:[s2] split1
+ move:[s4] Added e and f
+ working directory is now at ec94a1ed1330
+ $ hg up s4
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg id -r .
+ ec94a1ed1330 tip
+ $ hg up --hidden 'min(precursors(.))'
+ updating to a hidden changeset f1d3649d6a8b
+ (hidden revision 'f1d3649d6a8b' was rewritten as: ec94a1ed1330)
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory parent is obsolete! (f1d3649d6a8b)
+ (use 'hg evolve' to update to its successor: ec94a1ed1330)
+ $ hg amend -d '0 1'
+ 1 new orphan changesets
+ 2 new content-divergent changesets
+ $ hg rebase -r . -d ec94a1ed1330~1
+ rebasing 9:eb3b16fef8ea "Added e and f" (tip foo)
+ $ hg stack
+ ### topic: foo (2 heads)
+ ### target: default (branch)
+ s5: Added e and f
+ s3^ split2 (base)
+ s4@ Added e and f (current)
+ s3: split2
+ s2: split1
+ s1: Added a and b
+ s0^ Added foo (base)
+
+ $ hg evolve --content-divergent -r ec94a1ed1330
+ merge:[s5] Added e and f
+ with: [s4] Added e and f
+ base: [s] Added e and f
+ updating to "local" side of the conflict: ec94a1ed1330
+ merging "other" content-divergent changeset 'f2eff98490d2'
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ working directory is now at 8faad6276dc6