# HG changeset patch # User Pierre-Yves David # Date 1462485614 -7200 # Node ID dd6f090b7342255410e10a7c64c1a3a4cda4c3ed # Parent c2739551ea4e7b356c3f4b7f54b5c04b96d1e78d# Parent 093c445fd86a63d6c76848da61f10098bf3ab606 merge with stable throug 3.6 branch diff -r c2739551ea4e -r dd6f090b7342 .hgignore --- a/.hgignore Thu Feb 11 00:07:54 2016 +0000 +++ b/.hgignore Fri May 06 00:00:14 2016 +0200 @@ -1,7 +1,5 @@ syntax: re /figures/[^/]+\.png$ -^docs/build/ -^docs/html/ ^html/ \.pyc$ ~$ @@ -14,3 +12,4 @@ ^MANIFEST$ ^docs/tutorials/.*\.rst$ \.ico$ +tests/\.testtimes diff -r c2739551ea4e -r dd6f090b7342 .hgtags --- a/.hgtags Thu Feb 11 00:07:54 2016 +0000 +++ b/.hgtags Fri May 06 00:00:14 2016 +0200 @@ -38,3 +38,4 @@ 00026533ff9f52733a45df008e3d56a5d3a8e76a 5.2.0 44a9dcb3fefcf8281ebe4e359e7dbb637512cf7f 5.2.0 c15d6168412f175568dac89e6ee1cd8434fef906 5.2.1 +bd59cc2ee2039c370a0343f683488cde2a106565 5.3.0 diff -r c2739551ea4e -r dd6f090b7342 README --- a/README Thu Feb 11 00:07:54 2016 +0000 +++ b/README Fri May 06 00:00:14 2016 +0200 @@ -16,20 +16,20 @@ You can enable it by adding the line below to the ``extensions`` section of your hgrc:: - evolve = PATH/TO/mutable-history/hgext/evolve.py + evolve = PATH/TO/evolve-main/hgext/evolve.py 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,19 +56,33 @@ Changelog ========= -5.3.0 -- +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, - tests: drop our copy of 'run-tests.py' use core one instead, - bookmark: do all bookmark movement within a transaction. - evolve: compatibility with Mercurial 3.7 -- evolve: support merge with a single obsolete parent. +- evolve: support merge with a single obsolete parent (hg-3.7+ only) - evolve: prevent added file to be marked as unknown if evolve fails (issue4966) - evolve: stop relying on graftstate file for save evolve state (for `hg evolve --continue`) - -5.2.2 -- - +- evolve: fix divergence resolution when it result in an empty commit + (issue4950) (hg-3.5+ only) - no longer lock the repository for `hg parents` (issue4895) - updated help for the `evolve` command @@ -95,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 c2739551ea4e -r dd6f090b7342 contrib/nopushpublish.py --- a/contrib/nopushpublish.py Thu Feb 11 00:07:54 2016 +0000 +++ b/contrib/nopushpublish.py Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 debian/control --- a/debian/control Thu Feb 11 00:07:54 2016 +0000 +++ b/debian/control Fri May 06 00:00:14 2016 +0200 @@ -15,7 +15,7 @@ librsvg2-bin, wget, Python-Version: >= 2.6 -Homepage: https://bitbucket.org/marmoute/mutable-history +Homepage: https://www.mercurial-scm.org/doc/evolution/ Package: mercurial-evolve Architecture: all diff -r c2739551ea4e -r dd6f090b7342 debian/copyright --- a/debian/copyright Thu Feb 11 00:07:54 2016 +0000 +++ b/debian/copyright Fri May 06 00:00:14 2016 +0200 @@ -1,5 +1,5 @@ This software was downloaded from -https://bitbucket.org/marmoute/mutable-history +http://hg.netv6.net/evolve-main/ Copyright 2011 Peter Arrenbrecht Logilab SA diff -r c2739551ea4e -r dd6f090b7342 docs/evolve-faq.rst --- a/docs/evolve-faq.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/evolve-faq.rst Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 docs/evolve-good-practice.rst --- a/docs/evolve-good-practice.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/evolve-good-practice.rst Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 docs/from-mq.rst --- a/docs/from-mq.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/from-mq.rst Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 docs/index.rst --- a/docs/index.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/index.rst Fri May 06 00:00:14 2016 +0200 @@ -113,7 +113,7 @@ #. Clone the ``evolve`` repository:: cd ~/src - hg clone https://bitbucket.org/marmoute/mutable-history + hg clone http://hg.netv6.net/evolve-main #. Configure the extension, either locally :: @@ -125,7 +125,7 @@ Then add :: - evolve=~/src/mutable-history/hgext/evolve.py + evolve=~/src/evolve-main/hgext/evolve.py in the ``[extensions]`` section (adding the section if necessary). Use the directory that you actually cloned to, of course. diff -r c2739551ea4e -r dd6f090b7342 docs/obs-terms.rst --- a/docs/obs-terms.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/obs-terms.rst Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 docs/sharing.rst --- a/docs/sharing.rst Thu Feb 11 00:07:54 2016 +0000 +++ b/docs/sharing.rst Fri May 06 00:00:14 2016 +0200 @@ -102,7 +102,7 @@ publish = false [extensions] - evolve = /path/to/mutable-history/hgext/evolve.py + evolve = /path/to/evolve-main/hgext/evolve.py Then edit the configuration for ``dev-repo``:: @@ -111,7 +111,7 @@ and add :: [extensions] - evolve = /path/to/mutable-history/hgext/evolve.py + evolve = /path/to/evolve-main/hgext/evolve.py Keep in mind that in real life, these repositories would probably be on separate computers, so you'd have to login to each one to configure @@ -331,7 +331,7 @@ and add :: [extensions] - evolve = /path/to/mutable-history/hgext/evolve.py + evolve = /path/to/evolve-main/hgext/evolve.py Then edit Bob's repository configuration:: @@ -545,7 +545,7 @@ [extensions] rebase = - evolve = /path/to/mutable-history/hgext/evolve.py + evolve = /path/to/evolve-main/hgext/evolve.py [phases] publish = false diff -r c2739551ea4e -r dd6f090b7342 hgext/__init__.py --- a/hgext/__init__.py Thu Feb 11 00:07:54 2016 +0000 +++ b/hgext/__init__.py Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 hgext/evolve.py --- a/hgext/evolve.py Thu Feb 11 00:07:54 2016 +0000 +++ b/hgext/evolve.py Fri May 06 00:00:14 2016 +0200 @@ -9,18 +9,18 @@ '''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 ''' -__version__ = '5.2.1' -testedwith = '3.4.3 3.5.2 3.6' +__version__ = '5.3.0' +testedwith = '3.4.3 3.5.2 3.6.2 3.7' buglink = 'http://bz.selenic.com/' @@ -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 @@ -1130,7 +1142,7 @@ ctx = unfi[rev] parents = tuple(p.node() for p in ctx.parents()) before = len(store._all) - store.create(tr, mark[0], mark[1], mark[2], marks[3], + store.create(tr, mark[0], mark[1], mark[2], mark[3], parents=parents) if len(store._all) - before: ui.write(_('created new markers for %i\n') % rev) @@ -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) @@ -1998,7 +2135,14 @@ hg.update(repo, divergent.rev()) repo.ui.note(_('merging divergent changeset\n')) if progresscb: progresscb() - if 'partial' in merge.update.__doc__: + try: + stats = merge.update(repo, + other.node(), + branchmerge=True, + force=False, + ancestor=base.node(), + mergeancestor=True) + except TypeError: # Mercurial < 43c00ca887d1 (3.7) stats = merge.update(repo, other.node(), @@ -2007,13 +2151,6 @@ partial=None, ancestor=base.node(), mergeancestor=True) - else: - stats = merge.update(repo, - other.node(), - branchmerge=True, - force=False, - ancestor=base.node(), - mergeancestor=True) hg._showstats(repo, stats) if stats[3]: @@ -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 = [] @@ -2709,7 +2870,7 @@ lockmod.release(tr, lock, wlock) @command('^split', - [('r', 'rev', [], _("revision to fold")), + [('r', 'rev', [], _("revision to split")), ] + commitopts + commitopts2, _('hg split [OPTION]... [-r] REV')) def cmdsplit(ui, repo, *revs, **opts): @@ -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 c2739551ea4e -r dd6f090b7342 hgext/obsolete.py --- a/hgext/obsolete.py Thu Feb 11 00:07:54 2016 +0000 +++ b/hgext/obsolete.py Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 setup.py --- a/setup.py Thu Feb 11 00:07:54 2016 +0000 +++ b/setup.py Fri May 06 00:00:14 2016 +0200 @@ -29,7 +29,7 @@ author='Pierre-Yves David', maintainer='Pierre-Yves David', maintainer_email='pierre-yves.david@ens-lyon.org', - url='https://bitbucket.org/marmoute/mutable-history', + url='https://www.mercurial-scm.org/doc/evolution/', description='Flexible evolution of Mercurial history.', long_description=open('README').read(), keywords='hg mercurial', diff -r c2739551ea4e -r dd6f090b7342 tests/test-amend.t diff -r c2739551ea4e -r dd6f090b7342 tests/test-corrupt.t --- a/tests/test-corrupt.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-corrupt.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-divergent.t --- a/tests/test-divergent.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-divergent.t Fri May 06 00:00:14 2016 +0200 @@ -107,5 +107,53 @@ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved 0 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory is now at 6602ff5a79dc - - $ cd .. + +Test None docstring issue of evolve divergent, which caused hg crush + + $ hg init test2 + $ cd test2 + $ mkcommits _a _b + $ hg up "desc(_a)" + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit bdivergent1 + created new head + $ hg up "desc(_a)" + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit bdivergent2 + created new head + $ hg prune -s "desc(bdivergent1)" "desc(_b)" + 1 changesets pruned + $ hg prune -s "desc(bdivergent2)" "desc(_b)" --hidden + 1 changesets pruned + 2 new divergent changesets + $ hg log -G + @ 3:e708fd28d5cf@default(draft) add bdivergent2 [divergent] + | + | o 2:c2f698071cba@default(draft) add bdivergent1 [divergent] + |/ + o 0:135f39f4bd78@default(draft) add _a [] + + $ cat >$TESTTMP/test_extension.py << EOF + > from mercurial import merge + > origupdate = merge.update + > def newupdate(*args, **kwargs): + > return origupdate(*args, **kwargs) + > merge.update = newupdate + > EOF + $ cat >> $HGRCPATH << EOF + > [extensions] + > testextension=$TESTTMP/test_extension.py + > EOF + $ hg evolve --all + nothing to evolve on current working copy parent + (do you want to use --divergent) + [2] + $ hg evolve --divergent + merge:[3] add bdivergent2 + with: [2] add bdivergent1 + base: [1] add _b + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at aa26817f6fbe + + + $ cd .. diff -r c2739551ea4e -r dd6f090b7342 tests/test-evolve-list.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-evolve-list.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-evolve-order.t diff -r c2739551ea4e -r dd6f090b7342 tests/test-evolve.t --- a/tests/test-evolve.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-evolve.t Fri May 06 00:00:14 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 @@ -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 @@ -1450,3 +1451,118 @@ $ 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 c2739551ea4e -r dd6f090b7342 tests/test-obsolete-push.t --- a/tests/test-obsolete-push.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-obsolete-push.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-obsolete.t --- a/tests/test-obsolete.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-obsolete.t Fri May 06 00:00:14 2016 +0200 @@ -508,7 +508,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 c2739551ea4e -r dd6f090b7342 tests/test-prune.t --- a/tests/test-prune.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-prune.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-sharing.t diff -r c2739551ea4e -r dd6f090b7342 tests/test-split.t --- a/tests/test-split.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-split.t Fri May 06 00:00:14 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 diff -r c2739551ea4e -r dd6f090b7342 tests/test-stabilize-order.t --- a/tests/test-stabilize-order.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-stabilize-order.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-stabilize-result.t --- a/tests/test-stabilize-result.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-stabilize-result.t Fri May 06 00:00:14 2016 +0200 @@ -368,6 +368,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 c2739551ea4e -r dd6f090b7342 tests/test-tutorial.t --- a/tests/test-tutorial.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-tutorial.t Fri May 06 00:00:14 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 c2739551ea4e -r dd6f090b7342 tests/test-unstable.t --- a/tests/test-unstable.t Thu Feb 11 00:07:54 2016 +0000 +++ b/tests/test-unstable.t Fri May 06 00:00:14 2016 +0200 @@ -156,9 +156,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 c2739551ea4e -r dd6f090b7342 tests/test-userguide.t