merge default into stable
Mercurial 3.8 have been release, let's get ready for a 5.4.0 release.
--- 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$
~$
--- 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
--- 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 <rev>` to manually publish them")
return ret
--- 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
--- 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
--- 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.
--- 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
--- 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 |
--- 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 <contact@logilab.fr>
+from __future__ import absolute_import
+import pkgutil
+__path__ = pkgutil.extend_path(__path__, __name__)
+
--- 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 <old> "
- "--succ <new>` to obsolete the old one"))
+ hint = _("Redo the merge (%s) and use `hg prune <old> "
+ "--succ <new>` 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 <new-email@example.com>'
+
+ - 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)
--- 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 = {}
--- 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',
--- 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)
--- 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
--- /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 <<EOF
+ > [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 ..
--- 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
------------------------------------------------------------------------
--- /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 <<EOF
+ > [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
--- 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
--- 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
--- 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
--- 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
--- 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'}
--- 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)
--- 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 <<EOF
> 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
--- 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
--- 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]
--- 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
--- 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 <old> --succ <new>` 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 <old> --succ <new>` to obsolete the old one)
$ hg log -G
@ 5:2db39fda7e2f@default(draft) cprime
|
--- 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
|
+ ~