# HG changeset patch # User Pierre-Yves David # Date 1462479182 -7200 # Node ID 77df6101d3b57d625b6c967c9d7e0249f54bef0b # Parent 854421a48e0cf514fdbd064ded7c1a2b8ce04d6e# Parent 5fb7f37b82e6f3024f630aa6aff5fffaf3f9e327 merge default into stable Mercurial 3.8 have been release, let's get ready for a 5.4.0 release. diff -r 854421a48e0c -r 77df6101d3b5 .hgignore --- a/.hgignore Wed Apr 20 16:40:11 2016 -0700 +++ b/.hgignore Thu May 05 22:13:02 2016 +0200 @@ -1,7 +1,5 @@ syntax: re /figures/[^/]+\.png$ -^docs/build/ -^docs/html/ ^html/ \.pyc$ ~$ diff -r 854421a48e0c -r 77df6101d3b5 README --- a/README Wed Apr 20 16:40:11 2016 -0700 +++ b/README Thu May 05 22:13:02 2016 +0200 @@ -21,15 +21,15 @@ We recommend reading the documentation first. An online version is available here: - http://evolution.experimentalworks.net/doc/ + https://www.mercurial-scm.org/doc/evolution/ Or see the ``doc/`` directory for a local copy. Contribute ========== -Bugs are to be reported on the mercurial's bug tracker: http://bz.mercurial-scm.com/ -Use the the "evolution" component. +Bugs are to be reported on the mercurial's bug tracker (component: evolution): +https://bz.mercurial-scm.org/buglist.cgi?component=evolution&query_format=advanced&resolution=--- Please use the patchbomb extension to send email to mercurial devel. Please make sure to use the evolve-ext flag when doing so. You can use a command like @@ -56,6 +56,21 @@ Changelog ========= +5.4.0 -- + +- Some collaboration with the topic experimental extensions, + - hg evolve --all with consider all troubles in your current topic, + - preserve 'topic' during evolve, + - 'next' and 'prev' restrict themself to the current topic by default, +- remove the dangerous 'kill' alias for 'prune' (because 'hg kill -1' without +the leading 'hg' will give you an hardtime) +- during 'hg evolve' skip unsupported merge instead of aborting +- various documentation fix and update +- hg summary now suggest 'hg evolve --continue when appropriate` +- compatibility with Mercurial 3.8 'hgext' namespace package. +- small improvement to the `hg split` instruction +- add a 'metaedit' command to rewrite changeset meta data. + 5.3.0 -- 2016-02-11 - split: add a new command to split changesets, @@ -94,7 +109,7 @@ in now in `--all --any`. - evolve: add a 'experimental.evolutioncommands' for fine grained commands enabling -- next/prev: requires `--merge` to move with uncommited changes +- next/prev: requires `--merge` to move with uncommitted changes - next: significantly reword error messages - next: add a --evolve flag to evolve aspiring children when on a head diff -r 854421a48e0c -r 77df6101d3b5 contrib/nopushpublish.py --- a/contrib/nopushpublish.py Wed Apr 20 16:40:11 2016 -0700 +++ b/contrib/nopushpublish.py Thu May 05 22:13:02 2016 +0200 @@ -27,7 +27,7 @@ ret = orig(repo, remote, outgoing, *args) if npublish: - raise util.Abort("Publishing push forbiden", + raise util.Abort("Publishing push forbidden", hint="Use `hg phase -p ` to manually publish them") return ret diff -r 854421a48e0c -r 77df6101d3b5 debian/control --- a/debian/control Wed Apr 20 16:40:11 2016 -0700 +++ b/debian/control Thu May 05 22:13:02 2016 +0200 @@ -15,7 +15,7 @@ librsvg2-bin, wget, Python-Version: >= 2.6 -Homepage: http://evolution.experimentalworks.net/ +Homepage: https://www.mercurial-scm.org/doc/evolution/ Package: mercurial-evolve Architecture: all diff -r 854421a48e0c -r 77df6101d3b5 docs/evolve-faq.rst --- a/docs/evolve-faq.rst Wed Apr 20 16:40:11 2016 -0700 +++ b/docs/evolve-faq.rst Thu May 05 22:13:02 2016 +0200 @@ -110,7 +110,7 @@ $ hg record # commit the second part $ hg commit - # informs mercurial of what appened + # informs mercurial of what happened # current changeset (.) and previous one (.^) replace A (42) $ hg prune --new . --new .^ 42 diff -r 854421a48e0c -r 77df6101d3b5 docs/evolve-good-practice.rst --- a/docs/evolve-good-practice.rst Wed Apr 20 16:40:11 2016 -0700 +++ b/docs/evolve-good-practice.rst Thu May 05 22:13:02 2016 +0200 @@ -27,7 +27,7 @@ There is no descent conflict detection and handling right now. Rewriting other people's changesets guarantees that you will get conflicts. Communicate with your fellow developers before trying to -touch other people's work (which is a good pratice in any case). +touch other people's work (which is a good practice in any case). Using multiple branches will help you to achieve this goal. diff -r 854421a48e0c -r 77df6101d3b5 docs/from-mq.rst --- a/docs/from-mq.rst Wed Apr 20 16:40:11 2016 -0700 +++ b/docs/from-mq.rst Thu May 05 22:13:02 2016 +0200 @@ -85,7 +85,7 @@ .. $ hg record -m 'feature A' .. # oups, I forgot some stuff .. $ hg record babar.py -.. $ hg amend -c .^ # .^ refer to "working directoy parent, here 'feature A' +.. $ hg amend -c .^ # .^ refer to "working directory parent, here 'feature A' .. note: refresh is an alias for amend diff -r 854421a48e0c -r 77df6101d3b5 docs/obs-terms.rst --- a/docs/obs-terms.rst Wed Apr 20 16:40:11 2016 -0700 +++ b/docs/obs-terms.rst Thu May 05 22:13:02 2016 +0200 @@ -20,7 +20,7 @@ - multiple *successors*: the *precursor* were splits in multiple changesets. -.. The *precursors* and *successors* terms can be used on changeset directy: +.. The *precursors* and *successors* terms can be used on changeset directly: .. :precursors: of a changeset `A` are changesets used as *precursors* by .. obsolete marker using changeset `A` as *successors* @@ -84,8 +84,8 @@ | | | *obsolete* with at least | | | | one non-obsolete descendant | | | | | -| | | Thoses descendants prevent | -| | | properties of extincts | +| | | Those descendants prevent | +| | | properties of extinct | | | | changesets to apply. But | | | | they will refuse to be | | | | pushed without --force. | @@ -169,7 +169,7 @@ | Rewriting operation refuse to work on immutable changeset. | | | | Obsolete markers that refer an immutable changeset as precursors have | -| no effect on the precussors but may have effect on the successors. | +| no effect on the precursors but may have effect on the successors. | | | | When a *mutable* changeset becomes *immutable* (changing its phase from draft| | to public) it is just *immutable* and loose any property of it's former | diff -r 854421a48e0c -r 77df6101d3b5 hgext/__init__.py --- a/hgext/__init__.py Wed Apr 20 16:40:11 2016 -0700 +++ b/hgext/__init__.py Thu May 05 22:13:02 2016 +0200 @@ -1,1 +1,4 @@ -# Copyright 2011 Logilab SA +from __future__ import absolute_import +import pkgutil +__path__ = pkgutil.extend_path(__path__, __name__) + diff -r 854421a48e0c -r 77df6101d3b5 hgext/evolve.py --- a/hgext/evolve.py Wed Apr 20 16:40:11 2016 -0700 +++ b/hgext/evolve.py Thu May 05 22:13:02 2016 +0200 @@ -9,11 +9,11 @@ '''extends Mercurial feature related to Changeset Evolution This extension provides several commands to mutate history and deal with -issues it may raise. +resulting issues. It also: - - enables the "Changeset Obsolescence" feature of mercurial, + - enables the "Changeset Obsolescence" feature of Mercurial, - alters core commands and extensions that rewrite history to use this feature, - improves some aspect of the early implementation in Mercurial core @@ -61,8 +61,12 @@ import sys, os import random -from StringIO import StringIO -import struct +try: + import StringIO as io + StringIO = io.StringIO +except ImportError: + import io + StringIO = io.StringIO import re import collections import socket @@ -231,7 +235,7 @@ c(ui) def final_reposetup(self, ui, repo): - """Method to be used as a the extension reposetup + """Method to be used as the extension reposetup The following operations belong here: @@ -324,7 +328,7 @@ will be applied in the extension commandtable. This argument must be a string that will be searched using `extension.find` if not found and Abort error is raised. If the wrapping applies to an extension, it is - installed during `extsetup` + installed during `extsetup`. example:: @@ -398,7 +402,7 @@ evolveopts = ui.configlist('experimental', 'evolution') if not evolveopts: evolveopts = ['all'] - ui.setconfig('experimental', 'evolution', evolveopts) + ui.setconfig('experimental', 'evolution', evolveopts, 'evolve') @eh.uisetup def _configurecmdoptions(ui): @@ -459,7 +463,7 @@ # - Function to create markers # - useful alias pstatus and pdiff (should probably go in evolve) # - "troubles" method on changectx -# - function to travel throught the obsolescence graph +# - function to travel through the obsolescence graph # - function to find useful changeset to stabilize @@ -468,22 +472,26 @@ @eh.uisetup def _installalias(ui): if ui.config('alias', 'pstatus', None) is None: - ui.setconfig('alias', 'pstatus', 'status --rev .^') + ui.setconfig('alias', 'pstatus', 'status --rev .^', 'evolve') if ui.config('alias', 'pdiff', None) is None: - ui.setconfig('alias', 'pdiff', 'diff --rev .^') + ui.setconfig('alias', 'pdiff', 'diff --rev .^', 'evolve') if ui.config('alias', 'olog', None) is None: - ui.setconfig('alias', 'olog', "log -r 'precursors(.)' --hidden") + ui.setconfig('alias', 'olog', "log -r 'precursors(.)' --hidden", + 'evolve') if ui.config('alias', 'odiff', None) is None: ui.setconfig('alias', 'odiff', - "diff --hidden --rev 'limit(precursors(.),1)' --rev .") + "diff --hidden --rev 'limit(precursors(.),1)' --rev .", + 'evolve') if ui.config('alias', 'grab', None) is None: if os.name == 'nt': ui.setconfig('alias', 'grab', "! " + util.hgexecutable() + " rebase --dest . --rev $@ && " - + util.hgexecutable() + " up tip") + + util.hgexecutable() + " up tip", + 'evolve') else: ui.setconfig('alias', 'grab', - "! $HG rebase --dest . --rev $@ && $HG up tip") + "! $HG rebase --dest . --rev $@ && $HG up tip", + 'evolve') ### Troubled revset symbol @@ -778,6 +786,10 @@ else: # In 3.6.2, summary in core gained this feature, no need to display it pass + state = _evolvestateread(repo) + if state is not None: + # i18n: column positioning for "hg summary" + ui.write(_('evolve: (evolve --continue)\n')) @eh.extsetup def obssummarysetup(ui): @@ -828,7 +840,7 @@ wlock = repo.wlock() lock = repo.lock() tr = repo.transaction('rewrite') - if len(old.parents()) > 1: #XXX remove this unecessary limitation. + if len(old.parents()) > 1: #XXX remove this unnecessary limitation. raise error.Abort(_('cannot amend merge changesets')) base = old.p1() updatebookmarks = _bookmarksupdater(repo, old.node(), tr) @@ -1079,7 +1091,7 @@ except error.UnknownCommand: # Commands may be disabled return - for alias, e in cmdtable.iteritems(): + for alias, e in cmdtable.items(): if e is entry: break @@ -1455,9 +1467,14 @@ revs = repo.revs(targetcat+'()') if revopt: revs = scmutil.revrange(repo, revopt) & revs - elif not anyopt and targetcat == 'unstable': - revs = set(_aspiringdescendant(repo, - repo.revs('(.::) - obsolete()::'))) + elif not anyopt: + topic = getattr(repo, 'currenttopic', '') + if topic: + revs = repo.revs('topic(%s)', topic) & revs + elif targetcat == 'unstable': + revs = _aspiringdescendant(repo, + repo.revs('(.::) - obsolete()::')) + revs = set(revs) if targetcat == 'divergent': # Pick one divergent per group of divergents revs = _dedupedivergents(repo, revs) @@ -1510,6 +1527,115 @@ ordering.extend(sorted(dependencies)) return ordering +def divergentsets(repo, ctx): + """Compute sets of commits divergent with a given one""" + cache = {} + succsets = {} + base = {} + for n in obsolete.allprecursors(repo.obsstore, [ctx.node()]): + if n == ctx.node(): + # a node can't be a base for divergence with itself + continue + nsuccsets = obsolete.successorssets(repo, n, cache) + for nsuccset in nsuccsets: + if ctx.node() in nsuccset: + # we are only interested in *other* successor sets + continue + if tuple(nsuccset) in base: + # we already know the latest base for this divergency + continue + base[tuple(nsuccset)] = n + divergence = [] + for divset, b in base.iteritems(): + divergence.append({ + 'divergentnodes': divset, + 'commonprecursor': b + }) + + return divergence + +def _preparelistctxs(items, condition): + return [item.hex() for item in items if condition(item)] + +def _formatctx(fm, ctx): + fm.data(node=ctx.hex()) + fm.data(desc=ctx.description()) + fm.data(date=ctx.date()) + fm.data(user=ctx.user()) + +def listtroubles(ui, repo, troublecategories, **opts): + """Print all the troubles for the repo (or given revset)""" + troublecategories = troublecategories or ['divergent', 'unstable', 'bumped'] + showunstable = 'unstable' in troublecategories + showbumped = 'bumped' in troublecategories + showdivergent = 'divergent' in troublecategories + + revs = repo.revs('+'.join("%s()" % t for t in troublecategories)) + if opts.get('rev'): + revs = revs & repo.revs(opts.get('rev')) + + fm = ui.formatter('evolvelist', opts) + for rev in revs: + ctx = repo[rev] + unpars = _preparelistctxs(ctx.parents(), lambda p: p.unstable()) + obspars = _preparelistctxs(ctx.parents(), lambda p: p.obsolete()) + imprecs = _preparelistctxs(repo.set("allprecursors(%n)", ctx.node()), + lambda p: not p.mutable()) + dsets = divergentsets(repo, ctx) + + fm.startitem() + # plain formatter section + hashlen, desclen = 12, 60 + desc = ctx.description() + if desc: + desc = desc.splitlines()[0] + desc = (desc[:desclen] + '...') if len(desc) > desclen else desc + fm.plain('%s: ' % ctx.hex()[:hashlen]) + fm.plain('%s\n' % desc) + fm.data(node=ctx.hex(), rev=ctx.rev(), desc=desc, phase=ctx.phasestr()) + + for unpar in unpars if showunstable else []: + fm.plain(' unstable: %s (unstable parent)\n' % unpar[:hashlen]) + for obspar in obspars if showunstable else []: + fm.plain(' unstable: %s (obsolete parent)\n' % obspar[:hashlen]) + for imprec in imprecs if showbumped else []: + fm.plain(' bumped: %s (immutable precursor)\n' % imprec[:hashlen]) + + if dsets and showdivergent: + for dset in dsets: + fm.plain(' divergent: ') + first = True + for n in dset['divergentnodes']: + t = "%s (%s)" if first else " %s (%s)" + first = False + fm.plain(t % (node.hex(n)[:hashlen], repo[n].phasestr())) + comprec = node.hex(dset['commonprecursor'])[:hashlen] + fm.plain(" (precursor %s)\n" % comprec) + fm.plain("\n") + + # templater-friendly section + _formatctx(fm, ctx) + troubles = [] + for unpar in unpars: + troubles.append({'troubletype': 'unstable', 'sourcenode': unpar, + 'sourcetype': 'unstableparent'}) + for obspar in obspars: + troubles.append({'troubletype': 'unstable', 'sourcenode': obspar, + 'sourcetype': 'obsoleteparent'}) + for imprec in imprecs: + troubles.append({'troubletype': 'bumped', 'sourcenode': imprec, + 'sourcetype': 'immutableprecursor'}) + for dset in dsets: + divnodes = [{'node': node.hex(n), + 'phase': repo[n].phasestr(), + } for n in dset['divergentnodes']] + troubles.append({'troubletype': 'divergent', + 'commonprecursor': node.hex(dset['commonprecursor']), + 'divergentnodes': divnodes}) + fm.data(troubles=troubles) + + fm.end() + @command('^evolve|stabilize|solve', [('n', 'dry-run', False, _('do not perform actions, just print what would be done')), @@ -1525,6 +1651,7 @@ ('a', 'all', False, _('evolve all troubled changesets related to the ' 'current working directory and its descendants')), ('c', 'continue', False, _('continue an interrupted evolution')), + ('l', 'list', False, 'provide details on troubled changesets in the repo'), ] + mergetoolopts, _('[OPTIONS]...')) def evolve(ui, repo, **opts): @@ -1592,9 +1719,13 @@ (the default). You can combine ``--bumped`` or ``--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. """ # Options + listopt = opts['list'] contopt = opts['continue'] anyopt = opts['any'] allopt = opts['all'] @@ -1604,6 +1735,10 @@ revopt = opts['rev'] troublecategories = ['bumped', 'divergent', 'unstable'] specifiedcategories = [t for t in troublecategories if opts[t]] + if listopt: + listtroubles(ui, repo, specifiedcategories, **opts) + return + targetcat = 'unstable' if 1 < len(specifiedcategories): msg = _('cannot specify more than one trouble category to solve (yet)') @@ -1645,7 +1780,7 @@ def progresscb(): if revopt or allopt: - ui.progress(_('evolve'), seen, unit='changesets', total=count) + ui.progress(_('evolve'), seen, unit=_('changesets'), total=count) # Continuation handling if contopt: @@ -1753,10 +1888,12 @@ if not pctx.obsolete(): pctx = orig.p2() # second parent is obsolete ? elif orig.p2().obsolete(): - raise error.Abort(_("no support for evolving merge changesets " - "with two obsolete parents yet"), - hint=_("Redo the merge and use `hg prune " - "--succ ` to obsolete the old one")) + hint = _("Redo the merge (%s) and use `hg prune " + "--succ ` to obsolete the old one") % orig.hex()[:12] + ui.warn(_("warning: no support for evolving merge changesets " + "with two obsolete parents yet\n") + + _("(%s)\n") % hint) + return False if not pctx.obsolete(): ui.warn(_("cannot solve instability of %s, skipping\n") % orig) @@ -2027,14 +2164,14 @@ /!\ * hg up to the parent of the amended changeset (which are named W and Z) /!\ * hg revert --all -r X /!\ * hg ci -m "same message as the amended changeset" => new cset Y -/!\ * hg kill -n Y W Z +/!\ * hg prune -n Y W Z """) if progresscb: progresscb() emtpycommitallowed = repo.ui.backupconfig('ui', 'allowemptycommit') tr = repo.currenttransaction() assert tr is not None try: - repo.ui.setconfig('ui', 'allowemptycommit', True) + repo.ui.setconfig('ui', 'allowemptycommit', True, 'evolve') repo.dirstate.beginparentchange() repo.dirstate.setparents(divergent.node(), node.nullid) repo.dirstate.endparentchange() @@ -2075,6 +2212,7 @@ [('B', 'move-bookmark', False, _('move active bookmark after update')), ('', '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]...') @@ -2095,8 +2233,14 @@ raise parents = wparents[0].parents() + topic = getattr(repo, 'currenttopic', '') + if topic and not opts.get("no_topic", False): + parents = [ctx for ctx in parents if ctx.topic() == topic] displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) - if len(parents) == 1: + if not parents: + ui.warn(_('no parent in topic "%s"\n') % topic) + ui.warn(_('(do you want --no-topic)\n')) + elif len(parents) == 1: p = parents[0] bm = bmactive(repo) shouldmove = opts.get('move_bookmark') and bm is not None @@ -2133,6 +2277,7 @@ _('move active bookmark after update')), ('', 'merge', False, _('bring uncommitted change along')), ('', 'evolve', False, _('evolve the next changeset if necessary')), + ('', 'no-topic', False, _('ignore topic and move topologically')), ('n', 'dry-run', False, _('do not perform actions, just print what would be done'))], '[OPTION]...') @@ -2156,6 +2301,12 @@ raise children = [ctx for ctx in wparents[0].children() if not ctx.obsolete()] + topic = getattr(repo, 'currenttopic', '') + filtered = [] + if topic and not opts.get("no_topic", False): + filtered = [ctx for ctx in children if ctx.topic() != topic] + # XXX N-square membership on children + children = [ctx for ctx in children if ctx not in filtered] displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate}) if len(children) == 1: c = children[0] @@ -2191,8 +2342,17 @@ result = 1 else: aspchildren = _aspiringchildren(repo, [repo['.'].rev()]) + if topic: + filtered.extend(repo[c] for c in children + if repo[c].topic() != topic) + # XXX N-square membership on children + aspchildren = [ctx for ctx in aspchildren if ctx not in filtered] if not opts['evolve'] or not aspchildren: - ui.warn(_('no children\n')) + if filtered: + ui.warn(_('no children on topic "%s"\n') % topic) + ui.warn(_('do you want --no-topic\n')) + else: + ui.warn(_('no children\n')) if aspchildren: msg = _('(%i unstable changesets to be evolved here, ' 'do you want --evolve?)\n') @@ -2272,7 +2432,7 @@ return metadata -@command('^prune|obsolete|kill', +@command('^prune|obsolete', [('n', 'new', [], _("successor changeset (DEPRECATED)")), ('s', 'succ', [], _("successor changeset")), ('r', 'rev', [], _("revisions to prune")), @@ -2349,9 +2509,8 @@ if not precs: raise error.Abort('nothing to prune') - if not obsolete.isenabled(repo, obsolete.allowunstableopt): - if repo.revs("(%ld::) - %ld", revs, revs): - raise error.Abort(_("cannot prune in the middle of a stack")) + if _disallowednewunstable(repo, revs): + raise error.Abort(_("cannot prune in the middle of a stack")) # defines successors changesets sucs = scmutil.revrange(repo, succs) @@ -2359,7 +2518,9 @@ sucs = tuple(repo[n] for n in sucs) if not biject and len(sucs) > 1 and len(precs) > 1: msg = "Can't use multiple successors for multiple precursors" - raise error.Abort(msg) + hint = _("use --biject to mark a series as a replacement" + " for another") + raise error.Abort(msg, hint=hint) elif biject and len(sucs) != len(precs): msg = "Can't use %d successors for %d precursors" \ % (len(sucs), len(precs)) @@ -2685,7 +2846,7 @@ if obsoleted: obsoleted = repo.set('%lr', obsoleted) result = orig(ui, repo, *arg, **kwargs) - if not result: # commit successed + if not result: # commit succeeded new = repo['-1'] oldbookmarks = [] markers = [] @@ -2758,7 +2919,8 @@ def haschanges(): modified, added, removed, deleted = repo.status()[:4] return modified or added or removed or deleted - msg = 'HG: Please, edit the original changeset description.\n\n' + msg = ("HG: This is the original pre-split commit message. " + "Edit it as appropriate.\n\n") msg += ctx.description() opts['message'] = msg opts['edit'] = True @@ -2961,27 +3123,13 @@ ui.write_err(_('single revision specified, nothing to fold\n')) return 1 - roots = repo.revs('roots(%ld)', revs) - if len(roots) > 1: - raise error.Abort(_("cannot fold non-linear revisions " - "(multiple roots given)")) - root = repo[roots.first()] - if root.phase() <= phases.public: - raise error.Abort(_("cannot fold public revisions")) - heads = repo.revs('heads(%ld)', revs) - if len(heads) > 1: - raise error.Abort(_("cannot fold non-linear revisions " - "(multiple heads given)")) - head = repo[heads.first()] - disallowunstable = not obsolete.isenabled(repo, obsolete.allowunstableopt) - if disallowunstable: - if repo.revs("(%ld::) - %ld", revs, revs): - raise error.Abort(_("cannot fold chain not ending with a head "\ - "or with branching")) wlock = lock = None try: wlock = repo.wlock() lock = repo.lock() + + root, head = _foldcheck(repo, revs) + tr = repo.transaction('touch') try: commitopts = opts.copy() @@ -3013,7 +3161,147 @@ finally: lockmod.release(lock, wlock) - +@command('^metaedit', + [('r', 'rev', [], _("revision to edit")), + ('', 'fold', None, _("also fold specified revisions into one")), + ] + commitopts + commitopts2, + _('hg metaedit [OPTION]... [-r] [REV]')) +def metaedit(ui, repo, *revs, **opts): + """edit commit information + + Edits the commit information for the specified revisions. By default, edits + commit information for the working directory parent. + + With --fold, also folds multiple revisions into one if necessary. In this + case, the given revisions must form a linear unbroken chain. + + .. container:: verbose + + Some examples: + + - Edit the commit message for the working directory parent:: + + hg metaedit + + - Change the username for the working directory parent:: + + hg metaedit --user 'New User ' + + - Combine all draft revisions that are ancestors of foo but not of @ into + one:: + + hg metaedit --fold 'draft() and only(foo,@)' + + See :hg:`help phases` for more about draft revisions, and + :hg:`help revsets` for more about the `draft()` and `only()` keywords. + """ + revs = list(revs) + revs.extend(opts['rev']) + if not revs: + if opts['fold']: + raise error.Abort(_('revisions must be specified with --fold')) + revs = ['.'] + + wlock = lock = None + try: + wlock = repo.wlock() + lock = repo.lock() + + revs = scmutil.revrange(repo, revs) + if not opts['fold'] and len(revs) > 1: + # TODO: handle multiple revisions. This is somewhat tricky because + # if we want to edit a series of commits: + # + # a ---- b ---- c + # + # we need to rewrite a first, then directly rewrite b on top of the + # new a, then rewrite c on top of the new b. So we need to handle + # revisions in topological order. + raise error.Abort(_('editing multiple revisions without --fold is ' + 'not currently supported')) + + if opts['fold']: + root, head = _foldcheck(repo, revs) + else: + if repo.revs("%ld and public()", revs): + raise error.Abort(_('cannot edit commit information for public ' + 'revisions')) + newunstable = _disallowednewunstable(repo, revs) + if newunstable: + raise error.Abort( + _('cannot edit commit information in the middle of a stack'), + hint=_('%s will be affected') % repo[newunstable.first()]) + root = head = repo[revs.first()] + + wctx = repo[None] + p1 = wctx.p1() + tr = repo.transaction('metaedit') + newp1 = None + try: + commitopts = opts.copy() + allctx = [repo[r] for r in revs] + targetphase = max(c.phase() for c in allctx) + + if commitopts.get('message') or commitopts.get('logfile'): + commitopts['edit'] = False + else: + if opts['fold']: + msgs = ["HG: This is a fold of %d changesets." % len(allctx)] + msgs += ["HG: Commit message of changeset %s.\n\n%s\n" % + (c.rev(), c.description()) for c in allctx] + else: + msgs = [head.description()] + commitopts['message'] = "\n".join(msgs) + commitopts['edit'] = True + + # TODO: if the author and message are the same, don't create a new + # hash. Right now we create a new hash because the date can be + # different. + newid, created = rewrite(repo, root, allctx, head, + [root.p1().node(), root.p2().node()], + commitopts=commitopts) + if created: + if p1.rev() in revs: + newp1 = newid + phases.retractboundary(repo, tr, targetphase, [newid]) + obsolete.createmarkers(repo, [(ctx, (repo[newid],)) + for ctx in allctx]) + else: + ui.status(_("nothing changed\n")) + tr.close() + finally: + tr.release() + + if opts['fold']: + ui.status('%i changesets folded\n' % len(revs)) + if newp1 is not None: + hg.update(repo, newp1) + finally: + lockmod.release(lock, wlock) + +def _foldcheck(repo, revs): + roots = repo.revs('roots(%ld)', revs) + if len(roots) > 1: + raise error.Abort(_("cannot fold non-linear revisions " + "(multiple roots given)")) + root = repo[roots.first()] + if root.phase() <= phases.public: + raise error.Abort(_("cannot fold public revisions")) + heads = repo.revs('heads(%ld)', revs) + if len(heads) > 1: + raise error.Abort(_("cannot fold non-linear revisions " + "(multiple heads given)")) + head = repo[heads.first()] + if _disallowednewunstable(repo, revs): + raise error.Abort(_("cannot fold chain not ending with a head "\ + "or with branching")) + return root, head + +def _disallowednewunstable(repo, revs): + allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt) + if allowunstable: + return revset.baseset() + return repo.revs("(%ld::) - %ld", revs, revs) @eh.wrapcommand('graft') def graftwrapper(orig, ui, repo, *revs, **kwargs): @@ -3044,7 +3332,7 @@ @eh.extsetup def oldevolveextsetup(ui): - for cmd in ['kill', 'uncommit', 'touch', 'fold']: + for cmd in ['prune', 'uncommit', 'touch', 'fold']: try: entry = extensions.wrapcommand(cmdtable, cmd, warnobserrors) @@ -3246,7 +3534,7 @@ undecided.difference_update(common) - ui.progress(_("comparing with other"), None, total=totalnb) + ui.progress(_("comparing with other"), None) result = dag.headsetofconnecteds(common) ui.debug("%d total queries\n" % roundtrips) @@ -3265,7 +3553,7 @@ return len(self.getvalue()) def read(self, size=None): - obsexcprg(self.ui, self.tell(), unit="bytes", total=self.length) + obsexcprg(self.ui, self.tell(), unit=_("bytes"), total=self.length) return StringIO.read(self, size) def __iter__(self): @@ -3317,11 +3605,11 @@ % (len(markers), len(remotedata), totalbytes), True) for key, data in remotedata: - obsexcprg(repo.ui, sentbytes, item=key, unit="bytes", + obsexcprg(repo.ui, sentbytes, item=key, unit=_("bytes"), total=totalbytes) rslts.append(remote.pushkey('obsolete', key, '', data)) sentbytes += len(data) - obsexcprg(repo.ui, sentbytes, item=key, unit="bytes", + obsexcprg(repo.ui, sentbytes, item=key, unit=_("bytes"), total=totalbytes) obsexcprg(repo.ui, None) if [r for r in rslts if not r]: @@ -3530,12 +3818,12 @@ current = 0 data = StringIO() ui = self.ui - obsexcprg(ui, current, unit="bytes", total=length) + obsexcprg(ui, current, unit=_("bytes"), total=length) while current < length: readsize = min(length - current, chunk) data.write(f.read(readsize)) current += readsize - obsexcprg(ui, current, unit="bytes", total=length) + obsexcprg(ui, current, unit=_("bytes"), total=length) obsexcprg(ui, None) data.seek(0) return data @@ -3718,7 +4006,7 @@ backup = repo.ui.backupconfig('phases', 'new-commit') try: targetphase = max(orig.phase(), phases.draft) - repo.ui.setconfig('phases', 'new-commit', targetphase, 'rebase') + repo.ui.setconfig('phases', 'new-commit', targetphase, 'evolve') # Commit might fail if unresolved files exist nodenew = repo.commit(text=commitmsg, user=orig.user(), date=orig.date(), extra=extra) @@ -3780,7 +4068,7 @@ def _evolvestateread(repo): try: f = repo.vfs('evolvestate') - except IOError, err: + except IOError as err: if err.errno != errno.ENOENT: raise return None @@ -3834,6 +4122,14 @@ bmdeactivate(repo) if keepbranch: repo.dirstate.setbranch(orig.branch()) + if util.safehasattr(repo, 'currenttopic'): + # uurrgs + # there no other topic setter yet + if not orig.topic() and repo.vfs.exists('topic'): + repo.vfs.unlink('topic') + else: + with repo.vfs.open('topic', 'w') as f: + f.write(orig.topic()) try: r = merge.graft(repo, orig, pctx, ['local', 'graft'], True) diff -r 854421a48e0c -r 77df6101d3b5 hgext/obsolete.py --- a/hgext/obsolete.py Wed Apr 20 16:40:11 2016 -0700 +++ b/hgext/obsolete.py Thu May 05 22:13:02 2016 +0200 @@ -3,12 +3,12 @@ # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -"""Deprecated extension that formely introduces "Changeset Obsolescence". +"""Deprecated extension that formerly introduced "Changeset Obsolescence". -This concept is now partially in Mercurial core (starting with mercurial 2.3). -The remaining logic have been grouped with the evolve extension. +This concept is now partially in Mercurial core (starting with Mercurial 2.3). +The remaining logic has been grouped with the evolve extension. -Some code cemains in this extensions to detect and convert prehistoric format +Some code remains in this extensions to detect and convert prehistoric format of obsolete marker than early user may have create. Keep it enabled if you were such user. """ @@ -57,10 +57,10 @@ raise error.Abort('old format of obsolete marker detected!\n' 'run `hg debugconvertobsolete` once.') -def _obsdeserialise(flike): - """read a file like object serialised with _obsserialise +def _obsdeserialize(flike): + """read a file like object serialized with _obsserialize - this desierialize into a {subject -> objects} mapping + this deserialize into a {subject -> objects} mapping this was the very first format ever.""" rels = {} diff -r 854421a48e0c -r 77df6101d3b5 setup.py --- a/setup.py Wed Apr 20 16:40:11 2016 -0700 +++ b/setup.py Thu May 05 22:13:02 2016 +0200 @@ -29,7 +29,7 @@ author='Pierre-Yves David', maintainer='Pierre-Yves David', maintainer_email='pierre-yves.david@ens-lyon.org', - url='http://evolution.experimentalworks.net/', + url='https://www.mercurial-scm.org/doc/evolution/', description='Flexible evolution of Mercurial history.', long_description=open('README').read(), keywords='hg mercurial', diff -r 854421a48e0c -r 77df6101d3b5 tests/test-amend.t --- a/tests/test-amend.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-amend.t Thu May 05 22:13:02 2016 +0200 @@ -107,7 +107,7 @@ $ HGUSER= $ hg amend -e --config ui.username= -m "empty user" abort: no username supplied - (use "hg config --edit" to set your username) + (use 'hg config --edit' to set your username) [255] $ hg sum parent: 8:* tip (glob) diff -r 854421a48e0c -r 77df6101d3b5 tests/test-corrupt.t --- a/tests/test-corrupt.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-corrupt.t Thu May 05 22:13:02 2016 +0200 @@ -101,7 +101,7 @@ summary: add A - $ hg kill --fold -n -1 -- -2 -3 + $ hg prune --fold -n -1 -- -2 -3 2 changesets pruned $ hg push ../other pushing to ../other diff -r 854421a48e0c -r 77df6101d3b5 tests/test-evolve-list.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-evolve-list.t Thu May 05 22:13:02 2016 +0200 @@ -0,0 +1,80 @@ +Set up some configs + $ cat >> $HGRCPATH < [extensions] + > rebase= + > EOF + $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH + +Test the instability listing + $ hg init r2 + $ cd r2 + $ echo a > a && hg ci -Am a + adding a + $ echo b > b && hg ci -Am b + adding b + $ echo c > c && hg ci -Am c + adding c + $ hg up 0 + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo a >> a && hg ci --amend -m a + 2 new unstable changesets + $ hg evolve --list + d2ae7f538514: b + unstable: cb9a9f314b8b (obsolete parent) + + 177f92b77385: c + unstable: d2ae7f538514 (unstable parent) + + $ cd .. + +Test the bumpedness listing + $ hg init r3 + $ cd r3 + $ echo a > a && hg ci -Am a + adding a + $ echo b > b && hg ci --amend -m ab + $ hg phase --public --rev 0 --hidden + 1 new bumped changesets + $ hg evolve --list + 88cc282e27fc: ab + bumped: cb9a9f314b8b (immutable precursor) + + $ cd .. + +Test the divergence listing + $ hg init r1 + $ cd r1 + $ echo a > a && hg ci -Am a + adding a + $ hg up 0 + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo b > b && hg ci -Am b + adding b + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo c > c && hg ci -Am c + adding c + created new head + $ hg up 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo d > d && hg ci -Am d + adding d + created new head + $ hg rebase -s 1 -d 2 + rebasing 1:d2ae7f538514 "b" + $ hg rebase -s 1 -d 3 --hidden --config experimental.allowdivergence=True + rebasing 1:d2ae7f538514 "b" + 2 new divergent changesets + $ hg evolve --list + c882616e9d84: b + divergent: a922b3733e98 (draft) (precursor d2ae7f538514) + + a922b3733e98: b + divergent: c882616e9d84 (draft) (precursor d2ae7f538514) + + $ hg phase -p a922b3733e98 + $ hg evolve --list + c882616e9d84: b + divergent: a922b3733e98 (public) (precursor d2ae7f538514) + + $ cd .. diff -r 854421a48e0c -r 77df6101d3b5 tests/test-evolve-order.t --- a/tests/test-evolve-order.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-evolve-order.t Thu May 05 22:13:02 2016 +0200 @@ -155,6 +155,7 @@ |/ o 15:739f18ac1d03@default(draft) add _d | + ~ Second set of stack with no successor for b2_: $ mkstack "desc(_d)" b1_ b2_ b3_ b4_ >/dev/null @@ -196,6 +197,7 @@ |/ o 15:739f18ac1d03@default(draft) add _d | + ~ Solve the full second stack and only part of the first one $ echo "(desc(_d)::) - desc(c3_)" @@ -232,6 +234,7 @@ |/ o 15:739f18ac1d03@default(draft) add _d | + ~ Test multiple revision with some un-evolvable because parent is splitted ------------------------------------------------------------------------ diff -r 854421a48e0c -r 77df6101d3b5 tests/test-evolve-topic.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-evolve-topic.t Thu May 05 22:13:02 2016 +0200 @@ -0,0 +1,219 @@ + +Check we can find the topic extensions + + $ [ -z "$HGTEST_TOPICROOT" ] && echo 'skipped: $HGTEST_TOPICROOT not set' >&2 && exit 80 + [1] + $ [ ! -e $HGTEST_TOPICROOT/hgext3rd/topic/__init__.py ] && echo 'skipped: no topic repo found at $HGTEST_TOPICROOT' >&2 && exit 80 + [1] + $ cat >> $HGRCPATH < [defaults] + > amend=-d "0 0" + > fold=-d "0 0" + > [phases] + > publish = False + > [ui] + > logtemplate = {rev} - \{{get(namespaces, "topics")}} {node|short} {desc} ({phase})\n + > [diff] + > git = 1 + > unified = 0 + > [extensions] + > rebase = + > topic = $HGTEST_TOPICROOT/hgext3rd/topic/ + > EOF + $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext/evolve.py" >> $HGRCPATH + + $ mkcommit() { + > echo "$1" > "$1" + > hg add "$1" + > hg ci -m "add $1" + > } + +Create a simple setup + + $ hg init repoa + $ cd repoa + $ mkcommit aaa + $ mkcommit bbb + $ hg topic foo + $ mkcommit ccc + $ mkcommit ddd + $ mkcommit eee + $ mkcommit fff + $ hg topic bar + $ mkcommit ggg + $ mkcommit hhh + $ mkcommit iii + $ mkcommit jjj + + $ hg log -G + @ 9 - {bar} 1d964213b023 add jjj (draft) + | + o 8 - {bar} fcab990f3261 add iii (draft) + | + o 7 - {bar} b0c2554835ac add hhh (draft) + | + o 6 - {bar} c748293f1c1a add ggg (draft) + | + o 5 - {foo} 6a6b7365c751 add fff (draft) + | + o 4 - {foo} 3969ab847d9c add eee (draft) + | + o 3 - {foo} 4e3a154f38c7 add ddd (draft) + | + o 2 - {foo} cced9bac76e3 add ccc (draft) + | + o 1 - {} a4dbed0837ea add bbb (draft) + | + o 0 - {} 199cc73e9a0b add aaa (draft) + + +Test that evolve --all evolve the current topic +----------------------------------------------- + +make a mess + + $ hg up foo + switching to topic foo + 0 files updated, 0 files merged, 4 files removed, 0 files unresolved + $ hg topic -l + t4@ add fff (current) + t3: add eee + t2: add ddd + t1: add ccc + ^ add bbb + $ hg up 'desc(ddd)' + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ echo ddd >> ddd + $ hg amend + 6 new unstable changesets + $ hg up 'desc(fff)' + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ echo fff >> fff + $ hg amend + + $ hg log -G + @ 13 - {foo} e104f49bab28 add fff (draft) + | + | o 11 - {foo} d9cacd156ffc add ddd (draft) + | | + | | o 9 - {bar} 1d964213b023 add jjj (draft) + | | | + | | o 8 - {bar} fcab990f3261 add iii (draft) + | | | + | | o 7 - {bar} b0c2554835ac add hhh (draft) + | | | + | | o 6 - {bar} c748293f1c1a add ggg (draft) + | | | + +---x 5 - {foo} 6a6b7365c751 add fff (draft) + | | + o | 4 - {foo} 3969ab847d9c add eee (draft) + | | + x | 3 - {foo} 4e3a154f38c7 add ddd (draft) + |/ + o 2 - {foo} cced9bac76e3 add ccc (draft) + | + o 1 - {} a4dbed0837ea add bbb (draft) + | + o 0 - {} 199cc73e9a0b add aaa (draft) + + +Run evolve --all + + $ hg evolve --all + move:[4] add eee + atop:[11] add ddd + move:[13] add fff + atop:[14] add eee + working directory is now at 070c5573d8f9 + $ hg log -G + @ 15 - {foo} 070c5573d8f9 add fff (draft) + | + o 14 - {foo} 42b49017ff90 add eee (draft) + | + o 11 - {foo} d9cacd156ffc add ddd (draft) + | + | o 9 - {bar} 1d964213b023 add jjj (draft) + | | + | o 8 - {bar} fcab990f3261 add iii (draft) + | | + | o 7 - {bar} b0c2554835ac add hhh (draft) + | | + | o 6 - {bar} c748293f1c1a add ggg (draft) + | | + | x 5 - {foo} 6a6b7365c751 add fff (draft) + | | + | x 4 - {foo} 3969ab847d9c add eee (draft) + | | + | x 3 - {foo} 4e3a154f38c7 add ddd (draft) + |/ + o 2 - {foo} cced9bac76e3 add ccc (draft) + | + o 1 - {} a4dbed0837ea add bbb (draft) + | + o 0 - {} 199cc73e9a0b add aaa (draft) + + +Test that evolve does not loose topic information +------------------------------------------------- + + $ hg evolve --rev 'topic(bar)' + move:[6] add ggg + atop:[15] add fff + move:[7] add hhh + atop:[16] add ggg + move:[8] add iii + atop:[17] add hhh + move:[9] add jjj + atop:[18] add iii + working directory is now at 9bf430c106b7 + $ hg log -G + @ 19 - {bar} 9bf430c106b7 add jjj (draft) + | + o 18 - {bar} d2dc89c57700 add iii (draft) + | + o 17 - {bar} 20bc4d02aa62 add hhh (draft) + | + o 16 - {bar} 16d6f664b17c add ggg (draft) + | + o 15 - {foo} 070c5573d8f9 add fff (draft) + | + o 14 - {foo} 42b49017ff90 add eee (draft) + | + o 11 - {foo} d9cacd156ffc add ddd (draft) + | + o 2 - {foo} cced9bac76e3 add ccc (draft) + | + o 1 - {} a4dbed0837ea add bbb (draft) + | + o 0 - {} 199cc73e9a0b add aaa (draft) + + +Tests next and prev behavior +============================ + +Basic move are restricted to the current topic + + $ hg up foo + switching to topic foo + 0 files updated, 0 files merged, 4 files removed, 0 files unresolved + $ hg prev + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [14] add eee + $ hg next + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [15] add fff + $ hg next + no children on topic "foo" + do you want --no-topic + [1] + $ hg next --no-topic + switching to topic bar + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [16] add ggg + $ hg prev + no parent in topic "bar" + (do you want --no-topic) + $ hg prev --no-topic + switching to topic foo + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [15] add fff diff -r 854421a48e0c -r 77df6101d3b5 tests/test-evolve.t --- a/tests/test-evolve.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-evolve.t Thu May 05 22:13:02 2016 +0200 @@ -2,6 +2,7 @@ > [defaults] > amend=-d "0 0" > fold=-d "0 0" + > metaedit=-d "0 0" > [web] > push_ssl = false > allow_push = * @@ -112,7 +113,7 @@ $ hg log -r 1 --template '{rev} {phase} {obsolete}\n' 1 public stable - $ hg kill 1 + $ hg prune 1 abort: cannot prune immutable changeset: 7c3bad9141dc (see "hg help phases" for details) [255] @@ -123,7 +124,7 @@ $ hg id -n 5 - $ hg kill . + $ hg prune . 0 files updated, 0 files merged, 1 files removed, 0 files unresolved working directory now at fbb94e3a0ecf 1 changesets pruned @@ -136,7 +137,7 @@ test multiple kill - $ hg kill 4 -r 3 + $ hg prune 4 -r 3 0 files updated, 0 files merged, 1 files removed, 0 files unresolved working directory now at 7c3bad9141dc 2 changesets pruned @@ -151,7 +152,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo 4 > g $ hg add g - $ hg kill . + $ hg prune . 0 files updated, 0 files merged, 1 files removed, 0 files unresolved working directory now at 7c3bad9141dc 1 changesets pruned @@ -594,7 +595,7 @@ merging 1 warning: conflicts while merging 1! (edit, then use 'hg resolve --mark') abort: unresolved conflicts, can't continue - (use hg resolve and hg graft --continue) + (use 'hg resolve' and 'hg graft --continue') [255] $ hg log -r7 --template '{rev}:{node|short} {obsolete}\n' 7:a5bfd90a2f29 stable @@ -790,7 +791,7 @@ adding b $ hg mv a c $ hg ci -m c - $ hg kill .^ + $ hg prune .^ 1 changesets pruned 1 new unstable changesets $ hg stab --any @@ -1224,6 +1225,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ $ hg evolve --rev 23 --any abort: cannot specify both "--rev" and "--any" @@ -1262,6 +1264,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ Check that prune respects the allowunstable option $ hg up -C . @@ -1291,6 +1294,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ $ hg up 19 0 files updated, 0 files merged, 2 files removed, 0 files unresolved $ mkcommit c5_ @@ -1312,6 +1316,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ Check that fold respects the allowunstable option $ hg up edc3c9de504e @@ -1329,6 +1334,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ $ hg fold --exact "19 + 18" abort: cannot fold chain not ending with a head or with branching @@ -1356,6 +1362,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ Create a split commit $ printf "oo" > oo; @@ -1392,6 +1399,7 @@ |/ o 18:edc3c9de504e@default(draft) a3 | + ~ $ hg evolve --rev "18::" move:[33] add uu atop:[35] _pp @@ -1446,6 +1454,124 @@ |/ o 36:43c3f5ef149f@default(draft) add uu | + ~ $ hg status newlyadded A newlyadded + +hg metaedit +----------- + + $ hg update --clean . + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ rm newlyadded + $ hg metaedit -r 0 + abort: cannot edit commit information for public revisions + [255] + $ hg metaedit --fold + abort: revisions must be specified with --fold + [255] + $ hg metaedit -r 0 --fold + abort: cannot fold public revisions + [255] + $ hg metaedit '36 + 42' --fold + abort: cannot fold non-linear revisions (multiple roots given) + [255] + $ hg metaedit '36::39 + 41' --fold + abort: cannot fold non-linear revisions (multiple heads given) + [255] +check that metaedit respects allowunstable + $ hg metaedit '.^' --config 'experimental.evolution=createmarkers, allnewcommands' + abort: cannot edit commit information in the middle of a stack + (c904da5245b0 will be affected) + [255] + $ hg metaedit '18::20' --fold --config 'experimental.evolution=createmarkers, allnewcommands' + abort: cannot fold chain not ending with a head or with branching + [255] + $ hg metaedit --user foobar + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg log --template '{rev}: {author}\n' -r '42:' --hidden + 42: test + 43: foobar + $ hg log --template '{rev}: {author}\n' -r . + 43: foobar + +TODO: support this + $ hg metaedit '.^::.' + abort: editing multiple revisions without --fold is not currently supported + [255] + + $ HGEDITOR=cat hg metaedit '.^::.' --fold + HG: This is a fold of 2 changesets. + HG: Commit message of changeset 41. + + amended + + HG: Commit message of changeset 43. + + will be evolved safely + + + + HG: Enter commit message. Lines beginning with 'HG:' are removed. + HG: Leave message empty to abort commit. + HG: -- + HG: user: test + HG: branch 'default' + HG: changed a + HG: changed newfile + 2 changesets folded + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + + $ glog -r . + @ 44:41bf1183869c@default(draft) amended + | + ~ + +no new commit is created here because the date is the same + $ HGEDITOR=cat hg metaedit + amended + + + will be evolved safely + + + HG: Enter commit message. Lines beginning with 'HG:' are removed. + HG: Leave message empty to abort commit. + HG: -- + HG: user: test + HG: branch 'default' + HG: changed a + HG: changed newfile + nothing changed + + $ glog -r '.^::.' + @ 44:41bf1183869c@default(draft) amended + | + o 36:43c3f5ef149f@default(draft) add uu + | + ~ + +TODO: don't create a new commit in this case + $ hg metaedit --config defaults.metaedit= + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg log -r '.^::.' --template '{rev}: {desc|firstline}\n' + 36: add uu + 45: amended + + $ hg up .^ + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg metaedit --user foobar2 45 + $ hg log --template '{rev}: {author}\n' -r '42:' --hidden + 42: test + 43: foobar + 44: test + 45: test + 46: foobar2 + $ hg diff -r 45 -r 46 --hidden + +'fold' one commit + $ hg metaedit 39 --fold --user foobar3 + 1 changesets folded + $ hg log -r 47 --template '{rev}: {author}\n' + 47: foobar3 diff -r 854421a48e0c -r 77df6101d3b5 tests/test-inhibit.t --- a/tests/test-inhibit.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-inhibit.t Thu May 05 22:13:02 2016 +0200 @@ -419,7 +419,7 @@ abort: hidden revision '3'! (use --hidden to access hidden revisions) [255] - $ hg rebase -r ad78ff7d621f -r 53a94305e133 -d 2db36d8066ff + $ hg rebase -r ad78ff7d621f -r 53a94305e133 -d 2db36d8066ff --config experimental.rebaseskipobsolete=0 Warning: accessing hidden changesets 2db36d8066ff for write operation Warning: accessing hidden changesets ad78ff7d621f,53a94305e133 for write operation rebasing 10:ad78ff7d621f "add cK" @@ -536,6 +536,7 @@ |/ o 14:d66ccb8c5871 add cL | + ~ $ hg strip -r 210589181b14 0 files updated, 0 files merged, 1 files removed, 0 files unresolved working directory now at d66ccb8c5871 @@ -557,6 +558,7 @@ |/ o 14:d66ccb8c5871 add cL | + ~ Test prunestrip @@ -572,6 +574,7 @@ | @ 14:d66ccb8c5871 add cL foo | + ~ Check that --hidden used with inhibit does not hide every obsolete commit We show the log before and after a log -G --hidden, they should be the same @@ -803,6 +806,7 @@ $ hg log -G -r "25::" @ 25:71eb4f100663 add pk | + ~ $ hg up -C 22 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ mkcommit Dk @@ -816,6 +820,7 @@ | o 25:71eb4f100663 add pk | + ~ Create a stack (obsolete with succ in dest) -> (not obsolete) -> (not obsolete). Rebase the first two revs of the stack onto dest, we expect to see one new @@ -837,6 +842,7 @@ |/ o 25:71eb4f100663 add pk | + ~ $ hg prune 28 -s 27 1 changesets pruned $ hg up 25 @@ -857,6 +863,7 @@ |/ @ 25:71eb4f100663 add pk | + ~ Rebase the same stack in full on the destination, we expect it to disappear and only see the top revision added to destination. We don\'t expect 29 to be @@ -874,6 +881,7 @@ | @ 25:71eb4f100663 add pk | + ~ Pulling from a inhibit repo to a non-inhibit repo should work diff -r 854421a48e0c -r 77df6101d3b5 tests/test-obsolete-push.t --- a/tests/test-obsolete-push.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-obsolete-push.t Thu May 05 22:13:02 2016 +0200 @@ -25,7 +25,7 @@ $ echo c > c $ hg ci -qAm C c $ hg phase --secret --force . - $ hg kill 0 1 + $ hg prune 0 1 2 changesets pruned 1 new unstable changesets $ glog --hidden diff -r 854421a48e0c -r 77df6101d3b5 tests/test-obsolete.t --- a/tests/test-obsolete.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-obsolete.t Thu May 05 22:13:02 2016 +0200 @@ -457,6 +457,7 @@ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg up 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + 1 other heads for branch "default" $ hg id -n 8 @@ -508,7 +509,7 @@ should not rebase extinct changesets #excluded 'whole rebase set is extinct and ignored.' message not in core - $ hg rebase -b '3' -d 4 --traceback + $ hg rebase -b '3' -d 4 --traceback --config experimental.rebaseskipobsolete=0 rebasing 3:0d3f46688ccc "add obsol_c" rebasing 8:159dfc9fa5d3 "add obsol_d''" (tip) 2 new divergent changesets diff -r 854421a48e0c -r 77df6101d3b5 tests/test-prune.t --- a/tests/test-prune.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-prune.t Thu May 05 22:13:02 2016 +0200 @@ -194,6 +194,7 @@ $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nD")' -s 'desc("add nC")' abort: Can't use multiple successors for multiple precursors + (use --biject to mark a series as a replacement for another) [255] $ hg debugobsolete 9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'} diff -r 854421a48e0c -r 77df6101d3b5 tests/test-sharing.t --- a/tests/test-sharing.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-sharing.t Thu May 05 22:13:02 2016 +0200 @@ -89,6 +89,7 @@ added 1 changesets with 1 changes to 1 files (+1 heads) 2 new obsolescence markers 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + 1 other heads for branch "default" Figure SG03 $ hg shortlog --hidden -G @@ -119,6 +120,7 @@ $ cd ../test-repo $ hg update 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + 1 other heads for branch "default" $ hg shortlog --hidden -G @ 4:de6151c48e1c draft fix bug 37 | @@ -219,6 +221,7 @@ |/ @ 1:de6151c48e1c public fix bug 37 | + ~ Bob commits a draft changeset, pushes to review repo. $ cd ../bob @@ -294,11 +297,13 @@ |/ @ 1:de6151c48e1c public fix bug 37 | + ~ $ hg --hidden -R ../public shortlog -G -r 1:: o 2:540ba8f317e6 public implement feature X (v3) | o 1:de6151c48e1c public fix bug 37 | + ~ How do things look in the review repo? $ cd ../review @@ -315,6 +320,7 @@ |/ @ 1:de6151c48e1c public fix bug 37 | + ~ Meantime, Alice is back from lunch. While she was away, Bob approved her change, so now she can publish it. @@ -328,6 +334,7 @@ |/ o 1:de6151c48e1c public fix bug 37 | + ~ $ hg outgoing -q ../public 4:cbdfbd5a5db2 $ hg push ../public @@ -349,8 +356,10 @@ $ hg log -G -q -r 'head()' o 5:540ba8f317e6 | - | @ 4:cbdfbd5a5db2 - |/ + ~ + @ 4:cbdfbd5a5db2 + | + ~ $ hg --hidden shortlog -G -r 1:: o 5:540ba8f317e6 public implement feature X (v3) | @@ -362,6 +371,7 @@ |/ o 1:de6151c48e1c public fix bug 37 | + ~ Alice rebases her draft changeset on top of Bob's public changeset and publishes the result. @@ -401,6 +411,7 @@ |/ @ 1:de6151c48e1c public fix bug 37 | + ~ $ hg --hidden -R ../public shortlog -G -r 1:: o 3:a06ec1bf97bd public fix bug 15 (v2) | @@ -408,6 +419,7 @@ | o 1:de6151c48e1c public fix bug 37 | + ~ $ cd .. Setup for "cowboy mode" shared mutable history (to illustrate divergent @@ -462,6 +474,7 @@ |/ o 3:a06ec1bf97bd public fix bug 15 (v2) | + ~ Bob discovers the divergence. $ hg pull ../alice @@ -487,6 +500,7 @@ |/ o 3:a06ec1bf97bd public fix bug 15 (v2) | + ~ $ hg --hidden shortlog -r 'successors(2fe6)' 6:a360947f6faf draft fix bug 24 (v2 by bob) 7:e3f99ce9d9cd draft fix bug 24 (v2 by alice) @@ -516,6 +530,7 @@ |/ o 3:a06ec1bf97bd public fix bug 15 (v2) | + ~ $ hg --hidden shortlog -r 'precursors(9)' 6:a360947f6faf draft fix bug 24 (v2 by bob) 7:e3f99ce9d9cd draft fix bug 24 (v2 by alice) diff -r 854421a48e0c -r 77df6101d3b5 tests/test-split.t --- a/tests/test-split.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-split.t Thu May 05 22:13:02 2016 +0200 @@ -123,7 +123,7 @@ summary: add _a -Cannot split a commit with uncommited changes +Cannot split a commit with uncommitted changes $ hg up "desc(_c)" 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ echo "_cd" > _c @@ -267,9 +267,9 @@ | o changeset: 14:aec57822a8ff | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: split1 - | + ~ date: Thu Jan 01 00:00:00 1970 +0000 + summary: split1 + $ hg split < y > y @@ -313,9 +313,9 @@ | o changeset: 14:aec57822a8ff | user: test - | date: Thu Jan 01 00:00:00 1970 +0000 - | summary: split1 - | + ~ date: Thu Jan 01 00:00:00 1970 +0000 + summary: split1 + $ hg book bookA 19:a2b5c9d9b362 * bookB 19:a2b5c9d9b362 diff -r 854421a48e0c -r 77df6101d3b5 tests/test-stabilize-order.t --- a/tests/test-stabilize-order.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-stabilize-order.t Thu May 05 22:13:02 2016 +0200 @@ -132,7 +132,7 @@ no troubled changesets [1] -Test behaviour with --any +Test behavior with --any $ hg up 8 0 files updated, 0 files merged, 1 files removed, 0 files unresolved diff -r 854421a48e0c -r 77df6101d3b5 tests/test-stabilize-result.t --- a/tests/test-stabilize-result.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-stabilize-result.t Thu May 05 22:13:02 2016 +0200 @@ -366,6 +366,6 @@ /!\ * hg up to the parent of the amended changeset (which are named W and Z) /!\ * hg revert --all -r X /!\ * hg ci -m "same message as the amended changeset" => new cset Y - /!\ * hg kill -n Y W Z + /!\ * hg prune -n Y W Z ) [255] diff -r 854421a48e0c -r 77df6101d3b5 tests/test-tutorial.t --- a/tests/test-tutorial.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-tutorial.t Thu May 05 22:13:02 2016 +0200 @@ -74,7 +74,7 @@ Fixing mistake with `hg amend` -------------------------------- -We are versionning a shopping list +We are versioning a shopping list $ cd local $ cat >> shopping << EOF @@ -207,7 +207,7 @@ Getting rid of branchy history ---------------------------------- -While I was working on my list. someone made a change remotly. +While I was working on my list. someone made a change remotely. $ cd ../remote $ hg up -q diff -r 854421a48e0c -r 77df6101d3b5 tests/test-unstable.t --- a/tests/test-unstable.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-unstable.t Thu May 05 22:13:02 2016 +0200 @@ -154,9 +154,8 @@ $ hg evo --all --any --unstable - abort: no support for evolving merge changesets with two obsolete parents yet - (Redo the merge and use `hg prune --succ ` to obsolete the old one) - [255] + warning: no support for evolving merge changesets with two obsolete parents yet + (Redo the merge (6b4280e33286) and use `hg prune --succ ` to obsolete the old one) $ hg log -G @ 5:2db39fda7e2f@default(draft) cprime | diff -r 854421a48e0c -r 77df6101d3b5 tests/test-userguide.t --- a/tests/test-userguide.t Wed Apr 20 16:40:11 2016 -0700 +++ b/tests/test-userguide.t Thu May 05 22:13:02 2016 +0200 @@ -76,6 +76,7 @@ | @ 3:934359450037 draft implement feature Y | + ~ example 5: uncommit files at head (figure 4) $ echo 'relevant' >> file1.c @@ -91,6 +92,7 @@ |/ o 3:934359450037 draft implement feature Y | + ~ $ hg parents --template '{rev}:{node|short} {desc|firstline}\n{files}\n' 6:c8defeecf7a4 fix bug 234 file1.c @@ -121,6 +123,7 @@ |/ o 6:c8defeecf7a4 draft fix bug 234 | + ~ $ hg --hidden log -q -r 'successors(7) | successors(8) | successors(9)' 10:171c6a79a27b $ hg --hidden log -q -r 'precursors(10)' @@ -156,6 +159,7 @@ | o 10:171c6a79a27b draft fix bug 64 | + ~ example 7: amend an older changeset (figures 6, 7) $ hg update -q 11 @@ -180,6 +184,7 @@ |/ o 10:171c6a79a27b draft fix bug 64 | + ~ $ hg evolve -q --all $ hg shortlog -G -r 10:: @ 17:91b4b0f8b5c5 draft feature 23 @@ -190,6 +195,7 @@ | o 10:171c6a79a27b draft fix bug 64 | + ~ setup for example 8: prune an older changeset (figure 8) $ echo 'useful' >> file1.c @@ -207,6 +213,7 @@ | o 17:91b4b0f8b5c5 draft feature 23 | + ~ example 8: prune an older changeset (figures 8, 9) $ hg prune 19 @@ -219,6 +226,7 @@ | o 18:1f33e68b18b9 draft useful work | + ~ $ hg evolve -q --all --any $ hg --hidden shortlog -G -r 18:: @ 21:4393e5877437 draft more work @@ -229,6 +237,7 @@ |/ o 18:1f33e68b18b9 draft useful work | + ~ example 9: uncommit files from an older changeset (discard changes) (figure 10) @@ -246,6 +255,7 @@ | o 21:4393e5877437 draft more work | + ~ $ hg uncommit file2.c 1 new unstable changesets $ hg status @@ -266,6 +276,7 @@ |/ o 21:4393e5877437 draft more work | + ~ $ rm file2.c.orig example 10: uncommit files from an older changeset (keep changes) @@ -284,6 +295,7 @@ | o 25:0d972d6888e6 draft fix bug 67 | + ~ $ hg uncommit file2.c 1 new unstable changesets $ hg status @@ -300,6 +312,7 @@ |/ o 25:0d972d6888e6 draft fix bug 67 | + ~ $ hg evolve --all --any move:[27] new feature atop:[28] fix a bug @@ -317,3 +330,4 @@ |/ o 25:0d972d6888e6 draft fix bug 67 | + ~