--- a/README Sun Jul 09 15:01:32 2017 +0300
+++ b/README Tue Jul 25 05:52:14 2017 +0200
@@ -121,6 +121,24 @@
Changelog
=========
+6.6.0 - in progress
+-------------------
+
+ - amend: add a --extract flag to move change back to the working copy
+ (same as uncommit, but accessible through the amend commit)
+ - split: now properly refuse to split public changeset
+ - commands: unify and improve the pre-rewrite validation and error message
+ - uncommit: add support for --current-date and --current-user option
+ - fold: add support for --current-date and --current-user option
+ - metaedit: add support for --current-date and --current-user option
+ - split add support for --current-date and --current-user option
+
+ - topic: add --age option to sort topic by the most recently touched,
+ - topic: add a 't0' to access the root of a topic while keeping it active,
+ - topic: allow 'hg prev' to me move to 't0',
+ - topic: add a config option to enforce topic on new commit
+ (experimental.enforce-topic)
+
6.5.0 -- 2017-07-02
-------------------
--- a/hgext3rd/evolve/__init__.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/__init__.py Tue Jul 25 05:52:14 2017 +0200
@@ -214,12 +214,45 @@
Obsolescence markers will be exchanged between repositories that explicitly
assert support for the obsolescence feature (this can currently only be done
-via an extension).""".strip()
+via an extension).
+
+Instability
+==========
+
+(note: the vocabulary is in the process of being updated)
+
+Rewriting changesets might introduce instability (currently 'trouble').
+
+There are two main kinds of instability: orphaning and diverging.
+
+Orphans are changesets left behind when their ancestors are rewritten, (currently: 'unstable').
+Divergence has two variants:
+
+* Content-divergence occurs when independent rewrites of the same changesets
+ lead to different results. (currently: 'divergent')
+
+* Phase-divergence occurs when the old (obsolete) version of a changeset
+ becomes public. (currently: 'bumped')
+
+If it possible to prevent local creation of orphans by using the following config::
+
+ [experimental]
+ evolution=createmarkers,allnewcommands,exchange
+
+You can also enable that option explicitly::
+
+ [experimental]
+ evolution=createmarkers,allnewcommands,allowunstable,exchange
+
+or simply::
+
+ [experimental]
+ evolution=all
+""".strip()
import os
import sys
-import random
import re
import collections
import errno
@@ -243,7 +276,6 @@
import mercurial
from mercurial import util
-from mercurial import repair
from mercurial import obsolete
if not obsolete._enabled:
@@ -270,7 +302,7 @@
scmutil,
)
-from mercurial.commands import walkopts, commitopts, commitopts2, mergetoolopts
+from mercurial.commands import mergetoolopts
from mercurial.i18n import _
from mercurial.node import nullid
@@ -278,11 +310,13 @@
checkheads,
compat,
debugcmd,
+ cmdrewrite,
exthelper,
metadata,
obscache,
obsexchange,
obshistory,
+ rewriteutil,
safeguard,
templatekw,
utility,
@@ -299,6 +333,7 @@
commandopt = 'allnewcommands'
obsexcmsg = utility.obsexcmsg
+shorttemplate = utility.shorttemplate
colortable = {'evolve.node': 'yellow',
'evolve.user': 'green',
@@ -313,7 +348,11 @@
_unpack = struct.unpack
aliases, entry = cmdutil.findcmd('commit', commands.table)
-interactiveopt = [['i', 'interactive', None, _('use interactive mode')]]
+commitopts3 = cmdrewrite.commitopts3
+interactiveopt = cmdrewrite.interactiveopt
+_bookmarksupdater = rewriteutil.bookmarksupdater
+rewrite = rewriteutil.rewrite
+
# This extension contains the following code
#
# - Extension Helper code
@@ -330,6 +369,7 @@
eh.merge(obshistory.eh)
eh.merge(templatekw.eh)
eh.merge(compat.eh)
+eh.merge(cmdrewrite.eh)
uisetup = eh.final_uisetup
extsetup = eh.final_extsetup
reposetup = eh.final_reposetup
@@ -400,25 +440,6 @@
### experimental behavior ###
#####################################################################
-commitopts3 = [
- ('D', 'current-date', None,
- _('record the current date as commit date')),
- ('U', 'current-user', None,
- _('record the current user as committer')),
-]
-
-def _resolveoptions(ui, opts):
- """modify commit options dict to handle related options
-
- For now, all it does is figure out the commit date: respect -D unless
- -d was supplied.
- """
- # N.B. this is extremely similar to setupheaderopts() in mq.py
- if not opts.get('date') and opts.get('current_date'):
- opts['date'] = '%d %d' % util.makedate()
- if not opts.get('user') and opts.get('current_user'):
- opts['user'] = ui.username()
-
getrevs = obsolete.getrevs
#####################################################################
@@ -820,92 +841,6 @@
### changeset rewriting logic
#############################
-def rewrite(repo, old, updates, head, newbases, commitopts):
- """Return (nodeid, created) where nodeid is the identifier of the
- changeset generated by the rewrite process, and created is True if
- nodeid was actually created. If created is False, nodeid
- references a changeset existing before the rewrite call.
- """
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction('rewrite')
- 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)
-
- # commit a new version of the old changeset, including the update
- # collect all files which might be affected
- files = set(old.files())
- for u in updates:
- files.update(u.files())
-
- # Recompute copies (avoid recording a -> b -> a)
- copied = copies.pathcopies(base, head)
-
- # prune files which were reverted by the updates
- def samefile(f):
- if f in head.manifest():
- a = head.filectx(f)
- if f in base.manifest():
- b = base.filectx(f)
- return (a.data() == b.data()
- and a.flags() == b.flags())
- else:
- return False
- else:
- return f not in base.manifest()
- files = [f for f in files if not samefile(f)]
- # commit version of these files as defined by head
- headmf = head.manifest()
-
- def filectxfn(repo, ctx, path):
- if path in headmf:
- fctx = head[path]
- flags = fctx.flags()
- mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
- islink='l' in flags,
- isexec='x' in flags,
- copied=copied.get(path))
- return mctx
- return None
-
- message = cmdutil.logmessage(repo.ui, commitopts)
- if not message:
- message = old.description()
-
- user = commitopts.get('user') or old.user()
- # TODO: In case not date is given, we should take the old commit date
- # if we are working one one changeset or mimic the fold behavior about
- # date
- date = commitopts.get('date') or None
- extra = dict(commitopts.get('extra', old.extra()))
- extra['branch'] = head.branch()
-
- new = context.memctx(repo,
- parents=newbases,
- text=message,
- files=files,
- filectxfn=filectxfn,
- user=user,
- date=date,
- extra=extra)
-
- if commitopts.get('edit'):
- new._text = cmdutil.commitforceeditor(repo, new, [])
- revcount = len(repo)
- newid = repo.commitctx(new)
- new = repo[newid]
- created = len(repo) != revcount
- updatebookmarks(newid)
-
- tr.close()
- return newid, created
- finally:
- lockmod.release(tr, lock, wlock)
-
class MergeFailure(error.Abort):
pass
@@ -974,29 +909,8 @@
_finalizerelocate(repo, orig, dest, nodenew, tr)
return nodenew
-def _bookmarksupdater(repo, oldid, tr):
- """Return a callable update(newid) updating the current bookmark
- and bookmarks bound to oldid to newid.
- """
- def updatebookmarks(newid):
- dirty = False
- oldbookmarks = repo.nodebookmarks(oldid)
- if oldbookmarks:
- for b in oldbookmarks:
- repo._bookmarks[b] = newid
- dirty = True
- if dirty:
- repo._bookmarks.recordchange(tr)
- return updatebookmarks
-
### new command
#############################
-metadataopts = [
- ('d', 'date', '',
- _('record the specified date in metadata'), _('DATE')),
- ('u', 'user', '',
- _('record the specified user in metadata'), _('USER')),
-]
@eh.uisetup
def _installimportobsolete(ui):
@@ -1978,7 +1892,7 @@
with repo.dirstate.parentchange():
repo.dirstate.setparents(divergent.node(), node.nullid)
oldlen = len(repo)
- amend(ui, repo, message='', logfile='')
+ cmdrewrite.amend(ui, repo, message='', logfile='')
if oldlen == len(repo):
new = divergent
# no changes
@@ -2006,7 +1920,68 @@
raise error.Abort("base of divergent changeset %s not found" % ctx,
hint='this case is not yet handled')
-shorttemplate = "[{label('evolve.rev', rev)}] {desc|firstline}\n"
+def _gettopic(ctx):
+ """handle topic fetching with or without the extension"""
+ return getattr(ctx, 'topic', lambda: '')()
+
+def _gettopicidx(ctx):
+ """handle topic fetching with or without the extension"""
+ return getattr(ctx, 'topicidx', lambda: None)()
+
+def _getcurrenttopic(repo):
+ return getattr(repo, 'currenttopic', '')
+
+def _prevupdate(repo, displayer, target, bookmark, dryrun):
+ if dryrun:
+ repo.ui.write(('hg update %s;\n' % target.rev()))
+ if bookmark is not None:
+ repo.ui.write(('hg bookmark %s -r %s;\n'
+ % (bookmark, target.rev())))
+ else:
+ ret = hg.update(repo, target.rev())
+ if not ret:
+ tr = lock = None
+ try:
+ lock = repo.lock()
+ tr = repo.transaction('previous')
+ if bookmark is not None:
+ bmchanges = [(bookmark, target.node())]
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
+ else:
+ bookmarksmod.deactivate(repo)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock)
+
+ displayer.show(target)
+
+def _findprevtarget(repo, displayer, movebookmark=False, topic=True):
+ target = bookmark = None
+ wkctx = repo[None]
+ p1 = wkctx.parents()[0]
+ parents = p1.parents()
+ currenttopic = _getcurrenttopic(repo)
+
+ # we do not filter in the 1 case to allow prev to t0
+ if currenttopic and topic and _gettopicidx(p1) != 1:
+ parents = [ctx for ctx in parents if ctx.topic() == currenttopic]
+
+ # issue message for the various case
+ if p1.node() == node.nullid:
+ repo.ui.warn(_('already at repository root\n'))
+ elif not parents and currenttopic:
+ repo.ui.warn(_('no parent in topic "%s"\n') % currenttopic)
+ repo.ui.warn(_('(do you want --no-topic)\n'))
+ elif len(parents) == 1:
+ target = parents[0]
+ bookmark = None
+ if movebookmark:
+ bookmark = repo._activebookmark
+ else:
+ for p in parents:
+ displayer.show(p)
+ repo.ui.warn(_('multiple parents, explicitly update to one\n'))
+ return target, bookmark
@eh.command(
'^previous',
@@ -2037,44 +2012,22 @@
exc.hint = _('do you want --merge?')
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 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 = repo._activebookmark
- shouldmove = opts.get('move_bookmark') and bm is not None
- if dryrunopt:
- ui.write(('hg update %s;\n' % p.rev()))
- if shouldmove:
- ui.write(('hg bookmark %s -r %s;\n' % (bm, p.rev())))
- else:
- ret = hg.update(repo, p.rev())
- if not ret:
- tr = lock = None
- try:
- lock = repo.lock()
- tr = repo.transaction('previous')
- if shouldmove:
- repo._bookmarks[bm] = p.node()
- repo._bookmarks.recordchange(tr)
- else:
- bookmarksmod.deactivate(repo)
- tr.close()
- finally:
- lockmod.release(tr, lock)
+ topic = not opts.get("no_topic", False)
- displayer.show(p)
+ target, bookmark = _findprevtarget(repo, displayer,
+ opts.get('move_bookmark'), topic)
+ if target is not None:
+ backup = repo.ui.backupconfig('_internal', 'keep-topic')
+ try:
+ if topic and _getcurrenttopic(repo) != _gettopic(target):
+ repo.ui.setconfig('_internal', 'keep-topic', 'yes',
+ source='topic-extension')
+ _prevupdate(repo, displayer, target, bookmark, dryrunopt)
+ finally:
+ repo.ui.restoreconfig(backup)
return 0
else:
- for p in parents:
- displayer.show(p)
- ui.warn(_('multiple parents, explicitly update to one\n'))
return 1
finally:
lockmod.release(wlock)
@@ -2136,8 +2089,8 @@
lock = repo.lock()
tr = repo.transaction('next')
if shouldmove:
- repo._bookmarks[bm] = c.node()
- repo._bookmarks.recordchange(tr)
+ bmchanges = [(bm, c.node())]
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
else:
bookmarksmod.deactivate(repo)
tr.close()
@@ -2188,458 +2141,6 @@
finally:
lockmod.release(wlock)
-def _reachablefrombookmark(repo, revs, bookmarks):
- """filter revisions and bookmarks reachable from the given bookmark
- yoinked from mq.py
- """
- repomarks = repo._bookmarks
- if not bookmarks.issubset(repomarks):
- raise error.Abort(_("bookmark '%s' not found") %
- ','.join(sorted(bookmarks - set(repomarks.keys()))))
-
- # If the requested bookmark is not the only one pointing to a
- # a revision we have to only delete the bookmark and not strip
- # anything. revsets cannot detect that case.
- nodetobookmarks = {}
- for mark, bnode in repomarks.iteritems():
- nodetobookmarks.setdefault(bnode, []).append(mark)
- for marks in nodetobookmarks.values():
- if bookmarks.issuperset(marks):
- rsrevs = repair.stripbmrevset(repo, marks[0])
- revs = set(revs)
- revs.update(set(rsrevs))
- revs = sorted(revs)
- return repomarks, revs
-
-def _deletebookmark(repo, repomarks, bookmarks):
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction('prune')
- for bookmark in bookmarks:
- del repomarks[bookmark]
- repomarks.recordchange(tr)
- tr.close()
- for bookmark in sorted(bookmarks):
- repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
- finally:
- lockmod.release(tr, lock, wlock)
-
-def _getmetadata(**opts):
- metadata = {}
- date = opts.get('date')
- user = opts.get('user')
- if date:
- metadata['date'] = '%i %i' % util.parsedate(date)
- if user:
- metadata['user'] = user
- return metadata
-
-@eh.command(
- '^prune|obsolete',
- [('n', 'new', [], _("successor changeset (DEPRECATED)")),
- ('s', 'succ', [], _("successor changeset")),
- ('r', 'rev', [], _("revisions to prune")),
- ('k', 'keep', None, _("does not modify working copy during prune")),
- ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")),
- ('', 'fold', False,
- _("record a fold (multiple precursors, one successors)")),
- ('', 'split', False,
- _("record a split (on precursor, multiple successors)")),
- ('B', 'bookmark', [], _("remove revs only reachable from given"
- " bookmark"))] + metadataopts,
- _('[OPTION] [-r] REV...'))
-# XXX -U --noupdate option to prevent wc update and or bookmarks update ?
-def cmdprune(ui, repo, *revs, **opts):
- """hide changesets by marking them obsolete
-
- Pruned changesets are obsolete with no successors. If they also have no
- descendants, they are hidden (invisible to all commands).
-
- Non-obsolete descendants of pruned changesets become "unstable". Use :hg:`evolve`
- to handle this situation.
-
- When you prune the parent of your working copy, Mercurial updates the working
- copy to a non-obsolete parent.
-
- You can use ``--succ`` to tell Mercurial that a newer version (successor) of the
- pruned changeset exists. Mercurial records successor revisions in obsolescence
- markers.
-
- You can use the ``--biject`` option to specify a 1-1 mapping (bijection) between
- revisions to pruned (precursor) and successor changesets. This option may be
- removed in a future release (with the functionality provided automatically).
-
- If you specify multiple revisions in ``--succ``, you are recording a "split" and
- must acknowledge it by passing ``--split``. Similarly, when you prune multiple
- changesets with a single successor, you must pass the ``--fold`` option.
- """
- revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
- succs = opts['new'] + opts['succ']
- bookmarks = set(opts.get('bookmark'))
- metadata = _getmetadata(**opts)
- biject = opts.get('biject')
- fold = opts.get('fold')
- split = opts.get('split')
-
- options = [o for o in ('biject', 'fold', 'split') if opts.get(o)]
- if 1 < len(options):
- raise error.Abort(_("can only specify one of %s") % ', '.join(options))
-
- if bookmarks:
- repomarks, revs = _reachablefrombookmark(repo, revs, bookmarks)
- if not revs:
- # no revisions to prune - delete bookmark immediately
- _deletebookmark(repo, repomarks, bookmarks)
-
- if not revs:
- raise error.Abort(_('nothing to prune'))
-
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction('prune')
- # defines pruned changesets
- precs = []
- revs.sort()
- for p in revs:
- cp = repo[p]
- if not cp.mutable():
- # note: createmarkers() would have raised something anyway
- raise error.Abort('cannot prune immutable changeset: %s' % cp,
- hint="see 'hg help phases' for details")
- precs.append(cp)
- if not precs:
- raise error.Abort('nothing to prune')
-
- if _disallowednewunstable(repo, revs):
- raise error.Abort(_("cannot prune in the middle of a stack"),
- hint=_("new unstable changesets are not allowed"))
-
- # defines successors changesets
- sucs = scmutil.revrange(repo, succs)
- sucs.sort()
- 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"
- 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))
- raise error.Abort(msg)
- elif (len(precs) == 1 and len(sucs) > 1) and not split:
- msg = "please add --split if you want to do a split"
- raise error.Abort(msg)
- elif len(sucs) == 1 and len(precs) > 1 and not fold:
- msg = "please add --fold if you want to do a fold"
- raise error.Abort(msg)
- elif biject:
- relations = [(p, (s,)) for p, s in zip(precs, sucs)]
- else:
- relations = [(p, sucs) for p in precs]
-
- wdp = repo['.']
-
- if len(sucs) == 1 and len(precs) == 1 and wdp in precs:
- # '.' killed, so update to the successor
- newnode = sucs[0]
- else:
- # update to an unkilled parent
- newnode = wdp
-
- while newnode in precs or newnode.obsolete():
- newnode = newnode.parents()[0]
-
- if newnode.node() != wdp.node():
- if opts.get('keep', False):
- # This is largely the same as the implementation in
- # strip.stripcmd(). We might want to refactor this somewhere
- # common at some point.
-
- # only reset the dirstate for files that would actually change
- # between the working context and uctx
- descendantrevs = repo.revs("%d::." % newnode.rev())
- changedfiles = []
- for rev in descendantrevs:
- # blindly reset the files, regardless of what actually
- # changed
- changedfiles.extend(repo[rev].files())
-
- # reset files that only changed in the dirstate too
- dirstate = repo.dirstate
- dirchanges = [f for f in dirstate if dirstate[f] != 'n']
- changedfiles.extend(dirchanges)
- repo.dirstate.rebuild(newnode.node(), newnode.manifest(),
- changedfiles)
- dirstate.write(tr)
- else:
- bookactive = repo._activebookmark
- # Active bookmark that we don't want to delete (with -B option)
- # we deactivate and move it before the update and reactivate it
- # after
- movebookmark = bookactive and not bookmarks
- if movebookmark:
- bookmarksmod.deactivate(repo)
- repo._bookmarks[bookactive] = newnode.node()
- repo._bookmarks.recordchange(tr)
- commands.update(ui, repo, newnode.rev())
- ui.status(_('working directory now at %s\n')
- % ui.label(str(newnode), 'evolve.node'))
- if movebookmark:
- bookmarksmod.activate(repo, bookactive)
-
- # update bookmarks
- if bookmarks:
- _deletebookmark(repo, repomarks, bookmarks)
-
- # create markers
- obsolete.createmarkers(repo, relations, metadata=metadata)
-
- # informs that changeset have been pruned
- ui.status(_('%i changesets pruned\n') % len(precs))
-
- for ctx in repo.unfiltered().set('bookmark() and %ld', precs):
- # used to be:
- #
- # ldest = list(repo.set('max((::%d) - obsolete())', ctx))
- # if ldest:
- # c = ldest[0]
- #
- # but then revset took a lazy arrow in the knee and became much
- # slower. The new forms makes as much sense and a much faster.
- for dest in ctx.ancestors():
- if not dest.obsolete():
- updatebookmarks = _bookmarksupdater(repo, ctx.node(), tr)
- updatebookmarks(dest.node())
- break
-
- tr.close()
- finally:
- lockmod.release(tr, lock, wlock)
-
-@eh.command(
- 'amend|refresh',
- [('A', 'addremove', None,
- _('mark new/missing files as added/removed before committing')),
- ('e', 'edit', False, _('invoke editor on commit messages')),
- ('', 'close-branch', None,
- _('mark a branch as closed, hiding it from the branch list')),
- ('s', 'secret', None, _('use the secret phase for committing')),
- ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
- _('[OPTION]... [FILE]...'))
-def amend(ui, repo, *pats, **opts):
- """combine a changeset with updates and replace it with a new one
-
- Commits a new changeset incorporating both the changes to the given files
- and all the changes from the current parent changeset into the repository.
-
- See :hg:`commit` for details about committing changes.
-
- If you don't specify -m, the parent's message will be reused.
-
- Behind the scenes, Mercurial first commits the update as a regular child
- of the current parent. Then it creates a new commit on the parent's parents
- with the updated contents. Then it changes the working copy parent to this
- new combined changeset. Finally, the old changeset and its update are hidden
- from :hg:`log` (unless you use --hidden with log).
-
- Returns 0 on success, 1 if nothing changed.
- """
- opts = opts.copy()
- edit = opts.pop('edit', False)
- log = opts.get('logfile')
- opts['amend'] = True
- if not (edit or opts['message'] or log):
- opts['message'] = repo['.'].description()
- _resolveoptions(ui, opts)
- _alias, commitcmd = cmdutil.findcmd('commit', commands.table)
- return commitcmd[0](ui, repo, *pats, **opts)
-
-
-def _touchedbetween(repo, source, dest, match=None):
- touched = set()
- for files in repo.status(source, dest, match=match)[:3]:
- touched.update(files)
- return touched
-
-def _commitfiltered(repo, ctx, match, target=None):
- """Recommit ctx with changed files not in match. Return the new
- node identifier, or None if nothing changed.
- """
- base = ctx.p1()
- if target is None:
- target = base
- # ctx
- initialfiles = _touchedbetween(repo, base, ctx)
- if base == target:
- affected = set(f for f in initialfiles if match(f))
- newcontent = set()
- else:
- affected = _touchedbetween(repo, target, ctx, match=match)
- newcontent = _touchedbetween(repo, target, base, match=match)
- # The commit touchs all existing files
- # + all file that needs a new content
- # - the file affected bny uncommit with the same content than base.
- files = (initialfiles - affected) | newcontent
- if not newcontent and files == initialfiles:
- return None
-
- # Filter copies
- copied = copies.pathcopies(target, ctx)
- copied = dict((dst, src) for dst, src in copied.iteritems()
- if dst in files)
-
- def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent):
- if path in redirect:
- return filectxfn(repo, memctx, path, contentctx=target, redirect=())
- if path not in contentctx:
- return None
- fctx = contentctx[path]
- flags = fctx.flags()
- mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
- islink='l' in flags,
- isexec='x' in flags,
- copied=copied.get(path))
- return mctx
-
- new = context.memctx(repo,
- parents=[base.node(), node.nullid],
- text=ctx.description(),
- files=files,
- filectxfn=filectxfn,
- user=ctx.user(),
- date=ctx.date(),
- extra=ctx.extra())
- # commitctx always create a new revision, no need to check
- newid = repo.commitctx(new)
- return newid
-
-def _uncommitdirstate(repo, oldctx, match):
- """Fix the dirstate after switching the working directory from
- oldctx to a copy of oldctx not containing changed files matched by
- match.
- """
- ctx = repo['.']
- ds = repo.dirstate
- copies = dict(ds.copies())
- m, a, r = repo.status(oldctx.p1(), oldctx, match=match)[:3]
- for f in m:
- if ds[f] == 'r':
- # modified + removed -> removed
- continue
- ds.normallookup(f)
-
- for f in a:
- if ds[f] == 'r':
- # added + removed -> unknown
- ds.drop(f)
- elif ds[f] != 'a':
- ds.add(f)
-
- for f in r:
- if ds[f] == 'a':
- # removed + added -> normal
- ds.normallookup(f)
- elif ds[f] != 'r':
- ds.remove(f)
-
- # Merge old parent and old working dir copies
- oldcopies = {}
- for f in (m + a):
- src = oldctx[f].renamed()
- if src:
- oldcopies[f] = src[0]
- oldcopies.update(copies)
- copies = dict((dst, oldcopies.get(src, src))
- for dst, src in oldcopies.iteritems())
- # Adjust the dirstate copies
- for dst, src in copies.iteritems():
- if (src not in ctx or dst in ctx or ds[dst] != 'a'):
- src = None
- ds.copy(src, dst)
-
-@eh.command(
- '^uncommit',
- [('a', 'all', None, _('uncommit all changes when no arguments given')),
- ('r', 'rev', '', _('revert commit content to REV instead')),
- ] + commands.walkopts,
- _('[OPTION]... [NAME]'))
-def uncommit(ui, repo, *pats, **opts):
- """move changes from parent revision to working directory
-
- Changes to selected files in the checked out revision appear again as
- uncommitted changed in the working directory. A new revision
- without the selected changes is created, becomes the checked out
- revision, and obsoletes the previous one.
-
- The --include option specifies patterns to uncommit.
- The --exclude option specifies patterns to keep in the commit.
-
- The --rev argument let you change the commit file to a content of another
- revision. It still does not change the content of your file in the working
- directory.
-
- Return 0 if changed files are uncommitted.
- """
-
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- wctx = repo[None]
- if len(wctx.parents()) <= 0:
- raise error.Abort(_("cannot uncommit null changeset"))
- if len(wctx.parents()) > 1:
- raise error.Abort(_("cannot uncommit while merging"))
- old = repo['.']
- if old.phase() == phases.public:
- raise error.Abort(_("cannot rewrite immutable changeset"))
- if len(old.parents()) > 1:
- raise error.Abort(_("cannot uncommit merge changeset"))
- oldphase = old.phase()
-
- rev = None
- if opts.get('rev'):
- rev = scmutil.revsingle(repo, opts.get('rev'))
- ctx = repo[None]
- if ctx.p1() == rev or ctx.p2() == rev:
- raise error.Abort(_("cannot uncommit to parent changeset"))
-
- onahead = old.rev() in repo.changelog.headrevs()
- disallowunstable = not obsolete.isenabled(repo,
- obsolete.allowunstableopt)
- if disallowunstable and not onahead:
- raise error.Abort(_("cannot uncommit in the middle of a stack"))
-
- # Recommit the filtered changeset
- tr = repo.transaction('uncommit')
- updatebookmarks = _bookmarksupdater(repo, old.node(), tr)
- newid = None
- includeorexclude = opts.get('include') or opts.get('exclude')
- if (pats or includeorexclude or opts.get('all')):
- match = scmutil.match(old, pats, opts)
- newid = _commitfiltered(repo, old, match, target=rev)
- if newid is None:
- raise error.Abort(_('nothing to uncommit'),
- hint=_("use --all to uncommit all files"))
- # Move local changes on filtered changeset
- obsolete.createmarkers(repo, [(old, (repo[newid],))])
- phases.retractboundary(repo, tr, oldphase, [newid])
- with repo.dirstate.parentchange():
- repo.dirstate.setparents(newid, node.nullid)
- _uncommitdirstate(repo, old, match)
- updatebookmarks(newid)
- if not repo[newid].files():
- ui.warn(_("new changeset is empty\n"))
- ui.status(_("(use 'hg prune .' to remove it)\n"))
- tr.close()
- finally:
- lockmod.release(tr, lock, wlock)
-
@eh.wrapcommand('commit')
def commitwrapper(orig, ui, repo, *arg, **kwargs):
tr = None
@@ -2662,110 +2163,21 @@
markers.append((old, (new,)))
if markers:
obsolete.createmarkers(repo, markers)
+ bmchanges = []
for book in oldbookmarks:
- repo._bookmarks[book] = new.node()
+ bmchanges.append((book, new.node()))
if oldbookmarks:
if not wlock:
wlock = repo.wlock()
if not lock:
lock = repo.lock()
tr = repo.transaction('commit')
- repo._bookmarks.recordchange(tr)
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
tr.close()
return result
finally:
lockmod.release(tr, lock, wlock)
-def presplitupdate(repo, ui, prev, ctx):
- """prepare the working directory for a split (for topic hooking)
- """
- hg.update(repo, prev)
- commands.revert(ui, repo, rev=ctx.rev(), all=True)
-
-@eh.command(
- '^split',
- [('r', 'rev', [], _("revision to split")),
- ] + commitopts + commitopts2,
- _('hg split [OPTION]... [-r] REV'))
-def cmdsplit(ui, repo, *revs, **opts):
- """split a changeset into smaller changesets
-
- By default, split the current revision by prompting for all its hunks to be
- redistributed into new changesets.
-
- Use --rev to split a given changeset instead.
- """
- tr = wlock = lock = None
- newcommits = []
-
- revarg = (list(revs) + opts.get('rev')) or ['.']
- if len(revarg) != 1:
- msg = _("more than one revset is given")
- hnt = _("use either `hg split <rs>` or `hg split --rev <rs>`, not both")
- raise error.Abort(msg, hint=hnt)
-
- rev = scmutil.revsingle(repo, revarg[0])
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- cmdutil.bailifchanged(repo)
- tr = repo.transaction('split')
- ctx = repo[rev]
- r = ctx.rev()
- disallowunstable = not obsolete.isenabled(repo,
- obsolete.allowunstableopt)
- if disallowunstable:
- # XXX We should check head revs
- if repo.revs("(%d::) - %d", rev, rev):
- raise error.Abort(_("cannot split commit: %s not a head") % ctx)
-
- if len(ctx.parents()) > 1:
- raise error.Abort(_("cannot split merge commits"))
- prev = ctx.p1()
- bmupdate = _bookmarksupdater(repo, ctx.node(), tr)
- bookactive = repo._activebookmark
- if bookactive is not None:
- repo.ui.status(_("(leaving bookmark %s)\n") % repo._activebookmark)
- bookmarksmod.deactivate(repo)
-
- # Prepare the working directory
- presplitupdate(repo, ui, prev, ctx)
-
- def haschanges():
- modified, added, removed, deleted = repo.status()[:4]
- return modified or added or removed or deleted
- 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
- opts['user'] = ctx.user()
- while haschanges():
- pats = ()
- cmdutil.dorecord(ui, repo, commands.commit, 'commit', False,
- cmdutil.recordfilter, *pats, **opts)
- # TODO: Does no seem like the best way to do this
- # We should make dorecord return the newly created commit
- newcommits.append(repo['.'])
- if haschanges():
- if ui.prompt('Done splitting? [yN]', default='n') == 'y':
- commands.commit(ui, repo, **opts)
- newcommits.append(repo['.'])
- break
- else:
- ui.status(_("no more change to split\n"))
-
- if newcommits:
- tip = repo[newcommits[-1]]
- bmupdate(tip.node())
- if bookactive is not None:
- bookmarksmod.activate(repo, bookactive)
- obsolete.createmarkers(repo, [(repo[r], newcommits)])
- tr.close()
- finally:
- lockmod.release(tr, lock, wlock)
-
-
@eh.wrapcommand('strip', extension='strip', opts=[
('', 'bundle', None, _("delete the commit entirely and move it to a "
"backup bundle")),
@@ -2789,354 +2201,7 @@
kwargs['new'] = []
kwargs['succ'] = []
kwargs['biject'] = False
- return cmdprune(ui, repo, *revs, **kwargs)
-
-@eh.command(
- '^touch',
- [('r', 'rev', [], 'revision to update'),
- ('D', 'duplicate', False,
- 'do not mark the new revision as successor of the old one'),
- ('A', 'allowdivergence', False,
- 'mark the new revision as successor of the old one potentially creating '
- 'divergence')],
- # allow to choose the seed ?
- _('[-r] revs'))
-def touch(ui, repo, *revs, **opts):
- """create successors that are identical to their predecessors except
- for the changeset ID
-
- This is used to "resurrect" changesets
- """
- duplicate = opts['duplicate']
- allowdivergence = opts['allowdivergence']
- revs = list(revs)
- revs.extend(opts['rev'])
- if not revs:
- revs = ['.']
- revs = scmutil.revrange(repo, revs)
- if not revs:
- ui.write_err('no revision to touch\n')
- return 1
- if not duplicate and repo.revs('public() and %ld', revs):
- raise error.Abort("can't touch public revision")
- displayer = cmdutil.show_changeset(ui, repo, {'template': shorttemplate})
- wlock = lock = tr = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
- tr = repo.transaction('touch')
- revs.sort() # ensure parent are run first
- newmapping = {}
- for r in revs:
- ctx = repo[r]
- extra = ctx.extra().copy()
- extra['__touch-noise__'] = random.randint(0, 0xffffffff)
- # search for touched parent
- p1 = ctx.p1().node()
- p2 = ctx.p2().node()
- p1 = newmapping.get(p1, p1)
- p2 = newmapping.get(p2, p2)
-
- if not (duplicate or allowdivergence):
- # The user hasn't yet decided what to do with the revived
- # cset, let's ask
- sset = compat.successorssets(repo, ctx.node())
- nodivergencerisk = (len(sset) == 0 or
- (len(sset) == 1 and
- len(sset[0]) == 1 and
- repo[sset[0][0]].rev() == ctx.rev()
- ))
- if nodivergencerisk:
- duplicate = False
- else:
- displayer.show(ctx)
- index = ui.promptchoice(
- _("reviving this changeset will create divergence"
- " unless you make a duplicate.\n(a)llow divergence or"
- " (d)uplicate the changeset? $$ &Allowdivergence $$ "
- "&Duplicate"), 0)
- choice = ['allowdivergence', 'duplicate'][index]
- if choice == 'allowdivergence':
- duplicate = False
- else:
- duplicate = True
-
- new, unusedvariable = rewrite(repo, ctx, [], ctx,
- [p1, p2],
- commitopts={'extra': extra})
- # store touched version to help potential children
- newmapping[ctx.node()] = new
-
- if not duplicate:
- obsolete.createmarkers(repo, [(ctx, (repo[new],))])
- phases.retractboundary(repo, tr, ctx.phase(), [new])
- if ctx in repo[None].parents():
- with repo.dirstate.parentchange():
- repo.dirstate.setparents(new, node.nullid)
- tr.close()
- finally:
- lockmod.release(tr, lock, wlock)
-
-@eh.command(
- '^fold|squash',
- [('r', 'rev', [], _("revision to fold")),
- ('', 'exact', None, _("only fold specified revisions")),
- ('', 'from', None, _("fold revisions linearly to working copy parent"))
- ] + commitopts + commitopts2,
- _('hg fold [OPTION]... [-r] REV'))
-def fold(ui, repo, *revs, **opts):
- """fold multiple revisions into a single one
-
- With --from, folds all the revisions linearly between the given revisions
- and the parent of the working directory.
-
- With --exact, folds only the specified revisions while ignoring the
- parent of the working directory. In this case, the given revisions must
- form a linear unbroken chain.
-
- .. container:: verbose
-
- Some examples:
-
- - Fold the current revision with its parent::
-
- hg fold --from .^
-
- - Fold all draft revisions with working directory parent::
-
- hg fold --from 'draft()'
-
- See :hg:`help phases` for more about draft revisions and
- :hg:`help revsets` for more about the `draft()` keyword
-
- - Fold revisions between 3 and 6 with the working directory parent::
-
- hg fold --from 3::6
-
- - Fold revisions 3 and 4:
-
- hg fold "3 + 4" --exact
-
- - Only fold revisions linearly between foo and @::
-
- hg fold foo::@ --exact
- """
- revs = list(revs)
- revs.extend(opts['rev'])
- if not revs:
- raise error.Abort(_('no revisions specified'))
-
- revs = scmutil.revrange(repo, revs)
-
- if opts['from'] and opts['exact']:
- raise error.Abort(_('cannot use both --from and --exact'))
- elif opts['from']:
- # Try to extend given revision starting from the working directory
- extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
- discardedrevs = [r for r in revs if r not in extrevs]
- if discardedrevs:
- msg = _("cannot fold non-linear revisions")
- hint = _("given revisions are unrelated to parent of working"
- " directory")
- raise error.Abort(msg, hint=hint)
- revs = extrevs
- elif opts['exact']:
- # Nothing to do; "revs" is already set correctly
- pass
- else:
- raise error.Abort(_('must specify either --from or --exact'))
-
- if not revs:
- raise error.Abort(_('specified revisions evaluate to an empty set'),
- hint=_('use different revision arguments'))
- elif len(revs) == 1:
- ui.write_err(_('single revision specified, nothing to fold\n'))
- return 1
-
- wlock = lock = None
- try:
- wlock = repo.wlock()
- lock = repo.lock()
-
- root, head = _foldcheck(repo, revs)
-
- tr = repo.transaction('fold')
- 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:
- 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]
- commitopts['message'] = "\n".join(msgs)
- commitopts['edit'] = True
-
- newid, unusedvariable = rewrite(repo, root, allctx, head,
- [root.p1().node(),
- root.p2().node()],
- commitopts=commitopts)
- phases.retractboundary(repo, tr, targetphase, [newid])
- obsolete.createmarkers(repo, [(ctx, (repo[newid],))
- for ctx in allctx])
- tr.close()
- finally:
- tr.release()
- ui.status('%i changesets folded\n' % len(revs))
- if repo['.'].rev() in revs:
- hg.update(repo, newid)
- finally:
- lockmod.release(lock, wlock)
-
-@eh.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:
- msg = _('cannot edit commit information in the middle'
- ' of a stack')
- hint = _('%s will become unstable and new unstable changes'
- ' are not allowed')
- hint %= repo[newunstable.first()]
- raise error.Abort(msg, hint=hint)
- 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):
- msg = _("cannot fold chain not ending with a head or with branching")
- hint = _("new unstable changesets are not allowed")
- raise error.Abort(msg, hint=hint)
- 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)
+ return cmdrewrite.cmdprune(ui, repo, *revs, **kwargs)
@eh.wrapcommand('graft')
def graftwrapper(orig, ui, repo, *revs, **kwargs):
@@ -3208,23 +2273,24 @@
if new_format == repo.obsstore._version:
msg = _('New format is the same as the old format, not upgrading!')
raise error.Abort(msg)
- f = repo.svfs('obsstore', 'wb', atomictemp=True)
- known = set()
- markers = []
- for m in origmarkers:
- # filter out invalid markers
- if nullid in m[1]:
- m = list(m)
- m[1] = tuple(s for s in m[1] if s != nullid)
- m = tuple(m)
- if m in known:
- continue
- known.add(m)
- markers.append(m)
- ui.write(_('Old store is version %d, will rewrite in version %d\n') % (
- repo.obsstore._version, new_format))
- map(f.write, obsolete.encodemarkers(markers, True, new_format))
- f.close()
+ with repo.lock():
+ f = repo.svfs('obsstore', 'wb', atomictemp=True)
+ known = set()
+ markers = []
+ for m in origmarkers:
+ # filter out invalid markers
+ if nullid in m[1]:
+ m = list(m)
+ m[1] = tuple(s for s in m[1] if s != nullid)
+ m = tuple(m)
+ if m in known:
+ continue
+ known.add(m)
+ markers.append(m)
+ ui.write(_('Old store is version %d, will rewrite in version %d\n') % (
+ repo.obsstore._version, new_format))
+ map(f.write, obsolete.encodemarkers(markers, True, new_format))
+ f.close()
ui.write(_('Done!\n'))
@@ -3265,20 +2331,22 @@
nodesrc = orig.node()
destphase = repo[nodesrc].phase()
oldbookmarks = repo.nodebookmarks(nodesrc)
+ bmchanges = []
+
if nodenew is not None:
phases.retractboundary(repo, tr, destphase, [nodenew])
obsolete.createmarkers(repo, [(repo[nodesrc], (repo[nodenew],))])
for book in oldbookmarks:
- repo._bookmarks[book] = nodenew
+ bmchanges.append((book, nodenew))
else:
obsolete.createmarkers(repo, [(repo[nodesrc], ())])
# Behave like rebase, move bookmarks to dest
for book in oldbookmarks:
- repo._bookmarks[book] = dest.node()
+ bmchanges.append((book, dest.node()))
for book in destbookmarks: # restore bookmark that rebase move
- repo._bookmarks[book] = dest.node()
- if oldbookmarks or destbookmarks:
- repo._bookmarks.recordchange(tr)
+ bmchanges.append((book, dest.node()))
+ if bmchanges:
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
evolvestateversion = 0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/cmdrewrite.py Tue Jul 25 05:52:14 2017 +0200
@@ -0,0 +1,919 @@
+# Module dedicated to host history rewriting commands
+#
+# Copyright 2017 Octobus <contact@octobus.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+# Status: Stabilization of the API in progress
+#
+# The final set of command should go into core.
+
+from __future__ import absolute_import
+
+import random
+
+from mercurial import (
+ bookmarks as bookmarksmod,
+ cmdutil,
+ commands,
+ context,
+ copies,
+ error,
+ hg,
+ lock as lockmod,
+ node,
+ obsolete,
+ phases,
+ scmutil,
+ util,
+)
+
+from mercurial.i18n import _
+
+from . import (
+ compat,
+ exthelper,
+ rewriteutil,
+ utility,
+)
+
+eh = exthelper.exthelper()
+
+walkopts = commands.walkopts
+commitopts = commands.commitopts
+commitopts2 = commands.commitopts2
+mergetoolopts = commands.mergetoolopts
+
+# option added by evolve
+
+def _resolveoptions(ui, opts):
+ """modify commit options dict to handle related options
+
+ For now, all it does is figure out the commit date: respect -D unless
+ -d was supplied.
+ """
+ # N.B. this is extremely similar to setupheaderopts() in mq.py
+ if not opts.get('date') and opts.get('current_date'):
+ opts['date'] = '%d %d' % util.makedate()
+ if not opts.get('user') and opts.get('current_user'):
+ opts['user'] = ui.username()
+
+commitopts3 = [
+ ('D', 'current-date', None,
+ _('record the current date as commit date')),
+ ('U', 'current-user', None,
+ _('record the current user as committer')),
+]
+
+interactiveopt = [['i', 'interactive', None, _('use interactive mode')]]
+
+@eh.command(
+ 'amend|refresh',
+ [('A', 'addremove', None,
+ _('mark new/missing files as added/removed before committing')),
+ ('a', 'all', False, _("match all files")),
+ ('e', 'edit', False, _('invoke editor on commit messages')),
+ ('', 'extract', False, _('extract changes from the commit to the working copy')),
+ ('', 'close-branch', None,
+ _('mark a branch as closed, hiding it from the branch list')),
+ ('s', 'secret', None, _('use the secret phase for committing')),
+ ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt,
+ _('[OPTION]... [FILE]...'))
+def amend(ui, repo, *pats, **opts):
+ """combine a changeset with updates and replace it with a new one
+
+ Commits a new changeset incorporating both the changes to the given files
+ and all the changes from the current parent changeset into the repository.
+
+ See :hg:`commit` for details about committing changes.
+
+ If you don't specify -m, the parent's message will be reused.
+
+ If --extra is specified, the behavior of `hg amend` is reversed: Changes
+ to selected files in the checked out revision appear again as uncommitted
+ changed in the working directory.
+
+ Returns 0 on success, 1 if nothing changed.
+ """
+ opts = opts.copy()
+ if opts.get('extract'):
+ if opts.pop('interactive', False):
+ msg = _('not support for --interactive with --extract yet')
+ raise error.Abort(msg)
+ return uncommit(ui, repo, *pats, **opts)
+ else:
+ if opts.pop('all', False):
+ # add an include for all
+ include = list(opts.get('include'))
+ include.append('re:.*')
+ edit = opts.pop('edit', False)
+ log = opts.get('logfile')
+ opts['amend'] = True
+ if not (edit or opts['message'] or log):
+ opts['message'] = repo['.'].description()
+ _resolveoptions(ui, opts)
+ _alias, commitcmd = cmdutil.findcmd('commit', commands.table)
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ rewriteutil.precheck(repo, [repo['.'].rev()], action='amend')
+ return commitcmd[0](ui, repo, *pats, **opts)
+ finally:
+ lockmod.release(lock, wlock)
+
+def _touchedbetween(repo, source, dest, match=None):
+ touched = set()
+ for files in repo.status(source, dest, match=match)[:3]:
+ touched.update(files)
+ return touched
+
+def _commitfiltered(repo, ctx, match, target=None, message=None, user=None,
+ date=None):
+ """Recommit ctx with changed files not in match. Return the new
+ node identifier, or None if nothing changed.
+ """
+ base = ctx.p1()
+ if target is None:
+ target = base
+ # ctx
+ initialfiles = _touchedbetween(repo, base, ctx)
+ if base == target:
+ affected = set(f for f in initialfiles if match(f))
+ newcontent = set()
+ else:
+ affected = _touchedbetween(repo, target, ctx, match=match)
+ newcontent = _touchedbetween(repo, target, base, match=match)
+ # The commit touchs all existing files
+ # + all file that needs a new content
+ # - the file affected bny uncommit with the same content than base.
+ files = (initialfiles - affected) | newcontent
+ if not newcontent and files == initialfiles:
+ return None
+
+ # Filter copies
+ copied = copies.pathcopies(target, ctx)
+ copied = dict((dst, src) for dst, src in copied.iteritems()
+ if dst in files)
+
+ def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent):
+ if path in redirect:
+ return filectxfn(repo, memctx, path, contentctx=target, redirect=())
+ if path not in contentctx:
+ return None
+ fctx = contentctx[path]
+ flags = fctx.flags()
+ mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
+ islink='l' in flags,
+ isexec='x' in flags,
+ copied=copied.get(path))
+ return mctx
+
+ if message is None:
+ message = ctx.description()
+ if not user:
+ user = ctx.user()
+ if not date:
+ date = ctx.date()
+ new = context.memctx(repo,
+ parents=[base.node(), node.nullid],
+ text=message,
+ files=files,
+ filectxfn=filectxfn,
+ user=user,
+ date=date,
+ extra=ctx.extra())
+ # commitctx always create a new revision, no need to check
+ newid = repo.commitctx(new)
+ return newid
+
+def _uncommitdirstate(repo, oldctx, match):
+ """Fix the dirstate after switching the working directory from
+ oldctx to a copy of oldctx not containing changed files matched by
+ match.
+ """
+ ctx = repo['.']
+ ds = repo.dirstate
+ copies = dict(ds.copies())
+ m, a, r = repo.status(oldctx.p1(), oldctx, match=match)[:3]
+ for f in m:
+ if ds[f] == 'r':
+ # modified + removed -> removed
+ continue
+ ds.normallookup(f)
+
+ for f in a:
+ if ds[f] == 'r':
+ # added + removed -> unknown
+ ds.drop(f)
+ elif ds[f] != 'a':
+ ds.add(f)
+
+ for f in r:
+ if ds[f] == 'a':
+ # removed + added -> normal
+ ds.normallookup(f)
+ elif ds[f] != 'r':
+ ds.remove(f)
+
+ # Merge old parent and old working dir copies
+ oldcopies = {}
+ for f in (m + a):
+ src = oldctx[f].renamed()
+ if src:
+ oldcopies[f] = src[0]
+ oldcopies.update(copies)
+ copies = dict((dst, oldcopies.get(src, src))
+ for dst, src in oldcopies.iteritems())
+ # Adjust the dirstate copies
+ for dst, src in copies.iteritems():
+ if (src not in ctx or dst in ctx or ds[dst] != 'a'):
+ src = None
+ ds.copy(src, dst)
+
+@eh.command(
+ '^uncommit',
+ [('a', 'all', None, _('uncommit all changes when no arguments given')),
+ ('r', 'rev', '', _('revert commit content to REV instead')),
+ ] + commands.walkopts + commitopts + commitopts2 + commitopts3,
+ _('[OPTION]... [NAME]'))
+def uncommit(ui, repo, *pats, **opts):
+ """move changes from parent revision to working directory
+
+ Changes to selected files in the checked out revision appear again as
+ uncommitted changed in the working directory. A new revision
+ without the selected changes is created, becomes the checked out
+ revision, and obsoletes the previous one.
+
+ The --include option specifies patterns to uncommit.
+ The --exclude option specifies patterns to keep in the commit.
+
+ The --rev argument let you change the commit file to a content of another
+ revision. It still does not change the content of your file in the working
+ directory.
+
+ Return 0 if changed files are uncommitted.
+ """
+
+ _resolveoptions(ui, opts) # process commitopts3
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ wctx = repo[None]
+ if len(wctx.parents()) <= 0:
+ raise error.Abort(_("cannot uncommit null changeset"))
+ if len(wctx.parents()) > 1:
+ raise error.Abort(_("cannot uncommit while merging"))
+ old = repo['.']
+ rewriteutil.precheck(repo, [repo['.'].rev()], action='uncommit')
+ if len(old.parents()) > 1:
+ raise error.Abort(_("cannot uncommit merge changeset"))
+ oldphase = old.phase()
+
+ rev = None
+ if opts.get('rev'):
+ rev = scmutil.revsingle(repo, opts.get('rev'))
+ ctx = repo[None]
+ if ctx.p1() == rev or ctx.p2() == rev:
+ raise error.Abort(_("cannot uncommit to parent changeset"))
+
+ onahead = old.rev() in repo.changelog.headrevs()
+ disallowunstable = not obsolete.isenabled(repo,
+ obsolete.allowunstableopt)
+ if disallowunstable and not onahead:
+ raise error.Abort(_("cannot uncommit in the middle of a stack"))
+
+ # Recommit the filtered changeset
+ tr = repo.transaction('uncommit')
+ updatebookmarks = rewriteutil.bookmarksupdater(repo, old.node(), tr)
+ newid = None
+ includeorexclude = opts.get('include') or opts.get('exclude')
+ if (pats or includeorexclude or opts.get('all')):
+ match = scmutil.match(old, pats, opts)
+ if not (opts['message'] or opts['logfile']):
+ opts['message'] = old.description()
+ message = cmdutil.logmessage(ui, opts)
+ newid = _commitfiltered(repo, old, match, target=rev,
+ message=message, user=opts.get('user'),
+ date=opts.get('date'))
+ if newid is None:
+ raise error.Abort(_('nothing to uncommit'),
+ hint=_("use --all to uncommit all files"))
+ # Move local changes on filtered changeset
+ obsolete.createmarkers(repo, [(old, (repo[newid],))])
+ phases.retractboundary(repo, tr, oldphase, [newid])
+ with repo.dirstate.parentchange():
+ repo.dirstate.setparents(newid, node.nullid)
+ _uncommitdirstate(repo, old, match)
+ updatebookmarks(newid)
+ if not repo[newid].files():
+ ui.warn(_("new changeset is empty\n"))
+ ui.status(_("(use 'hg prune .' to remove it)\n"))
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+@eh.command(
+ '^fold|squash',
+ [('r', 'rev', [], _("revision to fold")),
+ ('', 'exact', None, _("only fold specified revisions")),
+ ('', 'from', None, _("fold revisions linearly to working copy parent"))
+ ] + commitopts + commitopts2 + commitopts3,
+ _('hg fold [OPTION]... [-r] REV'))
+def fold(ui, repo, *revs, **opts):
+ """fold multiple revisions into a single one
+
+ With --from, folds all the revisions linearly between the given revisions
+ and the parent of the working directory.
+
+ With --exact, folds only the specified revisions while ignoring the
+ parent of the working directory. In this case, the given revisions must
+ form a linear unbroken chain.
+
+ .. container:: verbose
+
+ Some examples:
+
+ - Fold the current revision with its parent::
+
+ hg fold --from .^
+
+ - Fold all draft revisions with working directory parent::
+
+ hg fold --from 'draft()'
+
+ See :hg:`help phases` for more about draft revisions and
+ :hg:`help revsets` for more about the `draft()` keyword
+
+ - Fold revisions between 3 and 6 with the working directory parent::
+
+ hg fold --from 3::6
+
+ - Fold revisions 3 and 4:
+
+ hg fold "3 + 4" --exact
+
+ - Only fold revisions linearly between foo and @::
+
+ hg fold foo::@ --exact
+ """
+ _resolveoptions(ui, opts)
+ revs = list(revs)
+ revs.extend(opts['rev'])
+ if not revs:
+ raise error.Abort(_('no revisions specified'))
+
+ revs = scmutil.revrange(repo, revs)
+
+ if opts['from'] and opts['exact']:
+ raise error.Abort(_('cannot use both --from and --exact'))
+ elif opts['from']:
+ # Try to extend given revision starting from the working directory
+ extrevs = repo.revs('(%ld::.) or (.::%ld)', revs, revs)
+ discardedrevs = [r for r in revs if r not in extrevs]
+ if discardedrevs:
+ msg = _("cannot fold non-linear revisions")
+ hint = _("given revisions are unrelated to parent of working"
+ " directory")
+ raise error.Abort(msg, hint=hint)
+ revs = extrevs
+ elif opts['exact']:
+ # Nothing to do; "revs" is already set correctly
+ pass
+ else:
+ raise error.Abort(_('must specify either --from or --exact'))
+
+ if not revs:
+ raise error.Abort(_('specified revisions evaluate to an empty set'),
+ hint=_('use different revision arguments'))
+ elif len(revs) == 1:
+ ui.write_err(_('single revision specified, nothing to fold\n'))
+ return 1
+
+ wlock = lock = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+
+ root, head = rewriteutil.foldcheck(repo, revs)
+
+ tr = repo.transaction('fold')
+ 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:
+ 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]
+ commitopts['message'] = "\n".join(msgs)
+ commitopts['edit'] = True
+
+ newid, unusedvariable = rewriteutil.rewrite(repo, root, allctx,
+ head,
+ [root.p1().node(),
+ root.p2().node()],
+ commitopts=commitopts)
+ phases.retractboundary(repo, tr, targetphase, [newid])
+ obsolete.createmarkers(repo, [(ctx, (repo[newid],))
+ for ctx in allctx])
+ tr.close()
+ finally:
+ tr.release()
+ ui.status('%i changesets folded\n' % len(revs))
+ if repo['.'].rev() in revs:
+ hg.update(repo, newid)
+ finally:
+ lockmod.release(lock, wlock)
+
+@eh.command(
+ '^metaedit',
+ [('r', 'rev', [], _("revision to edit")),
+ ('', 'fold', None, _("also fold specified revisions into one")),
+ ] + commitopts + commitopts2 + commitopts3,
+ _('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.
+ """
+ _resolveoptions(ui, opts)
+ 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 = rewriteutil.foldcheck(repo, revs)
+ else:
+ if repo.revs("%ld and public()", revs):
+ raise error.Abort(_('cannot edit commit information for public '
+ 'revisions'))
+ newunstable = rewriteutil.disallowednewunstable(repo, revs)
+ if newunstable:
+ msg = _('cannot edit commit information in the middle'
+ ' of a stack')
+ hint = _('%s will become unstable and new unstable changes'
+ ' are not allowed')
+ hint %= repo[newunstable.first()]
+ raise error.Abort(msg, hint=hint)
+ 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 = rewriteutil.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)
+
+metadataopts = [
+ ('d', 'date', '',
+ _('record the specified date in metadata'), _('DATE')),
+ ('u', 'user', '',
+ _('record the specified user in metadata'), _('USER')),
+]
+
+def _getmetadata(**opts):
+ metadata = {}
+ date = opts.get('date')
+ user = opts.get('user')
+ if date:
+ metadata['date'] = '%i %i' % util.parsedate(date)
+ if user:
+ metadata['user'] = user
+ return metadata
+
+@eh.command(
+ '^prune|obsolete',
+ [('n', 'new', [], _("successor changeset (DEPRECATED)")),
+ ('s', 'succ', [], _("successor changeset")),
+ ('r', 'rev', [], _("revisions to prune")),
+ ('k', 'keep', None, _("does not modify working copy during prune")),
+ ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")),
+ ('', 'fold', False,
+ _("record a fold (multiple precursors, one successors)")),
+ ('', 'split', False,
+ _("record a split (on precursor, multiple successors)")),
+ ('B', 'bookmark', [], _("remove revs only reachable from given"
+ " bookmark"))] + metadataopts,
+ _('[OPTION] [-r] REV...'))
+# XXX -U --noupdate option to prevent wc update and or bookmarks update ?
+def cmdprune(ui, repo, *revs, **opts):
+ """hide changesets by marking them obsolete
+
+ Pruned changesets are obsolete with no successors. If they also have no
+ descendants, they are hidden (invisible to all commands).
+
+ Non-obsolete descendants of pruned changesets become "unstable". Use :hg:`evolve`
+ to handle this situation.
+
+ When you prune the parent of your working copy, Mercurial updates the working
+ copy to a non-obsolete parent.
+
+ You can use ``--succ`` to tell Mercurial that a newer version (successor) of the
+ pruned changeset exists. Mercurial records successor revisions in obsolescence
+ markers.
+
+ You can use the ``--biject`` option to specify a 1-1 mapping (bijection) between
+ revisions to pruned (precursor) and successor changesets. This option may be
+ removed in a future release (with the functionality provided automatically).
+
+ If you specify multiple revisions in ``--succ``, you are recording a "split" and
+ must acknowledge it by passing ``--split``. Similarly, when you prune multiple
+ changesets with a single successor, you must pass the ``--fold`` option.
+ """
+ revs = scmutil.revrange(repo, list(revs) + opts.get('rev'))
+ succs = opts['new'] + opts['succ']
+ bookmarks = set(opts.get('bookmark'))
+ metadata = _getmetadata(**opts)
+ biject = opts.get('biject')
+ fold = opts.get('fold')
+ split = opts.get('split')
+
+ options = [o for o in ('biject', 'fold', 'split') if opts.get(o)]
+ if 1 < len(options):
+ raise error.Abort(_("can only specify one of %s") % ', '.join(options))
+
+ if bookmarks:
+ reachablefrombookmark = rewriteutil.reachablefrombookmark
+ repomarks, revs = reachablefrombookmark(repo, revs, bookmarks)
+ if not revs:
+ # no revisions to prune - delete bookmark immediately
+ rewriteutil.deletebookmark(repo, repomarks, bookmarks)
+
+ if not revs:
+ raise error.Abort(_('nothing to prune'))
+
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ rewriteutil.precheck(repo, revs, 'touch')
+ tr = repo.transaction('prune')
+ # defines pruned changesets
+ precs = []
+ revs.sort()
+ for p in revs:
+ cp = repo[p]
+ precs.append(cp)
+ if not precs:
+ raise error.Abort('nothing to prune')
+
+ # defines successors changesets
+ sucs = scmutil.revrange(repo, succs)
+ sucs.sort()
+ 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"
+ 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))
+ raise error.Abort(msg)
+ elif (len(precs) == 1 and len(sucs) > 1) and not split:
+ msg = "please add --split if you want to do a split"
+ raise error.Abort(msg)
+ elif len(sucs) == 1 and len(precs) > 1 and not fold:
+ msg = "please add --fold if you want to do a fold"
+ raise error.Abort(msg)
+ elif biject:
+ relations = [(p, (s,)) for p, s in zip(precs, sucs)]
+ else:
+ relations = [(p, sucs) for p in precs]
+
+ wdp = repo['.']
+
+ if len(sucs) == 1 and len(precs) == 1 and wdp in precs:
+ # '.' killed, so update to the successor
+ newnode = sucs[0]
+ else:
+ # update to an unkilled parent
+ newnode = wdp
+
+ while newnode in precs or newnode.obsolete():
+ newnode = newnode.parents()[0]
+
+ if newnode.node() != wdp.node():
+ if opts.get('keep', False):
+ # This is largely the same as the implementation in
+ # strip.stripcmd(). We might want to refactor this somewhere
+ # common at some point.
+
+ # only reset the dirstate for files that would actually change
+ # between the working context and uctx
+ descendantrevs = repo.revs("%d::." % newnode.rev())
+ changedfiles = []
+ for rev in descendantrevs:
+ # blindly reset the files, regardless of what actually
+ # changed
+ changedfiles.extend(repo[rev].files())
+
+ # reset files that only changed in the dirstate too
+ dirstate = repo.dirstate
+ dirchanges = [f for f in dirstate if dirstate[f] != 'n']
+ changedfiles.extend(dirchanges)
+ repo.dirstate.rebuild(newnode.node(), newnode.manifest(),
+ changedfiles)
+ dirstate.write(tr)
+ else:
+ bookactive = repo._activebookmark
+ # Active bookmark that we don't want to delete (with -B option)
+ # we deactivate and move it before the update and reactivate it
+ # after
+ movebookmark = bookactive and not bookmarks
+ if movebookmark:
+ bookmarksmod.deactivate(repo)
+ bmchanges = [(bookactive, newnode.node())]
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
+ commands.update(ui, repo, newnode.rev())
+ ui.status(_('working directory now at %s\n')
+ % ui.label(str(newnode), 'evolve.node'))
+ if movebookmark:
+ bookmarksmod.activate(repo, bookactive)
+
+ # update bookmarks
+ if bookmarks:
+ rewriteutil.deletebookmark(repo, repomarks, bookmarks)
+
+ # create markers
+ obsolete.createmarkers(repo, relations, metadata=metadata)
+
+ # informs that changeset have been pruned
+ ui.status(_('%i changesets pruned\n') % len(precs))
+
+ for ctx in repo.unfiltered().set('bookmark() and %ld', precs):
+ # used to be:
+ #
+ # ldest = list(repo.set('max((::%d) - obsolete())', ctx))
+ # if ldest:
+ # c = ldest[0]
+ #
+ # but then revset took a lazy arrow in the knee and became much
+ # slower. The new forms makes as much sense and a much faster.
+ for dest in ctx.ancestors():
+ if not dest.obsolete():
+ bookmarksupdater = rewriteutil.bookmarksupdater
+ updatebookmarks = bookmarksupdater(repo, ctx.node(), tr)
+ updatebookmarks(dest.node())
+ break
+
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+@eh.command(
+ '^split',
+ [('r', 'rev', [], _("revision to split")),
+ ] + commitopts + commitopts2 + commitopts3,
+ _('hg split [OPTION]... [-r] REV'))
+def cmdsplit(ui, repo, *revs, **opts):
+ """split a changeset into smaller changesets
+
+ By default, split the current revision by prompting for all its hunks to be
+ redistributed into new changesets.
+
+ Use --rev to split a given changeset instead.
+ """
+ _resolveoptions(ui, opts)
+ tr = wlock = lock = None
+ newcommits = []
+
+ revarg = (list(revs) + opts.get('rev')) or ['.']
+ if len(revarg) != 1:
+ msg = _("more than one revset is given")
+ hnt = _("use either `hg split <rs>` or `hg split --rev <rs>`, not both")
+ raise error.Abort(msg, hint=hnt)
+
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ rev = scmutil.revsingle(repo, revarg[0])
+ cmdutil.bailifchanged(repo)
+ rewriteutil.precheck(repo, [rev], action='split')
+ tr = repo.transaction('split')
+ ctx = repo[rev]
+
+ if len(ctx.parents()) > 1:
+ raise error.Abort(_("cannot split merge commits"))
+ prev = ctx.p1()
+ bmupdate = rewriteutil.bookmarksupdater(repo, ctx.node(), tr)
+ bookactive = repo._activebookmark
+ if bookactive is not None:
+ repo.ui.status(_("(leaving bookmark %s)\n") % repo._activebookmark)
+ bookmarksmod.deactivate(repo)
+
+ # Prepare the working directory
+ rewriteutil.presplitupdate(repo, ui, prev, ctx)
+
+ def haschanges():
+ modified, added, removed, deleted = repo.status()[:4]
+ return modified or added or removed or deleted
+ 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
+ if not opts['user']:
+ opts['user'] = ctx.user()
+ while haschanges():
+ pats = ()
+ cmdutil.dorecord(ui, repo, commands.commit, 'commit', False,
+ cmdutil.recordfilter, *pats, **opts)
+ # TODO: Does no seem like the best way to do this
+ # We should make dorecord return the newly created commit
+ newcommits.append(repo['.'])
+ if haschanges():
+ if ui.prompt('Done splitting? [yN]', default='n') == 'y':
+ commands.commit(ui, repo, **opts)
+ newcommits.append(repo['.'])
+ break
+ else:
+ ui.status(_("no more change to split\n"))
+
+ if newcommits:
+ tip = repo[newcommits[-1]]
+ bmupdate(tip.node())
+ if bookactive is not None:
+ bookmarksmod.activate(repo, bookactive)
+ obsolete.createmarkers(repo, [(repo[rev], newcommits)])
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+@eh.command(
+ '^touch',
+ [('r', 'rev', [], 'revision to update'),
+ ('D', 'duplicate', False,
+ 'do not mark the new revision as successor of the old one'),
+ ('A', 'allowdivergence', False,
+ 'mark the new revision as successor of the old one potentially creating '
+ 'divergence')],
+ # allow to choose the seed ?
+ _('[-r] revs'))
+def touch(ui, repo, *revs, **opts):
+ """create successors that are identical to their predecessors except
+ for the changeset ID
+
+ This is used to "resurrect" changesets
+ """
+ duplicate = opts['duplicate']
+ allowdivergence = opts['allowdivergence']
+ revs = list(revs)
+ revs.extend(opts['rev'])
+ if not revs:
+ revs = ['.']
+ revs = scmutil.revrange(repo, revs)
+ if not revs:
+ ui.write_err('no revision to touch\n')
+ return 1
+ if not duplicate:
+ rewriteutil.precheck(repo, revs, touch)
+ tmpl = utility.shorttemplate
+ displayer = cmdutil.show_changeset(ui, repo, {'template': tmpl})
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction('touch')
+ revs.sort() # ensure parent are run first
+ newmapping = {}
+ for r in revs:
+ ctx = repo[r]
+ extra = ctx.extra().copy()
+ extra['__touch-noise__'] = random.randint(0, 0xffffffff)
+ # search for touched parent
+ p1 = ctx.p1().node()
+ p2 = ctx.p2().node()
+ p1 = newmapping.get(p1, p1)
+ p2 = newmapping.get(p2, p2)
+
+ if not (duplicate or allowdivergence):
+ # The user hasn't yet decided what to do with the revived
+ # cset, let's ask
+ sset = compat.successorssets(repo, ctx.node())
+ nodivergencerisk = (len(sset) == 0 or
+ (len(sset) == 1 and
+ len(sset[0]) == 1 and
+ repo[sset[0][0]].rev() == ctx.rev()
+ ))
+ if nodivergencerisk:
+ duplicate = False
+ else:
+ displayer.show(ctx)
+ index = ui.promptchoice(
+ _("reviving this changeset will create divergence"
+ " unless you make a duplicate.\n(a)llow divergence or"
+ " (d)uplicate the changeset? $$ &Allowdivergence $$ "
+ "&Duplicate"), 0)
+ choice = ['allowdivergence', 'duplicate'][index]
+ if choice == 'allowdivergence':
+ duplicate = False
+ else:
+ duplicate = True
+
+ extradict = {'extra': extra}
+ new, unusedvariable = rewriteutil.rewrite(repo, ctx, [], ctx,
+ [p1, p2],
+ commitopts=extradict)
+ # store touched version to help potential children
+ newmapping[ctx.node()] = new
+
+ if not duplicate:
+ obsolete.createmarkers(repo, [(ctx, (repo[new],))])
+ phases.retractboundary(repo, tr, ctx.phase(), [new])
+ if ctx in repo[None].parents():
+ with repo.dirstate.parentchange():
+ repo.dirstate.setparents(new, node.nullid)
+ tr.close()
+ finally:
+ lockmod.release(tr, lock, wlock)
--- a/hgext3rd/evolve/compat.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/compat.py Tue Jul 25 05:52:14 2017 +0200
@@ -8,7 +8,8 @@
from mercurial import (
hg,
- obsolete
+ obsolete,
+ util,
)
try:
@@ -23,7 +24,7 @@
eh = exthelper.exthelper()
-if not hasattr(hg, '_copycache'):
+if not util.safehasattr(hg, '_copycache'):
# exact copy of relevantmarkers as in Mercurial-176d1a0ce385
# this fixes relevant markers computation for version < hg-4.3
@eh.wrapfunction(obsolete.obsstore, 'relevantmarkers')
@@ -75,3 +76,17 @@
if func is None:
func = obsolete.allprecursors
return func(*args, **kwargs)
+
+# compatibility layer for mercurial < 4.3
+def bookmarkapplychanges(repo, tr, changes):
+ """Apply a list of changes to bookmarks
+ """
+ bookmarks = repo._bookmarks
+ if util.safehasattr(bookmarks, 'applychanges'):
+ return bookmarks.applychanges(repo, tr, changes)
+ for name, node in changes:
+ if node is None:
+ del bookmarks[name]
+ else:
+ bookmarks[name] = node
+ bookmarks.recordchange(tr)
--- a/hgext3rd/evolve/hack/inhibit.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/hack/inhibit.py Tue Jul 25 05:52:14 2017 +0200
@@ -106,7 +106,7 @@
'keep': None,
'biject': False,
}
- evolve.cmdprune(ui, repo, **optsdict)
+ evolve.cmdrewrite.cmdprune(ui, repo, **optsdict)
# obsolescence inhibitor
########################
--- a/hgext3rd/evolve/metadata.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/metadata.py Tue Jul 25 05:52:14 2017 +0200
@@ -5,7 +5,7 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-__version__ = '6.5.1.dev'
+__version__ = '6.6.0.dev'
testedwith = '3.8.4 3.9.2 4.0.2 4.1.3 4.2.1'
minimumhgversion = '3.8'
buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obscache.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/obscache.py Tue Jul 25 05:52:14 2017 +0200
@@ -42,6 +42,12 @@
else:
timer = time.time
+# hg < 4.2 compat
+try:
+ from mercurial import vfs as vfsmod
+ vfsmod.vfs
+except ImportError:
+ from mercurial import scmutil as vfsmod
try:
obsstorefilecache = localrepo.localrepository.obsstore
@@ -320,6 +326,12 @@
return reset, revs, markers, (obssize, obskey)
+def getcachevfs(repo):
+ cachevfs = getattr(repo, 'cachevfs', None)
+ if cachevfs is None:
+ cachevfs = vfsmod.vfs(repo.vfs.join('cache'))
+ cachevfs.createmode = repo.store.createmode
+ return cachevfs
class obscache(dualsourcecache):
"""cache the "does a rev" is the precursors of some obsmarkers data
@@ -355,7 +367,7 @@
zero. That would be especially useful for the '.pending' overlay.
"""
- _filepath = 'cache/evoext-obscache-00'
+ _filepath = 'evoext-obscache-00'
_headerformat = '>q20sQQ20s'
_cachename = 'evo-ext-obscache' # used for error message
@@ -363,8 +375,7 @@
def __init__(self, repo):
super(obscache, self).__init__()
self._ondiskkey = None
- self._vfs = repo.vfs
- self._setdata(bytearray())
+ self._vfs = getcachevfs(repo)
@util.propertycache
def get(self):
@@ -445,7 +456,7 @@
if self._cachekey is None or self._cachekey == self._ondiskkey:
return
- cachefile = repo.vfs(self._filepath, 'w', atomictemp=True)
+ cachefile = self._vfs(self._filepath, 'w', atomictemp=True)
headerdata = struct.pack(self._headerformat, *self._cachekey)
cachefile.write(headerdata)
cachefile.write(self._data)
@@ -455,7 +466,7 @@
"""load data from disk"""
assert repo.filtername is None
- data = repo.vfs.tryread(self._filepath)
+ data = self._vfs.tryread(self._filepath)
if not data:
self._cachekey = self.emptykey
self._setdata(bytearray())
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/rewriteutil.py Tue Jul 25 05:52:14 2017 +0200
@@ -0,0 +1,247 @@
+# Module dedicated to host utility code dedicated to changeset rewrite
+#
+# Copyright 2017 Octobus <contact@octobus.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+# Status: Stabilization of the API in progress
+#
+# The content of this module should move into core incrementally once we are
+# happy one piece of it (and hopefully, able to reuse it in other core
+# commands).
+
+from mercurial import (
+ cmdutil,
+ commands,
+ context,
+ copies,
+ error,
+ hg,
+ lock as lockmod,
+ node,
+ obsolete,
+ phases,
+ repair,
+ revset,
+ util,
+)
+
+from mercurial.i18n import _
+
+from . import (
+ compat,
+)
+
+def _formatrevs(repo, revs, maxrevs=4):
+ """return a string summarising revision in a descent size
+
+ If there is few enough revision, we list them otherwise we display a
+ summary in the form:
+
+ 1ea73414a91b and 5 others
+ """
+ tonode = repo.changelog.node
+ numrevs = len(revs)
+ if numrevs < maxrevs:
+ shorts = [node.short(tonode(r)) for r in revs]
+ summary = ', '.join(shorts)
+ else:
+ if util.safehasattr(revs, 'first'):
+ first = revs.first()
+ else:
+ first = revs[0]
+ summary = _('%s and %d others')
+ summary %= (node.short(tonode(first)), numrevs - 1)
+ return summary
+
+def precheck(repo, revs, action='rewrite'):
+ """check if <revs> can be rewritten
+
+ <action> can be used to control the commit message.
+ """
+ if node.nullrev in revs:
+ msg = _("cannot %s the null revision") % (action)
+ hint = _("no changeset checked out")
+ raise error.Abort(msg, hint=hint)
+ publicrevs = repo.revs('%ld and public()', revs)
+ if publicrevs:
+ summary = _formatrevs(repo, publicrevs)
+ msg = _("cannot %s public changesets: %s") % (action, summary)
+ hint = _("see 'hg help phases' for details")
+ raise error.Abort(msg, hint=hint)
+ newunstable = disallowednewunstable(repo, revs)
+ if newunstable:
+ msg = _("%s will orphan %i descendants")
+ msg %= (action, len(newunstable))
+ hint = _("see 'hg help evolution.instability'")
+ raise error.Abort(msg, hint=hint)
+
+def bookmarksupdater(repo, oldid, tr):
+ """Return a callable update(newid) updating the current bookmark
+ and bookmarks bound to oldid to newid.
+ """
+ def updatebookmarks(newid):
+ oldbookmarks = repo.nodebookmarks(oldid)
+ bmchanges = [(b, newid) for b in oldbookmarks]
+ if bmchanges:
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
+ return updatebookmarks
+
+def disallowednewunstable(repo, revs):
+ """Check that editing <revs> will not create disallowed unstable
+
+ (unstable creation is controled by some special config).
+ """
+ allowunstable = obsolete.isenabled(repo, obsolete.allowunstableopt)
+ if allowunstable:
+ return revset.baseset()
+ return repo.revs("(%ld::) - %ld", revs, revs)
+
+def foldcheck(repo, revs):
+ """check that <revs> can be folded"""
+ precheck(repo, revs, action='fold')
+ 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()]
+ return root, head
+
+def deletebookmark(repo, repomarks, bookmarks):
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction('prune')
+ bmchanges = []
+ for bookmark in bookmarks:
+ bmchanges.append((bookmark, None))
+ compat.bookmarkapplychanges(repo, tr, bmchanges)
+ tr.close()
+ for bookmark in sorted(bookmarks):
+ repo.ui.write(_("bookmark '%s' deleted\n") % bookmark)
+ finally:
+ lockmod.release(tr, lock, wlock)
+
+def presplitupdate(repo, ui, prev, ctx):
+ """prepare the working directory for a split (for topic hooking)
+ """
+ hg.update(repo, prev)
+ commands.revert(ui, repo, rev=ctx.rev(), all=True)
+
+def reachablefrombookmark(repo, revs, bookmarks):
+ """filter revisions and bookmarks reachable from the given bookmark
+ yoinked from mq.py
+ """
+ repomarks = repo._bookmarks
+ if not bookmarks.issubset(repomarks):
+ raise error.Abort(_("bookmark '%s' not found") %
+ ','.join(sorted(bookmarks - set(repomarks.keys()))))
+
+ # If the requested bookmark is not the only one pointing to a
+ # a revision we have to only delete the bookmark and not strip
+ # anything. revsets cannot detect that case.
+ nodetobookmarks = {}
+ for mark, bnode in repomarks.iteritems():
+ nodetobookmarks.setdefault(bnode, []).append(mark)
+ for marks in nodetobookmarks.values():
+ if bookmarks.issuperset(marks):
+ rsrevs = repair.stripbmrevset(repo, marks[0])
+ revs = set(revs)
+ revs.update(set(rsrevs))
+ revs = sorted(revs)
+ return repomarks, revs
+
+def rewrite(repo, old, updates, head, newbases, commitopts):
+ """Return (nodeid, created) where nodeid is the identifier of the
+ changeset generated by the rewrite process, and created is True if
+ nodeid was actually created. If created is False, nodeid
+ references a changeset existing before the rewrite call.
+ """
+ wlock = lock = tr = None
+ try:
+ wlock = repo.wlock()
+ lock = repo.lock()
+ tr = repo.transaction('rewrite')
+ 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)
+
+ # commit a new version of the old changeset, including the update
+ # collect all files which might be affected
+ files = set(old.files())
+ for u in updates:
+ files.update(u.files())
+
+ # Recompute copies (avoid recording a -> b -> a)
+ copied = copies.pathcopies(base, head)
+
+ # prune files which were reverted by the updates
+ def samefile(f):
+ if f in head.manifest():
+ a = head.filectx(f)
+ if f in base.manifest():
+ b = base.filectx(f)
+ return (a.data() == b.data()
+ and a.flags() == b.flags())
+ else:
+ return False
+ else:
+ return f not in base.manifest()
+ files = [f for f in files if not samefile(f)]
+ # commit version of these files as defined by head
+ headmf = head.manifest()
+
+ def filectxfn(repo, ctx, path):
+ if path in headmf:
+ fctx = head[path]
+ flags = fctx.flags()
+ mctx = context.memfilectx(repo, fctx.path(), fctx.data(),
+ islink='l' in flags,
+ isexec='x' in flags,
+ copied=copied.get(path))
+ return mctx
+ return None
+
+ message = cmdutil.logmessage(repo.ui, commitopts)
+ if not message:
+ message = old.description()
+
+ user = commitopts.get('user') or old.user()
+ # TODO: In case not date is given, we should take the old commit date
+ # if we are working one one changeset or mimic the fold behavior about
+ # date
+ date = commitopts.get('date') or None
+ extra = dict(commitopts.get('extra', old.extra()))
+ extra['branch'] = head.branch()
+
+ new = context.memctx(repo,
+ parents=newbases,
+ text=message,
+ files=files,
+ filectxfn=filectxfn,
+ user=user,
+ date=date,
+ extra=extra)
+
+ if commitopts.get('edit'):
+ new._text = cmdutil.commitforceeditor(repo, new, [])
+ revcount = len(repo)
+ newid = repo.commitctx(new)
+ new = repo[newid]
+ created = len(repo) != revcount
+ updatebookmarks(newid)
+
+ tr.close()
+ return newid, created
+ finally:
+ lockmod.release(tr, lock, wlock)
--- a/hgext3rd/evolve/utility.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/evolve/utility.py Tue Jul 25 05:52:14 2017 +0200
@@ -5,6 +5,8 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
+shorttemplate = "[{label('evolve.rev', rev)}] {desc|firstline}\n"
+
def obsexcmsg(ui, message, important=False):
verbose = ui.configbool('experimental', 'verbose-obsolescence-exchange',
False)
--- a/hgext3rd/topic/__init__.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/topic/__init__.py Tue Jul 25 05:52:14 2017 +0200
@@ -53,6 +53,7 @@
from __future__ import absolute_import
import re
+import time
from mercurial.i18n import _
from mercurial import (
@@ -68,9 +69,11 @@
namespaces,
node,
obsolete,
+ obsutil,
patch,
phases,
registrar,
+ templatefilters,
util,
)
@@ -98,11 +101,13 @@
'topic.stack.index': 'yellow',
'topic.stack.index.base': 'none dim',
'topic.stack.desc.base': 'none dim',
+ 'topic.stack.shortnode.base': 'none dim',
'topic.stack.state.base': 'dim',
'topic.stack.state.clean': 'green',
'topic.stack.index.current': 'cyan', # random pick
'topic.stack.state.current': 'cyan bold', # random pick
'topic.stack.desc.current': 'cyan', # random pick
+ 'topic.stack.shortnode.current': 'cyan', # random pick
'topic.stack.state.unstable': 'red',
'topic.stack.summary.behindcount': 'cyan',
'topic.stack.summary.behinderror': 'red',
@@ -113,7 +118,7 @@
'topic.active': 'green',
}
-version = '0.1.1.dev'
+version = '0.2.0.dev'
testedwith = '4.0.2 4.1.3 4.2.1'
minimumhgversion = '4.0'
buglink = 'https://bz.mercurial-scm.org/'
@@ -123,6 +128,19 @@
return ''
return self.extra().get(constants.extrakey, '')
context.basectx.topic = _contexttopic
+def _contexttopicidx(self):
+ topic = self.topic()
+ if not topic:
+ # XXX we might want to include t0 here,
+ # however t0 is related to 'currenttopic' which has no place here.
+ return None
+ revlist = stack.getstack(self._repo, topic=topic)
+ try:
+ return revlist.index(self.rev())
+ except IndexError:
+ # Lets move to the last ctx of the current topic
+ return None
+context.basectx.topicidx = _contexttopicidx
topicrev = re.compile(r'^t\d+$')
branchrev = re.compile(r'^b\d+$')
@@ -144,10 +162,14 @@
if revs is not None:
try:
- r = revs[idx - 1]
+ r = revs[idx]
except IndexError:
msg = _('cannot resolve "%s": %s "%s" has only %d changesets')
- raise error.Abort(msg % (name, ttype, tname, len(revs)))
+ raise error.Abort(msg % (name, ttype, tname, len(revs) - 1))
+ # b0 or t0 can be None
+ if r == -1 and idx == 0:
+ msg = _('the %s "%s" has no %s')
+ raise error.Abort(msg % (ttype, tname, name))
return [repo[r].node()]
if name not in repo.topics:
return []
@@ -176,10 +198,16 @@
extensions.wrapfunction(cmdutil, 'buildcommittext', committextwrap)
extensions.wrapfunction(merge, 'update', mergeupdatewrap)
+ # We need to check whether t0 or b0 is passed to override the default update
+ # behaviour of changing topic and I can't find a better way
+ # to do that as scmutil.revsingle returns the rev number and hence we can't
+ # plug into logic for this into mergemod.update().
+ extensions.wrapcommand(commands.table, 'update', checkt0)
try:
evolve = extensions.find('evolve')
- extensions.wrapfunction(evolve, "presplitupdate", presplitupdatetopic)
+ extensions.wrapfunction(evolve.rewriteutil, "presplitupdate",
+ presplitupdatetopic)
except (KeyError, AttributeError):
pass
@@ -283,9 +311,30 @@
('', 'clear', False, 'clear active topic if any'),
('r', 'rev', '', 'revset of existing revisions', _('REV')),
('l', 'list', False, 'show the stack of changeset in the topic'),
+ ('', 'age', False, 'show when you last touched the topics')
] + commands.formatteropts)
def topics(ui, repo, topic='', clear=False, rev=None, list=False, **opts):
- """View current topic, set current topic, or see all topics.
+ """View current topic, set current topic, change topic for a set of revisions, or see all topics.
+
+ Clear topic on existing topiced revisions:
+ `hg topic --rev <related revset> --clear`
+
+ Change topic on some revisions:
+ `hg topic <newtopicname> --rev <related revset>`
+
+ Clear current topic:
+ `hg topic --clear`
+
+ Set current topic:
+ `hg topic <topicname>`
+
+ List of topics:
+ `hg topics`
+
+ List of topics with their last touched time sorted according to it:
+ `hg topic --age`
+
+ The active topic (if any) will be prepended with a "*".
The --verbose version of this command display various information on the state of each topic."""
if list:
@@ -320,7 +369,10 @@
def cmdstack(ui, repo, topic='', **opts):
"""list all changesets in a topic and other information
- List the current topic by default."""
+ List the current topic by default.
+
+ The --verbose version shows short nodes for the commits also.
+ """
if not topic:
topic = None
branch = None
@@ -411,6 +463,11 @@
def _listtopics(ui, repo, opts):
fm = ui.formatter('topics', opts)
+ showlast = opts.get('age')
+ if showlast:
+ # we have a new function as plugging logic into existing function is
+ # pretty much difficult
+ return _showlasttouched(repo, fm, opts)
activetopic = repo.currenttopic
namemask = '%s'
if repo.topics and ui.verbose:
@@ -463,6 +520,76 @@
fm.plain('\n')
fm.end()
+def _showlasttouched(repo, fm, opts):
+ topics = repo.topics
+ timedict = _getlasttouched(repo, topics)
+ times = timedict.keys()
+ times.sort()
+ if topics:
+ maxwidth = max(len(t) for t in topics)
+ namemask = '%%-%is' % maxwidth
+ activetopic = repo.currenttopic
+ for timevalue in times:
+ curtopics = timedict[timevalue][1]
+ for topic in curtopics:
+ fm.startitem()
+ marker = ' '
+ label = 'topic'
+ active = (topic == activetopic)
+ if active:
+ marker = '*'
+ label = 'topic.active'
+ fm.plain(' %s ' % marker, label=label)
+ fm.write('topic', namemask, topic, label=label)
+ fm.data(active=active)
+ fm.plain(' (')
+ if timevalue == -1:
+ timestr = 'not yet touched'
+ else:
+ timestr = templatefilters.age(timedict[timevalue][0])
+ fm.write('lasttouched', '%s', timestr, label='topic.list.time')
+ fm.plain(')')
+ fm.plain('\n')
+ fm.end()
+
+def _getlasttouched(repo, topics):
+ """
+ Calculates the last time a topic was used. Returns a dictionary of seconds
+ passed from current time for a topic as keys and topic name as values.
+ """
+ topicstime = {}
+ curtime = time.time()
+ for t in topics:
+ maxtime = (0, 0)
+ trevs = repo.revs("topic(%s)", t)
+ # Need to check for the time of all changesets in the topic, whether
+ # they are obsolete of non-heads
+ # XXX: can we just rely on the max rev number for this
+ for revs in trevs:
+ rt = repo[revs].date()
+ if rt[0] > maxtime[0]:
+ # Can store the rev to gather more info
+ # latesthead = revs
+ maxtime = rt
+ # looking on the markers also to get more information and accurate
+ # last touch time.
+ obsmarkers = obsutil.getmarkers(repo, [repo[revs].node()])
+ for marker in obsmarkers:
+ rt = marker.date()
+ if rt[0] > maxtime[0]:
+ maxtime = rt
+ # is the topic still yet untouched
+ if not trevs:
+ secspassed = -1
+ else:
+ secspassed = (curtime - maxtime[0])
+ try:
+ topicstime[secspassed][1].append(t)
+ except KeyError:
+ topicstime[secspassed] = (maxtime, [t])
+
+ return topicstime
+
def summaryhook(ui, repo):
t = repo.currenttopic
if not t:
@@ -472,10 +599,16 @@
def commitwrap(orig, ui, repo, *args, **opts):
with repo.wlock():
+ enforcetopic = ui.configbool('experimental', 'enforce-topic')
if opts.get('topic'):
t = opts['topic']
with repo.vfs.open('topic', 'w') as f:
f.write(t)
+ elif not repo.currenttopic and enforcetopic:
+ msg = _("no active topic")
+ hint = _("set a current topic or use '--config " +
+ "experimental.enforce-topic=no' to commit without a topic")
+ raise error.Abort(msg, hint=hint)
return orig(ui, repo, *args, **opts)
def committextwrap(orig, repo, ctx, subs, extramsg):
@@ -491,6 +624,7 @@
partial = not (matcher is None or matcher.always())
wlock = repo.wlock()
isrebase = False
+ ist0 = False
try:
ret = orig(repo, node, branchmerge, force, *args, **kwargs)
# The mergeupdatewrap function makes the destination's topic as the
@@ -500,7 +634,9 @@
# running.
if repo.ui.hasconfig('experimental', 'topicrebase'):
isrebase = True
- if (not partial and not branchmerge) or isrebase:
+ if repo.ui.configbool('_internal', 'keep-topic'):
+ ist0 = True
+ if ((not partial and not branchmerge) or isrebase) and not ist0:
ot = repo.currenttopic
t = ''
pctx = repo[node]
@@ -510,10 +646,25 @@
f.write(t)
if t and t != ot:
repo.ui.status(_("switching to topic %s\n") % t)
+ elif ist0:
+ repo.ui.status(_("preserving the current topic '%s'\n") %
+ repo.currenttopic)
return ret
finally:
wlock.release()
+def checkt0(orig, ui, repo, node=None, rev=None, *args, **kwargs):
+
+ thezeros = set(['t0', 'b0'])
+ backup = repo.ui.backupconfig('_internal', 'keep-topic')
+ try:
+ if node in thezeros or rev in thezeros:
+ repo.ui.setconfig('_internal', 'keep-topic', 'yes',
+ source='topic-extension')
+ return orig(ui, repo, node, rev, *args, **kwargs)
+ finally:
+ repo.ui.restoreconfig(backup)
+
def _fixrebase(loaded):
if not loaded:
return
--- a/hgext3rd/topic/revset.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/topic/revset.py Tue Jul 25 05:52:14 2017 +0200
@@ -78,7 +78,7 @@
topic = repo.currenttopic
if not topic:
branch = repo[None].branch()
- return revset.baseset(stack.getstack(repo, branch=branch, topic=topic)) & subset
+ return revset.baseset(stack.getstack(repo, branch=branch, topic=topic)[1:]) & subset
def modsetup(ui):
--- a/hgext3rd/topic/stack.py Sun Jul 09 15:01:32 2017 +0300
+++ b/hgext3rd/topic/stack.py Tue Jul 25 05:52:14 2017 +0200
@@ -10,6 +10,8 @@
)
from .evolvebits import builddependencies, _orderrevs, _singlesuccessor
+short = node.short
+
def getstack(repo, branch=None, topic=None):
# XXX need sorting
if topic is not None and branch is not None:
@@ -20,7 +22,13 @@
trevs = repo.revs("branch(%s) - public() - obsolete() - topic()", branch)
else:
raise error.ProgrammingError('neither branch and topic specified (not defined yet)')
- return _orderrevs(repo, trevs)
+ revs = _orderrevs(repo, trevs)
+ if revs:
+ pt1 = repo[revs[0]].p1()
+ if pt1.obsolete():
+ pt1 = repo[_singlesuccessor(repo, pt1)]
+ revs.insert(0, pt1.rev())
+ return revs
def labelsgen(prefix, labelssuffix):
""" Takes a label prefix and a list of suffixes. Returns a string of the prefix
@@ -84,8 +92,16 @@
fm.plain('%d behind' % data['behindcount'], label='topic.stack.summary.behindcount')
fm.plain('\n')
- for idx, r in enumerate(getstack(repo, branch=branch, topic=topic), 1):
+ for idx, r in enumerate(getstack(repo, branch=branch, topic=topic), 0):
ctx = repo[r]
+ # special case for t0, b0 as it's hard to plugin into rest of the logic
+ if idx == 0:
+ # t0, b0 can be None
+ if r == -1:
+ continue
+ entries.append((idx, False, ctx))
+ prev = ctx.rev()
+ continue
p1 = ctx.p1()
if p1.obsolete():
p1 = repo[_singlesuccessor(repo, p1)]
@@ -125,9 +141,14 @@
if idx is None:
fm.plain(' ')
+ if ui.verbose:
+ fm.plain(' ')
else:
fm.write('topic.stack.index', '%s%%d' % prefix, idx,
label='topic.stack.index ' + labelsgen('topic.stack.index.%s', states))
+ if ui.verbose:
+ fm.write('topic.stack.shortnode', '(%s)', short(ctx.node()),
+ label='topic.stack.shortnode ' + labelsgen('topic.stack.shortnode.%s', states))
fm.write('topic.stack.state.symbol', '%s', symbol,
label='topic.stack.state ' + labelsgen('topic.stack.state.%s', states))
fm.plain(' ')
@@ -148,7 +169,7 @@
:behindcount: number of changeset on rebase destination
"""
data = {}
- revs = getstack(repo, branch, topic)
+ revs = getstack(repo, branch, topic)[1:]
data['changesetcount'] = len(revs)
data['troubledcount'] = len([r for r in revs if repo[r].troubled()])
deps, rdeps = builddependencies(repo, revs)
--- a/tests/test-amend.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-amend.t Tue Jul 25 05:52:14 2017 +0200
@@ -1,11 +1,10 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ glog() {
- > hg glog --template '{rev}@{branch}({phase}) {desc|firstline}\n' "$@"
+ > hg log -G --template '{rev}@{branch}({phase}) {desc|firstline}\n' "$@"
> }
$ hg init repo --traceback
@@ -132,11 +131,9 @@
If you don't specify -m, the parent's message will be reused.
- Behind the scenes, Mercurial first commits the update as a regular child
- of the current parent. Then it creates a new commit on the parent's
- parents with the updated contents. Then it changes the working copy parent
- to this new combined changeset. Finally, the old changeset and its update
- are hidden from 'hg log' (unless you use --hidden with log).
+ If --extra is specified, the behavior of 'hg amend' is reversed: Changes
+ to selected files in the checked out revision appear again as uncommitted
+ changed in the working directory.
Returns 0 on success, 1 if nothing changed.
@@ -144,7 +141,9 @@
-A --addremove mark new/missing files as added/removed before
committing
+ -a --all match all files
-e --edit invoke editor on commit messages
+ --extract extract changes from the commit to the working copy
--close-branch mark a branch as closed, hiding it from the branch
list
-s --secret use the secret phase for committing
--- a/tests/test-corrupt.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-corrupt.t Tue Jul 25 05:52:14 2017 +0200
@@ -13,7 +13,6 @@
> git = 1
> unified = 0
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
@@ -30,7 +29,7 @@
$ mkcommit A
$ mkcommit B
$ mkcommit C
- $ hg glog
+ $ hg log -G
@ changeset: 2:829b19580856
| tag: tip
| user: test
@@ -67,7 +66,7 @@
$ hg up -q .^^
$ hg revert -r tip -a -q
$ hg ci -m 'coin' -q
- $ hg glog
+ $ hg log -G
@ changeset: 5:8313a6afebbb
| tag: tip
| parent: 2:829b19580856
--- a/tests/test-discovery-obshashrange.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-discovery-obshashrange.t Tue Jul 25 05:52:14 2017 +0200
@@ -34,23 +34,9 @@
* @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
* @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (8r, 0o) (glob)
* @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (8r, 0o) (glob)
* @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (8r, 0o) (glob)
* @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 exited 0 after *.?? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> blackbox (glob)
@@ -166,10 +152,10 @@
$ rm ../server/.hg/blackbox.log
$ hg blackbox
* @0000000000000000000000000000000000000000 (*)> pull --rev 4 (glob)
- * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
* @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (5r, 3o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated base branch cache in *.???? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> wrote base branch cache with 1 labels and 1 nodes (glob)
* @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (5r, 3o) (glob)
* @0000000000000000000000000000000000000000 (*)> 5 incoming changes - new heads: bebd167eb94d (glob)
* @0000000000000000000000000000000000000000 (*)> pull --rev 4 exited 0 after *.?? seconds (glob)
@@ -206,7 +192,7 @@
taking quick initial sample
query 2; still undecided: 5, sample size is: 5
sending known command
- 2 total queries
+ 2 total queries in *.????s (glob)
preparing listkeys for "phases"
sending listkeys command
received listkey for "phases": 58 bytes
@@ -238,7 +224,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 1 new obsolescence markers
- bundle2-input-bundle: with-transaction
+ bundle2-input-bundle: no-transaction
bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
bundle2-input-part: "reply:obsmarkers" (params: 0 advisory) supported
@@ -248,12 +234,12 @@
received listkey for "phases": 58 bytes
$ hg -R ../server blackbox
* @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
- * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> obscache is out of date, falling back to slower obsstore version (glob)
* @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
- * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob)
- * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
- * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (1r, 1o) (glob)
* @0000000000000000000000000000000000000000 (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
* @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
* @0000000000000000000000000000000000000000 (*)> blackbox (glob)
@@ -310,10 +296,11 @@
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> add foo (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> add foo exited 0 after *.?? seconds (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> commit -m foo (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated served branch cache in *.???? seconds (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 0o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obscache is out of date, falling back to slower obsstore version (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 1 nodes (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> commit -m foo exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
@@ -322,6 +309,7 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push -f --debug (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> found 1 common and 1 unknown server heads, 2 roundtrips in *.????s (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/5 mismatch - 1 obshashrange queries in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push -f --debug exited 0 after *.?? seconds (glob)
@@ -342,7 +330,7 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/6 mismatch - 1 obshashrange queries in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push exited True after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push exited 1 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
$ rm .hg/blackbox.log
$ hg debugobsolete | sort
@@ -421,13 +409,12 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/6 mismatch - 1 obshashrange queries in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (2r, 0o) (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (2r, 3o) (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 3o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (2r, 3o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 2 incoming changes - new heads: f69452c5b1af (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
@@ -567,17 +554,18 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev 'heads(all())' exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 1o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 1 incoming changes - new heads: 4de32a90b66c (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated base branch cache in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote base branch cache with 1 labels and 2 nodes (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-obscache cache reset (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (8r, 12o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
$ rm .hg/blackbox.log
@@ -617,11 +605,9 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev 'heads(all())' exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-obscache cache reset (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (9r, 12o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob)
- * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 1o) (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 1 incoming changes - new heads: 4de32a90b66c (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull exited 0 after *.?? seconds (glob)
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
@@ -695,10 +681,12 @@
pulling from ssh://user@dummy/server
searching for changes
OBSEXC: looking for common markers in 8 nodes
+ OBSEXC: request obsmarkers for 1 common nodes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
+ 2 new obsolescence markers
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg log -G
o 8 45f8b879de92 foo tip
@@ -728,9 +716,9 @@
* @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip -r 'desc("foo")' (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> saved backup bundle to $TESTTMP/client/.hg/strip-backup/45f8b879de92-94c82517-backup.hg (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-obshashrange cache reset (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (5r, 13o) (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (5r, 11o) (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-obscache cache reset (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (5r, 13o) (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (5r, 11o) (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated stablerange cache in *.???? seconds (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (3r, 0o) (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (3r, 0o) (glob)
@@ -742,12 +730,13 @@
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G exited 0 after *.?? seconds (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> pull (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> obsdiscovery, 1/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated stablerange cache in *.???? seconds (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 0o) (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated served branch cache in *.???? seconds (glob)
- * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 2o) (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated base branch cache in *.???? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote base branch cache with 1 labels and 2 nodes (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 2o) (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> pull exited 0 after *.?? seconds (glob)
* @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G (glob)
--- a/tests/test-divergent.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-divergent.t Tue Jul 25 05:52:14 2017 +0200
@@ -15,7 +15,6 @@
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline} [{troubles}]\n
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
--- a/tests/test-drop.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-drop.t Tue Jul 25 05:52:14 2017 +0200
@@ -1,7 +1,6 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ echo "drophack=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/hack/drophack.py" >> $HGRCPATH
@@ -207,11 +206,13 @@
| x changeset: 3:87ea30a976fd
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: pruned
| | summary: temporary amend commit for 34b6c051bf1f
| |
| x changeset: 2:34b6c051bf1f
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as a2c06c884bfe
| summary: add child
|
o changeset: 1:19509a42b0d0
@@ -263,4 +264,3 @@
summary: add base
============ obsmark ============
- 87ea30a976fdf235bf096f04899cb02a903873e2 0 {34b6c051bf1f78db6aef400776de5cb964470207} (*) {'ef1': '0', 'user': 'test'} (glob)
--- a/tests/test-evolve-cycles.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-cycles.t Tue Jul 25 05:52:14 2017 +0200
@@ -62,16 +62,19 @@
| tag: tip
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 2a34000d3544
| summary: C
|
x changeset: 2:c473644ee0e9
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as a8df460dbbfe
| summary: B
|
@ changeset: 1:2a34000d3544
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as c473644ee0e9
| summary: A
|
o changeset: 0:ea207398892e
@@ -204,31 +207,37 @@
| tag: tip
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 868d2e0eb19c
| summary: F
|
x changeset: 5:0da815c333f6
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as d9f908fde1a1
| summary: E
|
@ changeset: 4:868d2e0eb19c
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 0da815c333f6
| summary: D
|
x changeset: 3:a8df460dbbfe
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 2a34000d3544, 868d2e0eb19c
| summary: C
|
x changeset: 2:c473644ee0e9
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as a8df460dbbfe
| summary: B
|
x changeset: 1:2a34000d3544
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as c473644ee0e9
| summary: A
|
o changeset: 0:ea207398892e
--- a/tests/test-evolve-obshistory-complex.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-obshistory-complex.t Tue Jul 25 05:52:14 2017 +0200
@@ -99,21 +99,25 @@
x | | changeset: 4:868d2e0eb19c
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as d15d0ffc75f6
| | | summary: D
| | |
x | | changeset: 3:a8df460dbbfe
|/ / user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as d15d0ffc75f6
| | summary: C
| |
x | changeset: 2:c473644ee0e9
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as b868bc49b0a4
| | summary: B
| |
x | changeset: 1:2a34000d3544
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as b868bc49b0a4
| summary: A
|
o changeset: 0:ea207398892e
@@ -269,21 +273,25 @@
x | | changeset: 4:868d2e0eb19c
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: split as 7b3290f6e0a0, d0f33db50670
| | | summary: D
| | |
x | | changeset: 3:a8df460dbbfe
|/ / user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: split as 7b3290f6e0a0, d0f33db50670
| | summary: C
| |
x | changeset: 2:c473644ee0e9
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: split as 19e14c8397fc, e036916b63ea
| | summary: B
| |
x | changeset: 1:2a34000d3544
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 19e14c8397fc, e036916b63ea
| summary: A
|
o changeset: 0:ea207398892e
@@ -330,21 +338,25 @@
x | | changeset: 4:868d2e0eb19c
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: split as 7b3290f6e0a0, ec31316faa9d
| | | summary: D
| | |
x | | changeset: 3:a8df460dbbfe
|/ / user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: split as 7b3290f6e0a0, ec31316faa9d
| | summary: C
| |
x | changeset: 2:c473644ee0e9
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: split as 19e14c8397fc, 7b3290f6e0a0
| | summary: B
| |
x | changeset: 1:2a34000d3544
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 19e14c8397fc, 7b3290f6e0a0
| summary: A
|
o changeset: 0:ea207398892e
--- a/tests/test-evolve-obshistory.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-obshistory.t Tue Jul 25 05:52:14 2017 +0200
@@ -41,11 +41,13 @@
| x changeset: 2:f137d23bb3e1
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: pruned
| | summary: temporary amend commit for 471f378eab4c
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 4ae3a4151de9
| summary: A0
|
o changeset: 0:ea207398892e
@@ -59,7 +61,7 @@
@ 4ae3a4151de9 (3) A1
|
x 471f378eab4c (1) A0
- rewritten(description, content) by test (*) as 4ae3a4151de9 (glob)
+ rewritten(description, content) by test (Thu Jan 01 00:00:00 1970 +0000) as 4ae3a4151de9
--- a/471f378eab4c-changeset-description
+++ b/4ae3a4151de9-changeset-description
@@ -1,1 +1,3 @@
@@ -197,6 +199,7 @@
| tag: tip
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: pruned
| summary: B0
|
@ changeset: 1:471f378eab4c
@@ -336,6 +339,7 @@
| x changeset: 1:471597cad322
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 337fec4d2edc, f257fde29c7a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -589,6 +593,7 @@
| x changeset: 1:de7290d8b885
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -764,11 +769,13 @@
| x changeset: 2:0dec01379d3b
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as eb5a0daa2192
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -969,6 +976,7 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1001,6 +1009,8 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
+ | obsolete: rewritten as 65b757b745b9
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1282,6 +1292,7 @@
| x changeset: 2:0dec01379d3b
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as b7ea6d14e664
| summary: B0
|
o changeset: 1:471f378eab4c
@@ -1309,16 +1320,19 @@
| | parent: 1:471f378eab4c
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as eb5a0daa2192
| | summary: B1
| |
| | x changeset: 2:0dec01379d3b
| |/ user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as b7ea6d14e664
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1542,11 +1556,13 @@
|/ parent: 0:ea207398892e
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 7a230b46bf61
| summary: A1
|
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1587,6 +1603,7 @@
adding file changes
added 1 changesets with 0 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads, 'hg merge' to merge)
working directory parent is obsolete! (471f378eab4c)
(use 'hg evolve' to update to its successor: 7a230b46bf61)
--- a/tests/test-evolve-order.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-order.t Tue Jul 25 05:52:14 2017 +0200
@@ -16,7 +16,6 @@
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
--- a/tests/test-evolve-serveronly-bundle2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-serveronly-bundle2.t Tue Jul 25 05:52:14 2017 +0200
@@ -108,6 +108,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 2 new obsolescence markers
+ remote: obsoleted 1 changesets
$ cat ../errors.log
$ hg push
pushing to http://localhost:$HGPORT/
@@ -127,6 +128,7 @@
adding file changes
added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
2 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads)
$ cat ../errors.log
$ hg -R ../other pull
--- a/tests/test-evolve-serveronly.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-serveronly.t Tue Jul 25 05:52:14 2017 +0200
@@ -116,6 +116,7 @@
(please upgrade your server)
pushing 2 obsolescence markers (* bytes) (glob)
remote: 2 obsolescence markers added
+ remote: obsoleted 1 changesets
$ cat ../errors.log
$ hg push
pushing to http://localhost:$HGPORT/
@@ -139,6 +140,7 @@
pulling obsmarker using legacy method
(please upgrade your server)
2 obsolescence markers added
+ obsoleted 1 changesets
(run 'hg heads' to see heads)
$ cat ../errors.log
$ hg -R ../other pull
--- a/tests/test-evolve-split.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-split.t Tue Jul 25 05:52:14 2017 +0200
@@ -15,7 +15,6 @@
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
--- a/tests/test-evolve-templates.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-templates.t Tue Jul 25 05:52:14 2017 +0200
@@ -47,16 +47,19 @@
|/ parent: 0:ea207398892e
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten by test2 as d004c8f274b9
| summary: A1
|
| x changeset: 2:f137d23bb3e1
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: pruned by test1
| | summary: temporary amend commit for 471f378eab4c
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten by test1 as a468dc9b3633
| summary: A0
|
o changeset: 0:ea207398892e
@@ -76,10 +79,10 @@
o d004c8f274b9 (4) A2
|
x a468dc9b3633 (3) A1
- | rewritten(description) by test2 (*) as d004c8f274b9 (glob)
+ | rewritten(description) by test2 (Thu Apr 19 04:25:21 2001 +0000) as d004c8f274b9
|
@ 471f378eab4c (1) A0
- rewritten(description, content) by test1 (*) as a468dc9b3633 (glob)
+ rewritten(description, content) by test1 (Fri Feb 13 23:31:30 2009 +0000) as a468dc9b3633
$ hg tlog
o d004c8f274b9
@@ -113,7 +116,7 @@
o d004c8f274b9
|
| @ 471f378eab4c
- |/ Obsfate: rewritten by test1, test2 as d004c8f274b9 (between * and *) (glob)
+ |/ Obsfate: rewritten by test1, test2 as d004c8f274b9 (between 2001-04-19 04:25 +0000 and 2009-02-13 23:31 +0000)
|
o ea207398892e
@@ -180,7 +183,7 @@
o d004c8f274b9
|
| @ a468dc9b3633
- |/ Obsfate: rewritten by test2 as d004c8f274b9 (at *) (glob)
+ |/ Obsfate: rewritten by test2 as d004c8f274b9 (at 2001-04-19 04:25 +0000)
|
o ea207398892e
@@ -222,13 +225,13 @@
@ d004c8f274b9
|
| x a468dc9b3633
- |/ Obsfate: rewritten by test2 as d004c8f274b9 (at *) (glob)
+ |/ Obsfate: rewritten by test2 as d004c8f274b9 (at 2001-04-19 04:25 +0000)
|
| x f137d23bb3e1
- | | Obsfate: pruned by test1 (at *) (glob)
+ | | Obsfate: pruned by test1 (at 2009-02-13 23:31 +0000)
| |
| x 471f378eab4c
- |/ Obsfate: rewritten by test1 as a468dc9b3633 (at *) (glob)
+ |/ Obsfate: rewritten by test1 as a468dc9b3633 (at 2009-02-13 23:31 +0000)
|
o ea207398892e
@@ -236,11 +239,11 @@
$ hg fatelogjson --hidden
@ d004c8f274b9 ""
|
- | x a468dc9b3633 [{"markers": [["a468dc9b36338b14fdb7825f55ce3df4e71517ad", ["d004c8f274b9ec480a47a93c10dac5eee63adb78"], 0, [["ef1", "1"], ["user", "test2"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["d004c8f274b9ec480a47a93c10dac5eee63adb78"], "users": ["test2"], "verb": "rewritten"}] (glob)
+ | x a468dc9b3633 [{"markers": [["a468dc9b36338b14fdb7825f55ce3df4e71517ad", ["d004c8f274b9ec480a47a93c10dac5eee63adb78"], 0, [["ef1", "1"], ["user", "test2"]], [987654321.0, 0], null]], "max_date": [987654321.0, 0], "min_date": [987654321.0, 0], "successors": ["d004c8f274b9ec480a47a93c10dac5eee63adb78"], "users": ["test2"], "verb": "rewritten"}]
|/
- | x f137d23bb3e1 [{"markers": [["f137d23bb3e11dc1daeb6264fac9cb2433782e15", [], 0, [["ef1", "0"], ["user", "test1"]], [*, 0], ["471f378eab4c5e25f6c77f785b27c936efb22874"]]], "max_date": [*, 0], "min_date": [*, 0], "successors": [], "users": ["test1"], "verb": "pruned"}] (glob)
+ | x f137d23bb3e1 [{"markers": [["f137d23bb3e11dc1daeb6264fac9cb2433782e15", [], 0, [["ef1", "0"], ["user", "test1"]], [1234567890.0, 0], ["471f378eab4c5e25f6c77f785b27c936efb22874"]]], "max_date": [1234567890.0, 0], "min_date": [1234567890.0, 0], "successors": [], "users": ["test1"], "verb": "pruned"}]
| |
- | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"], 0, [["ef1", "9"], ["user", "test1"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"], "users": ["test1"], "verb": "rewritten"}] (glob)
+ | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"], 0, [["ef1", "9"], ["user", "test1"]], [1234567890.0, 0], null]], "max_date": [1234567890.0, 0], "min_date": [1234567890.0, 0], "successors": ["a468dc9b36338b14fdb7825f55ce3df4e71517ad"], "users": ["test1"], "verb": "rewritten"}]
|/
o ea207398892e ""
@@ -319,6 +322,7 @@
| x changeset: 1:471597cad322
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: split as 337fec4d2edc, f257fde29c7a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -405,7 +409,7 @@
|
o 337fec4d2edc ""
|
- | x 471597cad322 [{"markers": [["471597cad322d1f659bb169751be9133dad92ef3", ["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"], 0, [["ef1", "12"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"], "users": ["test"], "verb": "split"}] (glob)
+ | x 471597cad322 [{"markers": [["471597cad322d1f659bb169751be9133dad92ef3", ["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"], 0, [["ef1", "12"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["337fec4d2edcf0e7a467e35f818234bc620068b5", "f257fde29c7a847c9b607f6e958656d0df0fb15c"], "users": ["test"], "verb": "split"}]
|/
o ea207398892e ""
@@ -452,11 +456,13 @@
| x changeset: 2:0dec01379d3b
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as eb5a0daa2192
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -570,9 +576,9 @@
$ hg fatelogjson --hidden
@ eb5a0daa2192 ""
|
- | x 0dec01379d3b [{"markers": [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "13"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 0dec01379d3b [{"markers": [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "13"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}]
| |
- | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "9"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "9"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}]
|/
o ea207398892e ""
@@ -599,6 +605,7 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -631,6 +638,8 @@
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
+ | obsolete: rewritten as 65b757b745b9
| summary: A0
|
o changeset: 0:ea207398892e
@@ -734,11 +743,11 @@
$ hg fatelogjson --hidden
o 019fadeab383 ""
|
- | x 65b757b745b9 [{"markers": [["65b757b745b935093c87a2bccd877521cccffcbd", ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 65b757b745b9 [{"markers": [["65b757b745b935093c87a2bccd877521cccffcbd", ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["019fadeab383f6699fa83ad7bdb4d82ed2c0e5ab"], "users": ["test"], "verb": "rewritten"}]
|/
| @ fdf9bde5129a ""
|/
- | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], "users": ["test"], "verb": "rewritten"}, {"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["65b757b745b935093c87a2bccd877521cccffcbd"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["65b757b745b935093c87a2bccd877521cccffcbd"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], "users": ["test"], "verb": "rewritten"}, {"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["65b757b745b935093c87a2bccd877521cccffcbd"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["65b757b745b935093c87a2bccd877521cccffcbd"], "users": ["test"], "verb": "rewritten"}]
|/
o ea207398892e ""
@@ -766,6 +775,7 @@
| x changeset: 2:0dec01379d3b
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as b7ea6d14e664
| summary: B0
|
o changeset: 1:471f378eab4c
@@ -793,16 +803,19 @@
| | parent: 1:471f378eab4c
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as eb5a0daa2192
| | summary: B1
| |
| | x changeset: 2:0dec01379d3b
| |/ user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as b7ea6d14e664
| | summary: B0
| |
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as eb5a0daa2192
| summary: A0
|
o changeset: 0:ea207398892e
@@ -947,11 +960,11 @@
$ hg fatelogjson --hidden
@ eb5a0daa2192 ""
|
- | x b7ea6d14e664 [{"markers": [["b7ea6d14e664bdc8922221f7992631b50da3fb07", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "13"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x b7ea6d14e664 [{"markers": [["b7ea6d14e664bdc8922221f7992631b50da3fb07", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "13"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}]
| |
- | | x 0dec01379d3b [{"markers": [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", ["b7ea6d14e664bdc8922221f7992631b50da3fb07"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["b7ea6d14e664bdc8922221f7992631b50da3fb07"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | | x 0dec01379d3b [{"markers": [["0dec01379d3be6318c470ead31b1fe7ae7cb53d5", ["b7ea6d14e664bdc8922221f7992631b50da3fb07"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["b7ea6d14e664bdc8922221f7992631b50da3fb07"], "users": ["test"], "verb": "rewritten"}]
| |/
- | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "9"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], 0, [["ef1", "9"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["eb5a0daa21923bbf8caeb2c42085b9e463861fd0"], "users": ["test"], "verb": "rewritten"}]
|/
o ea207398892e ""
@@ -997,11 +1010,13 @@
|/ parent: 0:ea207398892e
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 7a230b46bf61
| summary: A1
|
| x changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as fdf9bde5129a
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1018,6 +1033,7 @@
adding file changes
added 1 changesets with 0 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads, 'hg merge' to merge)
working directory parent is obsolete! (471f378eab4c)
(use 'hg evolve' to update to its successor: 7a230b46bf61)
@@ -1032,6 +1048,7 @@
| @ changeset: 1:471f378eab4c
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 7a230b46bf61
| summary: A0
|
o changeset: 0:ea207398892e
@@ -1057,7 +1074,7 @@
o 7a230b46bf61
|
| @ 471f378eab4c
- |/ Obsfate: rewritten by test as 7a230b46bf61 (between * and *) (glob)
+ |/ Obsfate: rewritten by test as 7a230b46bf61 (at 1970-01-01 00:00 +0000)
|
o ea207398892e
@@ -1088,7 +1105,7 @@
@ 7a230b46bf61
|
| x 471f378eab4c
- |/ Obsfate: rewritten by test as 7a230b46bf61 (between * and *) (glob)
+ |/ Obsfate: rewritten by test as 7a230b46bf61 (at 1970-01-01 00:00 +0000)
|
o ea207398892e
@@ -1096,7 +1113,7 @@
$ hg fatelogjson --hidden
@ 7a230b46bf61 ""
|
- | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null], ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e", ["7a230b46bf61e50b30308c6cfd7bd1269ef54702"], 0, [["ef1", "1"], ["user", "test"]], [*, 0], null]], "max_date": [*, 0], "min_date": [*, 0], "successors": ["7a230b46bf61e50b30308c6cfd7bd1269ef54702"], "users": ["test"], "verb": "rewritten"}] (glob)
+ | x 471f378eab4c [{"markers": [["471f378eab4c5e25f6c77f785b27c936efb22874", ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null], ["fdf9bde5129a28d4548fadd3f62b265cdd3b7a2e", ["7a230b46bf61e50b30308c6cfd7bd1269ef54702"], 0, [["ef1", "1"], ["user", "test"]], [0.0, 0], null]], "max_date": [0.0, 0], "min_date": [0.0, 0], "successors": ["7a230b46bf61e50b30308c6cfd7bd1269ef54702"], "users": ["test"], "verb": "rewritten"}]
|/
o ea207398892e ""
@@ -1131,7 +1148,7 @@
$ hg fatelog -v
@ 471f378eab4c
- | Obsfate: pruned by test (at *) (glob)
+ | Obsfate: pruned by test (at 1970-01-01 00:00 +0000)
|
o ea207398892e
--- a/tests/test-evolve-topic.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve-topic.t Tue Jul 25 05:52:14 2017 +0200
@@ -78,7 +78,7 @@
t3: add eee
t2: add ddd
t1: add ccc
- ^ add bbb
+ t0^ add bbb (base)
$ hg up 'desc(ddd)'
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ echo ddd >> ddd
@@ -209,9 +209,14 @@
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[16] add ggg
$ hg prev
+ preserving the current topic 'bar'
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ [15] add fff
+ $ hg prev
no parent in topic "bar"
(do you want --no-topic)
+ [1]
$ hg prev --no-topic
switching to topic foo
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- [15] add fff
+ [14] add eee
--- a/tests/test-evolve.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-evolve.t Tue Jul 25 05:52:14 2017 +0200
@@ -14,7 +14,6 @@
> git = 1
> unified = 0
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
@@ -31,7 +30,7 @@
> }
$ glog() {
- > hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+ > hg log -G --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
> }
$ shaof() {
@@ -81,6 +80,38 @@
Obsolescence markers will be exchanged between repositories that
explicitly assert support for the obsolescence feature (this can currently
only be done via an extension).
+
+ Instability ==========
+
+ (note: the vocabulary is in the process of being updated)
+
+ Rewriting changesets might introduce instability (currently 'trouble').
+
+ There are two main kinds of instability: orphaning and diverging.
+
+ Orphans are changesets left behind when their ancestors are rewritten,
+ (currently: 'unstable'). Divergence has two variants:
+
+ * Content-divergence occurs when independent rewrites of the same
+ changesets lead to different results. (currently: 'divergent')
+ * Phase-divergence occurs when the old (obsolete) version of a changeset
+ becomes public. (currently: 'bumped')
+
+ If it possible to prevent local creation of orphans by using the following
+ config:
+
+ [experimental]
+ evolution=createmarkers,allnewcommands,exchange
+
+ You can also enable that option explicitly:
+
+ [experimental]
+ evolution=createmarkers,allnewcommands,allowunstable,exchange
+
+ or simply:
+
+ [experimental]
+ evolution=all
various init
@@ -114,7 +145,7 @@
$ hg log -r 1 --template '{rev} {phase} {obsolete}\n'
1 public
$ hg prune 1
- abort: cannot prune immutable changeset: 7c3bad9141dc
+ abort: cannot touch public changesets: 7c3bad9141dc
(see 'hg help phases' for details)
[255]
$ hg log -r 1 --template '{rev} {phase} {obsolete}\n'
@@ -372,7 +403,7 @@
all solving bumped troubled
- $ hg glog
+ $ hg log -G
@ 8 feature-B: another feature that rox - test
|
| o 7 : another feature (child of ba0ec09b1bab) - test
@@ -387,7 +418,7 @@
computing new diff
committed as 6707c5e1c49d
working directory is now at 6707c5e1c49d
- $ hg glog
+ $ hg log -G
@ 9 feature-B: bumped update to 99833d22b0c6: - test
|
o 7 : another feature (child of ba0ec09b1bab) - test
@@ -446,7 +477,7 @@
atop:[14] dansk 2!
merging main-file-1
working directory is now at 68557e4f0048
- $ hg glog
+ $ hg log -G
@ 15 : dansk 3! - test
|
o 14 : dansk 2! - test
@@ -683,48 +714,13 @@
Test fold
+(most of the testing have been moved to test-fold
$ rm *.orig
- $ hg fold
- abort: no revisions specified
- [255]
- $ hg fold --from
- abort: no revisions specified
- [255]
- $ hg fold .
- abort: must specify either --from or --exact
- [255]
- $ hg fold --from . --exact
- abort: cannot use both --from and --exact
- [255]
- $ hg fold --from .
- single revision specified, nothing to fold
- [1]
- $ hg fold 0::10 --rev 1 --exact
- abort: cannot fold non-linear revisions (multiple heads given)
- [255]
- $ hg fold -r 4 -r 6 --exact
- abort: cannot fold non-linear revisions (multiple roots given)
- [255]
- $ hg fold --from 10 1
- abort: cannot fold non-linear revisions
- (given revisions are unrelated to parent of working directory)
- [255]
- $ hg fold --exact -r "4 and not 4"
- abort: specified revisions evaluate to an empty set
- (use different revision arguments)
- [255]
$ hg phase --public 0
- $ hg fold --from -r 0
- abort: cannot fold public revisions
- [255]
$ hg fold --from -r 5
3 changesets folded
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg fold --from 6 # want to run hg fold 6
- abort: hidden revision '6'!
- (use --hidden to access hidden revisions; successor: af636757ce3b)
- [255]
$ hg log -r 11 --template '{desc}\n'
add 3
@@ -1019,7 +1015,7 @@
$ hg commit -m "add new file bumped" -o 11
$ hg phase --public --hidden 11
1 new bumped changesets
- $ hg glog
+ $ hg log -G
@ 12 : add new file bumped - test
|
| o 11 : a2 - test
@@ -1038,7 +1034,7 @@
Now we have a bumped and an unstable changeset, we solve the bumped first
normally the unstable changeset would be solve first
- $ hg glog
+ $ hg log -G
@ 12 : add new file bumped - test
|
| o 11 : a2 - test
@@ -1074,7 +1070,7 @@
$ hg up 14
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ printf "newline\nnewline\n" >> a
- $ hg glog
+ $ hg log -G
o 16 : add gh - test
|
| o 15 : add gg - test
@@ -1091,7 +1087,7 @@
$ hg amend
2 new unstable changesets
- $ hg glog
+ $ hg log -G
@ 18 : a3 - test
|
| o 16 : add gh - test
@@ -1124,7 +1120,7 @@
move:[16] add gh
atop:[18] a3
working directory is now at e02107f98737
- $ hg glog
+ $ hg log -G
@ 20 : add gh - test
|
| o 19 : add gg - test
@@ -1284,7 +1280,8 @@
$ hg up 8dc373be86d9^
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ hg uncommit --all
- abort: cannot uncommit in the middle of a stack
+ abort: uncommit will orphan 4 descendants
+ (see 'hg help evolution.instability')
[255]
$ hg up 8dc373be86d9
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -1342,12 +1339,12 @@
$ mkcommit c5_
created new head
$ hg prune '26 + 27'
- abort: cannot prune in the middle of a stack
- (new unstable changesets are not allowed)
+ abort: touch will orphan 1 descendants
+ (see 'hg help evolution.instability')
[255]
$ hg prune '19::28'
- abort: cannot prune in the middle of a stack
- (new unstable changesets are not allowed)
+ abort: touch will orphan 1 descendants
+ (see 'hg help evolution.instability')
[255]
$ hg prune '26::'
3 changesets pruned
@@ -1363,6 +1360,9 @@
~
Check that fold respects the allowunstable option
+
+(most of this has been moved to test-fold.t)
+
$ hg up edc3c9de504e
0 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ mkcommit unstableifparentisfolded
@@ -1380,14 +1380,6 @@
|
~
- $ hg fold --exact "19 + 18"
- abort: cannot fold chain not ending with a head or with branching
- (new unstable changesets are not allowed)
- [255]
- $ hg fold --exact "18::29"
- abort: cannot fold chain not ending with a head or with branching
- (new unstable changesets are not allowed)
- [255]
$ hg fold --exact "19::"
2 changesets folded
--- a/tests/test-exchange-obsmarkers-case-A3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-A3.t Tue Jul 25 05:52:14 2017 +0200
@@ -73,7 +73,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ f6298a8ac3a4 (draft): B1
|
@@ -174,7 +176,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ f6298a8ac3a4 (draft): B1
|
@@ -242,6 +246,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 1 new obsolescence markers
+ remote: obsoleted 1 changesets
## post push state
# obstore: main
28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -257,6 +262,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads, 'hg merge' to merge)
1 new unstable changesets
## post pull state
--- a/tests/test-exchange-obsmarkers-case-A4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-A4.t Tue Jul 25 05:52:14 2017 +0200
@@ -64,6 +64,7 @@
created new head
$ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A0)'`
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ e5ea8f9c7314 (draft): A1
|
--- a/tests/test-exchange-obsmarkers-case-A5.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-A5.t Tue Jul 25 05:52:14 2017 +0200
@@ -66,7 +66,9 @@
$ mkcommit A1
$ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A0)'`
$ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+ obsoleted 1 changesets
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 8c0a98c83722 (draft): A1
|
--- a/tests/test-exchange-obsmarkers-case-A6.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-A6.t Tue Jul 25 05:52:14 2017 +0200
@@ -64,6 +64,7 @@
create a marker after this
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ e5ea8f9c7314 (draft): A1
|
@@ -108,6 +109,7 @@
searching for changes
no changes found
remote: 1 new obsolescence markers
+ remote: obsoleted 1 changesets
## post push state
# obstore: main
28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -118,6 +120,7 @@
pulling from main
no changes found
1 new obsolescence markers
+ obsoleted 1 changesets
## post pull state
# obstore: main
28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -141,6 +144,7 @@
searching for changes
no changes found
remote: 1 new obsolescence markers
+ remote: obsoleted 1 changesets
## post push state
# obstore: main
28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -152,6 +156,7 @@
searching for changes
no changes found
1 new obsolescence markers
+ obsoleted 1 changesets
## post pull state
# obstore: main
28b51eb45704506b5c603decd6bf7ac5e0f6a52f e5ea8f9c73143125d36658e90ef70c6d2027a5b7 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
--- a/tests/test-exchange-obsmarkers-case-B5.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-B5.t Tue Jul 25 05:52:14 2017 +0200
@@ -70,8 +70,10 @@
created new head
$ mkcommit B1
$ hg debugobsolete --hidden `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg debugobsolete --hidden aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(B0)'`
$ hg debugobsolete --hidden `getid 'desc(B0)'` `getid 'desc(B1)'`
+ obsoleted 1 changesets
$ hg prune -qd '0 0' 'desc(B1)'
$ hg log -G --hidden
x 069b05c3876d (draft): B1
--- a/tests/test-exchange-obsmarkers-case-B6.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-B6.t Tue Jul 25 05:52:14 2017 +0200
@@ -57,6 +57,7 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid 'desc(B0)'` `getid 'desc(B1)'`
+ obsoleted 1 changesets
$ hg prune -qd '0 0' .
$ hg log -G --hidden
x f6298a8ac3a4 (draft): B1
--- a/tests/test-exchange-obsmarkers-case-C2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-C2.t Tue Jul 25 05:52:14 2017 +0200
@@ -62,6 +62,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ e5ea8f9c7314 (draft): A1
|
--- a/tests/test-exchange-obsmarkers-case-C3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-C3.t Tue Jul 25 05:52:14 2017 +0200
@@ -64,6 +64,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg prune -qd '0 0' .
$ hg log -G --hidden
x e5ea8f9c7314 (draft): A1
--- a/tests/test-exchange-obsmarkers-case-C4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-C4.t Tue Jul 25 05:52:14 2017 +0200
@@ -65,6 +65,7 @@
$ mkcommit C
created new head
$ hg debugobsolete --hidden `getid 'desc(A)'` `getid 'desc(B)'`
+ obsoleted 1 changesets
$ hg debugobsolete --hidden `getid 'desc(A)'` `getid 'desc(C)'`
$ hg prune -qd '0 0' .
$ hg log -G --hidden
--- a/tests/test-exchange-obsmarkers-case-D1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-D1.t Tue Jul 25 05:52:14 2017 +0200
@@ -61,6 +61,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg prune -d '0 0' 'desc(B)'
1 changesets pruned
$ hg strip --hidden -q 'desc(A0)' --config devel.strip-obsmarkers=no
--- a/tests/test-exchange-obsmarkers-case-D2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-D2.t Tue Jul 25 05:52:14 2017 +0200
@@ -54,6 +54,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg prune --date '0 0' .
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
working directory now at a9bdc8b26820
--- a/tests/test-exchange-obsmarkers-case-D3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-D3.t Tue Jul 25 05:52:14 2017 +0200
@@ -57,6 +57,7 @@
created new head
$ mkcommit A1
$ hg debugobsolete `getid 'desc(A0)'` `getid 'desc(A1)'`
+ obsoleted 1 changesets
$ hg prune -d '0 0' .
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
working directory now at 35b183996678
--- a/tests/test-exchange-obsmarkers-case-D4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-exchange-obsmarkers-case-D4.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,8 +59,10 @@
created new head
$ mkcommit B1
$ hg debugobsolete `getid 'desc(A0)'` aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+ obsoleted 1 changesets
$ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(A1)'`
$ hg debugobsolete `getid 'desc(B0)'` bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ obsoleted 1 changesets
$ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb `getid 'desc(B1)'`
$ hg log -G --hidden
@ 069b05c3876d (draft): B1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-fold.t Tue Jul 25 05:52:14 2017 +0200
@@ -0,0 +1,225 @@
+ $ . $TESTDIR/testlib/common.sh
+
+setup
+
+ $ cat >> $HGRCPATH <<EOF
+ > [defaults]
+ > fold=-d "0 0"
+ > [extensions]
+ > evolve=
+ > [ui]
+ > logtemplate = '{rev} - {node|short} {desc|firstline} [{author}] ({phase})\n'
+ > EOF
+
+ $ hg init fold-tests
+ $ cd fold-tests/
+ $ hg debugbuilddag .+3:branchpoint+4*branchpoint+2
+ $ hg up 'desc("r7")'
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg log -G
+ o 10 - a8407f9a3dc1 r10 [debugbuilddag] (draft)
+ |
+ o 9 - 529dfc5bb875 r9 [debugbuilddag] (draft)
+ |
+ o 8 - abf57d94268b r8 [debugbuilddag] (draft)
+ |
+ | @ 7 - 4de32a90b66c r7 [debugbuilddag] (draft)
+ | |
+ | o 6 - f69452c5b1af r6 [debugbuilddag] (draft)
+ | |
+ | o 5 - c8d03c1b5e94 r5 [debugbuilddag] (draft)
+ | |
+ | o 4 - bebd167eb94d r4 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (draft)
+
+
+Test various error case
+
+ $ hg fold --exact null::
+ abort: cannot fold the null revision
+ (no changeset checked out)
+ [255]
+ $ hg fold
+ abort: no revisions specified
+ [255]
+ $ hg fold --from
+ abort: no revisions specified
+ [255]
+ $ hg fold .
+ abort: must specify either --from or --exact
+ [255]
+ $ hg fold --from . --exact
+ abort: cannot use both --from and --exact
+ [255]
+ $ hg fold --from .
+ single revision specified, nothing to fold
+ [1]
+ $ hg fold '0::(7+10)' --exact
+ abort: cannot fold non-linear revisions (multiple heads given)
+ [255]
+ $ hg fold -r 4 -r 6 --exact
+ abort: cannot fold non-linear revisions (multiple roots given)
+ [255]
+ $ hg fold --from 10 1
+ abort: cannot fold non-linear revisions
+ (given revisions are unrelated to parent of working directory)
+ [255]
+ $ hg fold --exact -r "4 and not 4"
+ abort: specified revisions evaluate to an empty set
+ (use different revision arguments)
+ [255]
+ $ hg phase --public 0
+ $ hg fold --from -r 0
+ abort: cannot fold public changesets: 1ea73414a91b
+ (see 'hg help phases' for details)
+ [255]
+
+Test actual folding
+
+ $ hg fold --from -r 'desc("r5")'
+ 3 changesets folded
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+(test inherited from test-evolve.t)
+
+ $ hg fold --from 6 # want to run hg fold 6
+ abort: hidden revision '6'!
+ (use --hidden to access hidden revisions; successor: 198b5c405d01)
+ [255]
+
+ $ hg log -G
+ @ 11 - 198b5c405d01 r5 [debugbuilddag] (draft)
+ |
+ | o 10 - a8407f9a3dc1 r10 [debugbuilddag] (draft)
+ | |
+ | o 9 - 529dfc5bb875 r9 [debugbuilddag] (draft)
+ | |
+ | o 8 - abf57d94268b r8 [debugbuilddag] (draft)
+ | |
+ o | 4 - bebd167eb94d r4 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (public)
+
+
+test fold --exact
+
+ $ hg fold --exact 'desc("r8") + desc("r10")'
+ abort: cannot fold non-linear revisions (multiple roots given)
+ [255]
+ $ hg fold --exact 'desc("r8")::desc("r10")'
+ 3 changesets folded
+ $ hg log -G
+ o 12 - b568edbee6e0 r8 [debugbuilddag] (draft)
+ |
+ | @ 11 - 198b5c405d01 r5 [debugbuilddag] (draft)
+ | |
+ | o 4 - bebd167eb94d r4 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (public)
+
+
+Test allow unstable
+
+ $ echo a > a
+ $ hg add a
+ $ hg commit '-m r11'
+ $ hg up '.^'
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg log -G
+ o 13 - 14d0e0da8e91 r11 [test] (draft)
+ |
+ | o 12 - b568edbee6e0 r8 [debugbuilddag] (draft)
+ | |
+ @ | 11 - 198b5c405d01 r5 [debugbuilddag] (draft)
+ | |
+ o | 4 - bebd167eb94d r4 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (public)
+
+
+ $ cat << EOF >> .hg/hgrc
+ > [experimental]
+ > evolution = createmarkers, allnewcommands
+ > EOF
+ $ hg fold --from 'desc("r4")'
+ abort: fold will orphan 1 descendants
+ (see 'hg help evolution.instability')
+ [255]
+ $ hg fold --from 'desc("r3")::desc("r11")'
+ abort: fold will orphan 1 descendants
+ (see 'hg help evolution.instability')
+ [255]
+
+test --user variant
+
+ $ cat << EOF >> .hg/hgrc
+ > [experimental]
+ > evolution = createmarkers, allnewcommands
+ > EOF
+ $ cat << EOF >> .hg/hgrc
+ > [experimental]
+ > evolution = all
+ > EOF
+
+ $ hg fold --exact 'desc("r5") + desc("r11")' --user 'Victor Rataxes <victor@rhino.savannah>'
+ 2 changesets folded
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg log -G
+ @ 14 - 29b470a33594 r5 [Victor Rataxes <victor@rhino.savannah>] (draft)
+ |
+ | o 12 - b568edbee6e0 r8 [debugbuilddag] (draft)
+ | |
+ o | 4 - bebd167eb94d r4 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (public)
+
+
+ $ hg fold --from 'desc("r4")' -U
+ 2 changesets folded
+ 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg log -G
+ @ 15 - 91880abed0f2 r4 [test] (draft)
+ |
+ | o 12 - b568edbee6e0 r8 [debugbuilddag] (draft)
+ |/
+ o 3 - 2dc09a01254d r3 [debugbuilddag] (draft)
+ |
+ o 2 - 01241442b3c2 r2 [debugbuilddag] (draft)
+ |
+ o 1 - 66f7d451a68b r1 [debugbuilddag] (draft)
+ |
+ o 0 - 1ea73414a91b r0 [debugbuilddag] (public)
+
+ $ cd ..
+
--- a/tests/test-inhibit.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-inhibit.t Tue Jul 25 05:52:14 2017 +0200
@@ -686,6 +686,8 @@
adding manifests
adding file changes
added 2 changesets with 1 changes to 2 files (+1 heads)
+ 3 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads .' to see heads, 'hg merge' to merge)
Only allow direct access and check that evolve works like before
--- a/tests/test-metaedit.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-metaedit.t Tue Jul 25 05:52:14 2017 +0200
@@ -14,7 +14,6 @@
> git = 1
> unified = 0
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
@@ -31,7 +30,7 @@
> }
$ glog() {
- > hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+ > hg log -G --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
> }
$ shaof() {
@@ -104,7 +103,8 @@
abort: revisions must be specified with --fold
[255]
$ hg metaedit -r 0 --fold
- abort: cannot fold public revisions
+ abort: cannot fold public changesets: ea207398892e
+ (see 'hg help phases' for details)
[255]
$ hg metaedit 'desc(C) + desc(F)' --fold
abort: cannot fold non-linear revisions (multiple roots given)
@@ -118,8 +118,8 @@
(587528abfffe will become unstable and new unstable changes are not allowed)
[255]
$ hg metaedit 'desc(A)::desc(B)' --fold --config 'experimental.evolution=createmarkers, allnewcommands'
- abort: cannot fold chain not ending with a head or with branching
- (new unstable changesets are not allowed)
+ abort: fold will orphan 4 descendants
+ (see 'hg help evolution.instability')
[255]
$ hg metaedit --user foobar
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -209,7 +209,7 @@
$ hg diff -r "10" -r "11" --hidden
'fold' one commit
- $ hg metaedit "desc(D2)" --fold --user foobar3
+ $ HGUSER=foobar3 hg metaedit "desc(D2)" --fold -U --config
1 changesets folded
$ hg log -r "tip" --template '{rev}: {author}\n'
13: foobar3
--- a/tests/test-obsolete-push.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-obsolete-push.t Tue Jul 25 05:52:14 2017 +0200
@@ -2,13 +2,12 @@
> [defaults]
> amend=-d "0 0"
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ template='{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n'
$ glog() {
- > hg glog --template "$template" "$@"
+ > hg log -G --template "$template" "$@"
> }
Test outgoing, common A is suspended, B unstable and C secret, remote
--- a/tests/test-obsolete.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-obsolete.t Tue Jul 25 05:52:14 2017 +0200
@@ -33,6 +33,7 @@
$ getid 3
0d3f46688ccc6e756c7e96cf64c391c411309597
$ hg debugobsolete 4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597
+ obsoleted 1 changesets
$ hg debugobsolete
4538525df7e2b9f09423636c61ef63a4cb872a2d 0d3f46688ccc6e756c7e96cf64c391c411309597 0 (*) {'user': 'test'} (glob)
@@ -96,6 +97,7 @@
$ mkcommit "obsol_c'" # 4 (on 1)
created new head
$ hg debugobsolete `getid 3` `getid 4`
+ obsoleted 1 changesets
$ qlog
4
- 725c380fe99b
@@ -126,6 +128,7 @@
parent: 1:7c3bad9141dc
user: test
date: Thu Jan 01 00:00:00 1970 +0000
+ obsolete: rewritten as 725c380fe99b
summary: add obsol_c
working directory parent is obsolete! (0d3f46688ccc)
@@ -209,6 +212,7 @@
created new head
1 new unstable changesets
$ hg debugobsolete `getid 5` `getid 6`
+ obsoleted 1 changesets
$ qlog
6
- 95de7fc6918d
@@ -237,6 +241,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ qlog -R ../other-new
5
- 95de7fc6918d
@@ -266,6 +271,7 @@
created new head
1 new unstable changesets
$ hg debugobsolete `getid 6` `getid 7`
+ obsoleted 1 changesets
$ hg pull -R ../other-new .
pulling from .
searching for changes
@@ -274,6 +280,7 @@
adding file changes
added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
1 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads, 'hg merge' to merge)
$ qlog -R ../other-new
6
@@ -354,6 +361,7 @@
created new head
1 new unstable changesets
$ hg debugobsolete `getid 7` `getid 8`
+ obsoleted 1 changesets
$ cd ../other-new
$ hg up -q 3
$ hg pull ../local/
@@ -364,6 +372,7 @@
adding file changes
added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
1 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg up -q 7 # to check rollback update behavior
@@ -437,6 +446,7 @@
- 1f0dee641bb7
$ hg debugobsolete `getid 9` #kill
+ obsoleted 1 changesets
$ hg up null -q # to be not based on 9 anymore
$ qlog
8
@@ -455,6 +465,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
+ updated to "159dfc9fa5d3: add obsol_d''"
1 other heads for branch "default"
$ hg id -n
8
@@ -539,10 +550,12 @@
adding file changes
added 2 changesets with 1 changes to [12] files (re)
3 new obsolescence markers
+ obsoleted 1 changesets
$ hg up -q 10
$ mkcommit "obsol_d'''"
created new head
$ hg debugobsolete `getid 11` `getid 12`
+ obsoleted 1 changesets
$ hg push ../other-new --traceback
pushing to ../other-new
searching for changes
@@ -551,6 +564,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ..
check bumped detection
@@ -739,12 +753,14 @@
| | | x changeset: 14:33d458d86621
| | | | user: test
| | | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | | obsolete: pruned
| | | | summary: temporary amend commit for 0b1b6dd009c0
| | | |
| | | x changeset: 13:0b1b6dd009c0
| | |/ parent: 10:2033b4e49474
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as 705ab2a6b72e
| | | summary: add f
| | |
| | | o changeset: 12:6db5e282cb91
@@ -769,30 +785,36 @@
| | parent: -1:000000000000
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: pruned
| | summary: add toto
| |
| | x changeset: 8:159dfc9fa5d3
| | | parent: 3:0d3f46688ccc
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as 9468a5f5d8b2
| | | summary: add obsol_d''
| | |
| | | x changeset: 7:909a0fb57e5d
| | |/ parent: 3:0d3f46688ccc
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as 159dfc9fa5d3
| | | summary: add obsol_d'
| | |
| | | x changeset: 6:95de7fc6918d
| | |/ parent: 3:0d3f46688ccc
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as 909a0fb57e5d
| | | summary: add obsol_d
| | |
| | | x changeset: 5:a7a6f2b5d8a5
| | |/ parent: 3:0d3f46688ccc
| | | user: test
| | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | | obsolete: rewritten as 95de7fc6918d
+ | | | obsolete: rewritten as 50f11e5e3a63
| | | summary: add d
| | |
| o | changeset: 4:725c380fe99b
@@ -805,11 +827,14 @@
| |/ parent: 1:7c3bad9141dc
| | user: test
| | date: Thu Jan 01 00:00:00 1970 +0000
+ | | obsolete: rewritten as 725c380fe99b
+ | | obsolete: rewritten as 2033b4e49474
| | summary: add obsol_c
| |
x | changeset: 2:4538525df7e2
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as 0d3f46688ccc
| summary: add c
|
o changeset: 1:7c3bad9141dc
--- a/tests/test-oldconvert.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-oldconvert.t Tue Jul 25 05:52:14 2017 +0200
@@ -7,7 +7,6 @@
> [alias]
> odiff=diff --rev 'limit(obsparents(.),1)' --rev .
> [extensions]
- > hgext.graphlog=
> EOF
$ mkcommit() {
> echo "$1" > "$1"
@@ -34,13 +33,13 @@
$ echo "obsolete=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/legacy.py" >> $HGRCPATH
- $ hg glog
+ $ hg log -G
abort: old format of obsolete marker detected!
run `hg debugconvertobsolete` once.
[255]
$ hg debugconvertobsolete --traceback
1 obsolete marker converted
- $ hg glog
+ $ hg log -G
@ changeset: 2:d67cd0334eee
| tag: tip
| parent: 0:1f0dee641bb7
@@ -101,7 +100,7 @@
> }
> ]
> EOF
- $ hg glog
+ $ hg log -G
abort: old format of obsolete marker detected!
run `hg debugconvertobsolete` once.
[255]
--- a/tests/test-prev-next.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-prev-next.t Tue Jul 25 05:52:14 2017 +0200
@@ -1,11 +1,11 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
hg prev -B should move active bookmark
- $ hg init
+ $ hg init test-repo
+ $ cd test-repo
$ touch a
$ hg add a
$ hg commit -m 'added a'
@@ -93,6 +93,15 @@
mark 2:4e26ef31f919
no-move 2:4e26ef31f919
+test prev on root
+
+ $ hg up null
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ $ hg prev
+ already at repository root
+ [1]
+ $ hg up 1
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
Behavior with local modification
--------------------------------
@@ -216,6 +225,8 @@
atop:[6] added b (3)
working directory is now at 47ea25be8aea
+ $ cd ..
+
prev and next should lock properly against other commands
$ hg init repo
--- a/tests/test-prune.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-prune.t Tue Jul 25 05:52:14 2017 +0200
@@ -86,7 +86,7 @@
cannot prune public changesets
$ hg prune 0
- abort: cannot prune immutable changeset: 1f0dee641bb7
+ abort: cannot touch public changesets: 1f0dee641bb7
(see 'hg help phases' for details)
[255]
$ hg debugobsolete
--- a/tests/test-push-checkheads-partial-C1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-partial-C1.t Tue Jul 25 05:52:14 2017 +0200
@@ -57,6 +57,7 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
--- a/tests/test-push-checkheads-partial-C2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-partial-C2.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,6 +59,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ f6082bc4ffef (draft): A1
|
--- a/tests/test-push-checkheads-partial-C3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-partial-C3.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,6 +59,7 @@
$ mkcommit C0
created new head
$ hg debugobsolete --record-parents `getid "desc(B0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 0f88766e02d6 (draft): C0
|
--- a/tests/test-push-checkheads-partial-C4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-partial-C4.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,6 +59,7 @@
$ mkcommit C0
created new head
$ hg debugobsolete --record-parents `getid "desc(A0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 0f88766e02d6 (draft): C0
|
--- a/tests/test-push-checkheads-pruned-B1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B1.t Tue Jul 25 05:52:14 2017 +0200
@@ -49,6 +49,7 @@
$ mkcommit B0
created new head
$ hg debugobsolete --record-parents `getid "desc(A0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 74ff5441d343 (draft): B0
|
@@ -68,5 +69,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B2.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,7 +59,9 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(B0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ f6082bc4ffef (draft): A1
|
@@ -81,5 +83,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B3.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,7 +59,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete --record-parents `getid "desc(A0)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
@@ -81,6 +83,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B4.t Tue Jul 25 05:52:14 2017 +0200
@@ -60,7 +60,9 @@
$ mkcommit C0
created new head
$ hg debugobsolete --record-parents `getid "desc(A0)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(B0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 0f88766e02d6 (draft): C0
|
@@ -82,5 +84,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B5.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B5.t Tue Jul 25 05:52:14 2017 +0200
@@ -63,8 +63,11 @@
$ mkcommit B1
created new head
$ hg debugobsolete --record-parents `getid "desc(A0)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)"` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(C0)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
@@ -88,5 +91,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
3 new obsolescence markers
+ obsoleted 3 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B6.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B6.t Tue Jul 25 05:52:14 2017 +0200
@@ -52,7 +52,9 @@
$ hg up 'desc(B0)'
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
x ba93660aff8d (draft): A1
|
@@ -74,5 +76,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B7.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B7.t Tue Jul 25 05:52:14 2017 +0200
@@ -51,7 +51,9 @@
$ hg up 'desc(B0)'
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
x ba93660aff8d (draft): A1
|
@@ -73,5 +75,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-pruned-B8.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-pruned-B8.t Tue Jul 25 05:52:14 2017 +0200
@@ -66,9 +66,13 @@
$ mkcommit A2
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(A1)" ` `getid "desc(A2)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ c1f8d089020f (draft): A2
|
@@ -94,5 +98,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
4 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A1.t Tue Jul 25 05:52:14 2017 +0200
@@ -46,6 +46,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ f6082bc4ffef (draft): A1
|
@@ -65,5 +66,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A2.t Tue Jul 25 05:52:14 2017 +0200
@@ -59,7 +59,9 @@
created new head
$ mkcommit B1
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 262c8c798096 (draft): B1
|
@@ -83,5 +85,6 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A3.t Tue Jul 25 05:52:14 2017 +0200
@@ -62,7 +62,9 @@
created new head
$ mkcommit A1
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ c1c7524e9488 (draft): A1
|
@@ -86,5 +88,6 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A4.t Tue Jul 25 05:52:14 2017 +0200
@@ -48,6 +48,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ mkcommit B0
$ hg log -G --hidden
@ f40ded968333 (draft): B0
@@ -70,5 +71,6 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../../
--- a/tests/test-push-checkheads-superceed-A5.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A5.t Tue Jul 25 05:52:14 2017 +0200
@@ -49,6 +49,7 @@
created new head
$ mkcommit A1
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ ba93660aff8d (draft): A1
|
@@ -70,6 +71,7 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A6.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A6.t Tue Jul 25 05:52:14 2017 +0200
@@ -68,7 +68,9 @@
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ mkcommit B1
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ d70a1f75a020 (draft): B1
|
@@ -94,5 +96,6 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A7.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A7.t Tue Jul 25 05:52:14 2017 +0200
@@ -68,7 +68,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
@@ -94,5 +96,6 @@
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
2 new obsolescence markers
+ obsoleted 2 changesets
$ cd ../..
--- a/tests/test-push-checkheads-superceed-A8.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-superceed-A8.t Tue Jul 25 05:52:14 2017 +0200
@@ -53,7 +53,9 @@
$ mkcommit A2
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(A1)" ` `getid "desc(A2)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ c1f8d089020f (draft): A2
|
@@ -75,5 +77,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-unpushed-D1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D1.t Tue Jul 25 05:52:14 2017 +0200
@@ -49,6 +49,7 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg up 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ mkcommit B0
--- a/tests/test-push-checkheads-unpushed-D2.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D2.t Tue Jul 25 05:52:14 2017 +0200
@@ -63,7 +63,9 @@
$ mkcommit A1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(B0)"`
+ obsoleted 1 changesets
$ hg up 0
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ mkcommit C0
--- a/tests/test-push-checkheads-unpushed-D3.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D3.t Tue Jul 25 05:52:14 2017 +0200
@@ -66,7 +66,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
--- a/tests/test-push-checkheads-unpushed-D4.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D4.t Tue Jul 25 05:52:14 2017 +0200
@@ -82,7 +82,9 @@
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
$ mkcommit B1
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ d70a1f75a020 (draft): B1
|
@@ -118,5 +120,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-unpushed-D5.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D5.t Tue Jul 25 05:52:14 2017 +0200
@@ -71,7 +71,9 @@
$ mkcommit B1
created new head
$ hg debugobsolete `getid "desc(A0)" ` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(B0)" ` `getid "desc(B1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 25c56d33e4c4 (draft): B1
|
@@ -103,5 +105,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files
1 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-push-checkheads-unpushed-D6.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D6.t Tue Jul 25 05:52:14 2017 +0200
@@ -56,7 +56,9 @@
$ mkcommit C0
created new head
$ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 0f88766e02d6 (draft): C0
|
--- a/tests/test-push-checkheads-unpushed-D7.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-push-checkheads-unpushed-D7.t Tue Jul 25 05:52:14 2017 +0200
@@ -65,8 +65,11 @@
$ mkcommit C0
created new head
$ hg debugobsolete `getid "desc(A0)"` `getid "desc(A1)"`
+ obsoleted 1 changesets
$ hg debugobsolete `getid "desc(A1)"` `getid "desc(A2)"`
+ obsoleted 1 changesets
$ hg debugobsolete --record-parents `getid "desc(A2)"`
+ obsoleted 1 changesets
$ hg log -G --hidden
@ 0f88766e02d6 (draft): C0
|
@@ -92,5 +95,6 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
3 new obsolescence markers
+ obsoleted 1 changesets
$ cd ../..
--- a/tests/test-sharing.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-sharing.t Tue Jul 25 05:52:14 2017 +0200
@@ -88,7 +88,9 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ updated to "60ffde5765c5: fix bug 37"
1 other heads for branch "default"
Figure SG03
@@ -120,6 +122,7 @@
$ cd ../test-repo
$ hg update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ updated to "de6151c48e1c: fix bug 37"
1 other heads for branch "default"
$ hg shortlog --hidden -G
@ 4:de6151c48e1c draft fix bug 37
@@ -144,7 +147,8 @@
Now that the fix is public, we cannot amend it any more.
$ hg amend -m 'fix bug 37'
- abort: cannot amend public changesets
+ abort: cannot amend public changesets: de6151c48e1c
+ (see 'hg help phases' for details)
[255]
Figure SG05
@@ -209,6 +213,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
updating bookmark bug15
$ hg -R ../review bookmarks
bug15 3:cbdfbd5a5db2
@@ -253,6 +258,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
updating bookmark featureX
Bob receives second review, amends, and pushes to public:
@@ -278,6 +284,7 @@
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
2 new obsolescence markers
+ obsoleted 1 changesets
updating bookmark featureX
$ hg -R ../review bookmarks
bug15 3:cbdfbd5a5db2
@@ -393,6 +400,7 @@
adding file changes
added 1 changesets with 0 changes to 1 files
1 new obsolescence markers
+ obsoleted 1 changesets
updating bookmark bug15
Figure SG08: review and public changesets after Alice pushes.
--- a/tests/test-split.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-split.t Tue Jul 25 05:52:14 2017 +0200
@@ -1,6 +1,8 @@
test of the split command
-----------------------
+ $ . $TESTDIR/testlib/common.sh
+
$ cat >> $HGRCPATH <<EOF
> [defaults]
> amend=-d "0 0"
@@ -18,9 +20,8 @@
> [ui]
> interactive = true
> [extensions]
- > hgext.graphlog=
+ > evolve =
> EOF
- $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
> echo "$1" > "$1"
> hg add "$1"
@@ -94,7 +95,7 @@
1334a80b33c3f9873edab728fbbcf500eab61d2e d2fe56e71366c2c5376c89960c281395062c0619 0 (*) {'ef1': '8', 'user': 'test'} (glob)
06be89dfe2ae447383f30a2984933352757b6fb4 0 {1334a80b33c3f9873edab728fbbcf500eab61d2e} (*) {'ef1': '0', 'user': 'test'} (glob)
d2fe56e71366c2c5376c89960c281395062c0619 2d8abdb827cdf71ca477ef6985d7ceb257c53c1b 033b3f5ae73db67c10de938fb6f26b949aaef172 0 (*) {'ef1': '13', 'user': 'test'} (glob)
- $ hg glog
+ $ hg log -G
@ changeset: 7:033b3f5ae73d
| tag: tip
| user: test
@@ -130,10 +131,21 @@
$ hg split
abort: uncommitted changes
[255]
+ $ hg up "desc(_c)" -C
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+Cannot split public changeset
+
+ $ hg phase --rev 'desc("_a")'
+ 0: draft
+ $ hg phase --rev 'desc("_a")' --public
+ $ hg split --rev 'desc("_a")'
+ abort: cannot split public changesets: 135f39f4bd78
+ (see 'hg help phases' for details)
+ [255]
+ $ hg phase --rev 'desc("_a")' --draft --force
Split a revision specified with -r
- $ hg up "desc(_c)" -C
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo "change to b" >> _b
$ hg amend -m "_cprim"
2 new unstable changesets
@@ -212,7 +224,7 @@
move:[11] split2
atop:[14] split1
working directory is now at d74c6715e706
- $ hg glog
+ $ hg log -G
@ changeset: 15:d74c6715e706
| tag: tip
| user: test
@@ -255,7 +267,7 @@
$ hg book
bookA 17:7a6b35779b85
* bookB 17:7a6b35779b85
- $ hg glog -r "14::"
+ $ hg log -G -r "14::"
@ changeset: 17:7a6b35779b85
| bookmark: bookA
| bookmark: bookB
@@ -270,7 +282,7 @@
~ date: Thu Jan 01 00:00:00 1970 +0000
summary: split1
- $ hg split <<EOF
+ $ hg split --user victor <<EOF
> y
> y
> n
@@ -296,18 +308,18 @@
created new head
Done splitting? [yN] y
- $ hg glog -r "14::"
- @ changeset: 19:60ea019b0f8d
+ $ hg log -G -r "14::"
+ @ changeset: 19:452a26648478
| bookmark: bookA
| bookmark: bookB
| tag: tip
- | user: test
+ | user: victor
| date: Thu Jan 01 00:00:00 1970 +0000
| summary: split6
|
- o changeset: 18:2c7a2e53f23b
+ o changeset: 18:1315679b77dc
| parent: 14:3f134f739075
- | user: test
+ | user: victor
| date: Thu Jan 01 00:00:00 1970 +0000
| summary: split5
|
@@ -317,8 +329,8 @@
summary: split1
$ hg book
- bookA 19:60ea019b0f8d
- * bookB 19:60ea019b0f8d
+ bookA 19:452a26648478
+ * bookB 19:452a26648478
Lastest revision is selected if multiple are given to -r
$ hg split -r "desc(_a)::"
@@ -337,7 +349,8 @@
> evolutioncommands=split
> EOF
$ hg split -r "desc(split3)"
- abort: cannot split commit: ead2066d1dbf not a head
+ abort: split will orphan 4 descendants
+ (see 'hg help evolution.instability')
[255]
Changing evolution level to createmarkers
@@ -399,9 +412,18 @@
$ echo babar > babar
$ echo celeste > celeste
$ hg add babar celeste
- $ hg commit -m "Works on mytopic" babar celeste
+ $ hg commit -m "Works on mytopic" babar celeste --user victor
+ $ hg log -r .
+ changeset: 21:26f72cfaf036
+ branch: new-branch
+ tag: tip
+ topic: mytopic
+ user: victor
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: Works on mytopic
+
$ hg summary
- parent: 21:615c369f47f0 tip
+ parent: 21:26f72cfaf036 tip
Works on mytopic
branch: new-branch
commit: 2 unknown (clean)
@@ -411,7 +433,7 @@
Split it
- $ hg split << EOF
+ $ hg split -U << EOF
> Y
> Y
> N
@@ -448,15 +470,15 @@
Check that the topic is still here
$ hg log -r "tip~1::"
- changeset: 22:f879ab83f991
+ changeset: 22:addcf498f19e
branch: new-branch
topic: mytopic
- parent: 20:89e64a2c68b3
+ parent: 20:fdb403258632
user: test
date: Thu Jan 01 00:00:00 1970 +0000
summary: split7
- changeset: 23:db75dbc1a3a6
+ changeset: 23:2532b288af61
branch: new-branch
tag: tip
topic: mytopic
--- a/tests/test-stabilize-conflict.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-stabilize-conflict.t Tue Jul 25 05:52:14 2017 +0200
@@ -152,6 +152,7 @@
|/ parent: 0:29ec1554cfaf
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as e04690b09bc6
| summary: babar count up to ten
|
o changeset: 0:29ec1554cfaf
@@ -243,6 +244,7 @@
|/ parent: 0:29ec1554cfaf
| user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as b20d08eea373
| summary: babar count up to ten
|
o changeset: 0:29ec1554cfaf
--- a/tests/test-stabilize-order.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-stabilize-order.t Tue Jul 25 05:52:14 2017 +0200
@@ -2,12 +2,11 @@
> [defaults]
> amend=-d "0 0"
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ glog() {
- > hg glog --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
+ > hg log -G --template '{rev}:{node|short}@{branch}({phase}) {desc|firstline}\n' "$@"
> }
$ hg init repo
@@ -221,6 +220,7 @@
| x changeset: 12:2256dae6521f
|/ user: test
| date: Thu Jan 01 00:00:00 1970 +0000
+ | obsolete: rewritten as f83a0bce03e4
| summary: addc
|
o changeset: 11:7a68bc4596ea
--- a/tests/test-stabilize-result.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-stabilize-result.t Tue Jul 25 05:52:14 2017 +0200
@@ -3,12 +3,11 @@
> amend=-d "0 0"
> [extensions]
> hgext.rebase=
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ glog() {
- > hg glog --template \
+ > hg log -G --template \
> '{rev}:{node|short}@{branch}({phase}) bk:[{bookmarks}] {desc|firstline}\n' "$@"
> }
--- a/tests/test-stack-branch.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-stack-branch.t Tue Jul 25 05:52:14 2017 +0200
@@ -75,7 +75,14 @@
b3: c_e
b2: c_d
b1: c_c
- ^ c_b
+ b0^ c_b (base)
+ $ hg stack -v
+ ### branch: foo
+ b4(913c298d8b0a)@ c_f (current)
+ b3(4f2a69f6d380): c_e
+ b2(f61adbacd17a): c_d
+ b1(3e9313bc4b71): c_c
+ b0(4a04f1104a27)^ c_b (base)
Test "t#" reference
-------------------
@@ -123,7 +130,7 @@
b3$ c_e (unstable)
b2@ c_d (current)
b1: c_c
- ^ c_b
+ b0^ c_b (base)
$ hg up b3
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg stack
@@ -132,7 +139,7 @@
b3$ c_e (current unstable)
b2: c_d
b1: c_c
- ^ c_b
+ b0^ c_b (base)
$ hg up b2
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -206,7 +213,7 @@
b3: c_g
b2: c_d
b1: c_c
- ^ c_b
+ b0^ c_b (base)
Case with multiple heads on the topic with unstability involved
---------------------------------------------------------------
@@ -249,7 +256,7 @@
b3: c_g
b2@ c_D (current)
b1: c_c
- ^ c_b
+ b0^ c_b (base)
Check that stack doesn't show draft changesets on a branch
----------------------------------------------------------
@@ -263,7 +270,7 @@
b3: c_g
b2@ c_D (current)
b1: c_c
- ^ c_b
+ b0^ c_b (base)
$ hg phase --public b1
$ hg stack
### branch: foo (2 heads)
@@ -273,7 +280,7 @@
b3: c_h
b2: c_g
b1@ c_D (current)
- ^ c_c
+ b0^ c_c (base)
Check that stack doesn't show changeset with a topic
----------------------------------------------------
@@ -285,4 +292,4 @@
b3: c_h
b2: c_g
b1@ c_D (current)
- ^ c_c
+ b0^ c_c (base)
--- a/tests/test-topic-fold.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic-fold.t Tue Jul 25 05:52:14 2017 +0200
@@ -18,7 +18,6 @@
> [ui]
> interactive = true
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "topic=$(echo $(dirname $TESTDIR))/hgext3rd/topic/" >> $HGRCPATH
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
@@ -54,7 +53,7 @@
### topic: myfeature
### branch: default
t1@ folded (current)
- ^ add ROOT
+ t0^ add ROOT (base)
$ logtopic
@ 3:4fd43e5bdc443dc8489edffac19bd8f93ccf1a5c
| topics: myfeature
--- a/tests/test-topic-rebase.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic-rebase.t Tue Jul 25 05:52:14 2017 +0200
@@ -18,7 +18,6 @@
> [ui]
> interactive = true
> [extensions]
- > hgext.graphlog=
> rebase=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
@@ -46,7 +45,7 @@
### topic: myfeature
### branch: default
t1@ add feature1 (current)
- ^ add ROOT
+ t0^ add ROOT (base)
$ logtopic
@ 1:39e7a938055e87615edf675c24a10997ff05bb06
| topics: myfeature
@@ -76,7 +75,7 @@
### topic: myfeature
### branch: default
t1@ add feature1 (current)
- ^ add default
+ t0^ add default (base)
$ logtopic
@ 3:fc6593661cf3256ba165cbccd6019ead17cc3726
| topics: myfeature
@@ -90,7 +89,7 @@
### topic: myfeature
### branch: default
t1@ add feature1 (current)
- ^ add default
+ t0^ add default (base)
Check that rebase keep the topic in case of merge conflict
----------------------------------------------------------
@@ -152,11 +151,11 @@
### topic: myotherfeature
### branch: default
t1@ myotherfeature1 (current)
- ^ default3
+ t0^ default3 (base)
$ hg update --rev 7
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg stack
### topic: myotherfeature
### branch: default
t1@ myotherfeature1 (current)
- ^ default3
+ t0^ default3 (base)
--- a/tests/test-topic-stack-data.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic-stack-data.t Tue Jul 25 05:52:14 2017 +0200
@@ -248,23 +248,33 @@
t3: bar1_d
t2: add bar_b
t1: add bar_a
- ^ add base_e
+ t0^ add base_e (base)
+ $ hg stack bar -v
+ ### topic: bar (2 heads)
+ ### branch: default
+ t5(9cbadf11b44d): add bar_c
+ t2(e555c7e8c767)^ add bar_b (base)
+ t4(a920412b5a05)$ add bar_e (unstable)
+ t3(6915989374b1): bar1_d
+ t2(e555c7e8c767): add bar_b
+ t1(a5c2b4e00bbf): add bar_a
+ t0(92f489a6251f)^ add base_e (base)
$ hg stack baz
### topic: baz
### branch: default, 2 behind
t2: add baz_b
t1: add baz_a
- ^ add base_c
+ t0^ add base_c (base)
$ hg stack foo
### topic: foo
### branch: lake, ambigious rebase destination
t2@ add foo_b (current)
t1: add foo_a
- ^ add lake_a
+ t0^ add lake_a (base)
$ hg stack fuz
### topic: fuz
### branch: default, 1 behind
t3$ add fuz_c (unstable)
t2$ add fuz_b (unstable)
t1: fuz1_a
- ^ add base_d
+ t0^ add base_d (base)
--- a/tests/test-topic-stack.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic-stack.t Tue Jul 25 05:52:14 2017 +0200
@@ -76,7 +76,15 @@
t3: c_e
t2: c_d
t1: c_c
- ^ c_b
+ t0^ c_b (base)
+ $ hg stack -v
+ ### topic: foo
+ ### branch: default
+ t4(6559e6d93aea)@ c_f (current)
+ t3(0f9ac936c87d): c_e
+ t2(e629654d7050): c_d
+ t1(8522f9e3fee9): c_c
+ t0(ea705abc4f51)^ c_b (base)
$ hg stack -Tjson | python -m json.tool
[
{
@@ -118,6 +126,60 @@
{
"isentry": false,
"topic.stack.desc": "c_b",
+ "topic.stack.index": 0,
+ "topic.stack.state": [
+ "base"
+ ],
+ "topic.stack.state.symbol": "^"
+ }
+ ]
+ $ hg stack -v -Tjson | python -m json.tool
+ [
+ {
+ "isentry": true,
+ "topic.stack.desc": "c_f",
+ "topic.stack.index": 4,
+ "topic.stack.shortnode": "6559e6d93aea",
+ "topic.stack.state": [
+ "current"
+ ],
+ "topic.stack.state.symbol": "@"
+ },
+ {
+ "isentry": true,
+ "topic.stack.desc": "c_e",
+ "topic.stack.index": 3,
+ "topic.stack.shortnode": "0f9ac936c87d",
+ "topic.stack.state": [
+ "clean"
+ ],
+ "topic.stack.state.symbol": ":"
+ },
+ {
+ "isentry": true,
+ "topic.stack.desc": "c_d",
+ "topic.stack.index": 2,
+ "topic.stack.shortnode": "e629654d7050",
+ "topic.stack.state": [
+ "clean"
+ ],
+ "topic.stack.state.symbol": ":"
+ },
+ {
+ "isentry": true,
+ "topic.stack.desc": "c_c",
+ "topic.stack.index": 1,
+ "topic.stack.shortnode": "8522f9e3fee9",
+ "topic.stack.state": [
+ "clean"
+ ],
+ "topic.stack.state.symbol": ":"
+ },
+ {
+ "isentry": false,
+ "topic.stack.desc": "c_b",
+ "topic.stack.index": 0,
+ "topic.stack.shortnode": "ea705abc4f51",
"topic.stack.state": [
"base"
],
@@ -180,7 +242,7 @@
t3$ c_e (unstable)
t2@ c_d (current)
t1: c_c
- ^ c_b
+ t0^ c_b (base)
$ hg up t3
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg topic --list
@@ -190,7 +252,7 @@
t3$ c_e (current unstable)
t2: c_d
t1: c_c
- ^ c_b
+ t0^ c_b (base)
$ hg topic --list --color=debug
[topic.stack.summary.topic|### topic: [topic.active|foo]]
[topic.stack.summary.branches|### branch: default]
@@ -198,7 +260,7 @@
[topic.stack.index topic.stack.index.current topic.stack.index.unstable|t3][topic.stack.state topic.stack.state.current topic.stack.state.unstable|$] [topic.stack.desc topic.stack.desc.current topic.stack.desc.unstable|c_e][topic.stack.state topic.stack.state.current topic.stack.state.unstable| (current unstable)]
[topic.stack.index topic.stack.index.clean|t2][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_d]
[topic.stack.index topic.stack.index.clean|t1][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_c]
- [topic.stack.state topic.stack.state.base|^] [topic.stack.desc topic.stack.desc.base|c_b]
+ [topic.stack.index topic.stack.index.base|t0][topic.stack.state topic.stack.state.base|^] [topic.stack.desc topic.stack.desc.base|c_b][topic.stack.state topic.stack.state.base| (base)]
$ hg up t2
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
@@ -281,7 +343,7 @@
t3: c_g
t2: c_d
t1: c_c
- ^ c_b
+ t0^ c_b (base)
Case with multiple heads on the topic with unstability involved
---------------------------------------------------------------
@@ -325,7 +387,7 @@
t3: c_g
t2@ c_D (current)
t1: c_c
- ^ c_b
+ t0^ c_b (base)
Trying to list non existing topic
$ hg stack thisdoesnotexist
--- a/tests/test-topic-tutorial.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic-tutorial.t Tue Jul 25 05:52:14 2017 +0200
@@ -126,7 +126,7 @@
### branch: default
t2@ adding fruits (current)
t1: adding condiments
- ^ Shopping list
+ t0^ Shopping list (base)
The topic deactivates when we update away from it::
@@ -361,7 +361,7 @@
### branch: default
t2@ Adding orange juice (current)
t1: Adding apple juice
- ^ adding fruits
+ t0^ adding fruits (base)
$ hg up tools
switching to topic tools
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -371,7 +371,7 @@
t3@ Adding drill (current)
t2: Adding saw
t1: Adding hammer
- ^ adding fruits
+ t0^ adding fruits (base)
They are seen as independent branches by Mercurial. No rebase or merge
between them will be attempted by default::
@@ -479,5 +479,5 @@
t3@ Adding drill (current)
t2: Adding saw
t1: Adding hammer
- ^ add a pair of shoes
+ t0^ add a pair of shoes (base)
--- a/tests/test-topic.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-topic.t Tue Jul 25 05:52:14 2017 +0200
@@ -15,7 +15,28 @@
$ hg help topics
hg topics [TOPIC]
- View current topic, set current topic, or see all topics.
+ View current topic, set current topic, change topic for a set of revisions, or
+ see all topics.
+
+ Clear topic on existing topiced revisions:
+ 'hg topic --rev <related revset> --clear'
+
+ Change topic on some revisions:
+ 'hg topic <newtopicname> --rev <related revset>'
+
+ Clear current topic:
+ 'hg topic --clear'
+
+ Set current topic:
+ 'hg topic <topicname>'
+
+ List of topics:
+ 'hg topics'
+
+ List of topics with their last touched time sorted according to it:
+ 'hg topic --age'
+
+ The active topic (if any) will be prepended with a "*".
The --verbose version of this command display various information on the
state of each topic.
@@ -25,6 +46,7 @@
--clear clear active topic if any
-r --rev REV revset of existing revisions
-l --list show the stack of changeset in the topic
+ --age show when you last touched the topics
(some details hidden, use --verbose to show complete help)
$ hg topics
@@ -777,3 +799,115 @@
| date: Thu Jan 01 00:00:00 1970 +0000
| summary: start on fran
|
+
+Testing for updating to t0
+==========================
+
+ $ hg stack
+ ### topic: changewut (2 heads)
+ ### branch: default, 5 behind
+ t3: fran?
+ t1^ start on fran (base)
+ t2@ gamma (current)
+ t1: start on fran
+ t0^ Add file delta (base)
+ $ hg up t0
+ preserving the current topic 'changewut'
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg topic
+ * changewut
+ $ hg stack
+ ### topic: changewut (2 heads)
+ ### branch: default, 5 behind
+ t3: fran?
+ t1^ start on fran (base)
+ t2: gamma
+ t1: start on fran
+ t0^ Add file delta (base)
+
+ $ hg topics --age
+ * changewut (1970-01-01)
+
+ $ cd ..
+
+Testing the new config knob to forbid untopiced commit
+======================================================
+
+ $ hg init ponky
+ $ cd ponky
+ $ cat <<EOF >> .hg/hgrc
+ > [phases]
+ > publish=false
+ > EOF
+ $ cat <<EOF >> $HGRCPATH
+ > [experimental]
+ > enforce-topic = yes
+ > EOF
+ $ touch a b c d
+ $ hg add a
+ $ hg ci -m "Added a"
+ abort: no active topic
+ (set a current topic or use '--config experimental.enforce-topic=no' to commit without a topic)
+ [255]
+
+(same test, checking we abort before the editor)
+
+ $ EDITOR=cat hg ci -m "Added a" --edit
+ abort: no active topic
+ (set a current topic or use '--config experimental.enforce-topic=no' to commit without a topic)
+ [255]
+ $ hg ci -m "added a" --config experimental.enforce-topic=no
+ $ hg log
+ changeset: 0:a154386e50d1
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: added a
+
+ $ hg topic topic1970 --rev 0
+ switching to topic topic1970
+ changed topic on 1 changes
+ $ hg add b
+ $ hg topic topic1990
+ $ hg ci -m "Added b" --config devel.default-date="631152000 0"
+ $ hg add c
+ $ hg topic topic2010
+ $ hg ci -m "Added c" --config devel.default-date="1262304000 0"
+ $ hg log
+ changeset: 3:9048b194797d
+ tag: tip
+ topic: topic2010
+ user: test
+ date: Fri Jan 01 00:00:00 2010 +0000
+ summary: Added c
+
+ changeset: 2:186d493c7f8d
+ topic: topic1990
+ user: test
+ date: Mon Jan 01 00:00:00 1990 +0000
+ summary: Added b
+
+ changeset: 1:e5a30a141954
+ topic: topic1970
+ parent: -1:000000000000
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: added a
+
+ $ hg topics
+ topic1970
+ topic1990
+ * topic2010
+ $ hg topics --age
+ * topic2010 (2010-01-01)
+ topic1990 (1990-01-01)
+ topic1970 (1970-01-01)
+ $ hg up topic1970
+ switching to topic topic1970
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ $ hg topics --age
+ topic2010 (2010-01-01)
+ topic1990 (1990-01-01)
+ * topic1970 (1970-01-01)
+
+ $ cd ..
--- a/tests/test-tutorial.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-tutorial.t Tue Jul 25 05:52:14 2017 +0200
@@ -461,6 +461,12 @@
-r --rev VALUE revert commit content to REV instead
-I --include PATTERN [+] include names matching the given patterns
-X --exclude PATTERN [+] exclude names matching the given patterns
+ -m --message TEXT use text as commit message
+ -l --logfile FILE read commit message from file
+ -d --date DATE record the specified date as commit date
+ -u --user USER record the specified user as committer
+ -D --current-date record the current date as commit date
+ -U --current-user record the current user as committer
(some details hidden, use --verbose to show complete help)
@@ -496,6 +502,8 @@
-l --logfile FILE read commit message from file
-d --date DATE record the specified date as commit date
-u --user USER record the specified user as committer
+ -D --current-date record the current date as commit date
+ -U --current-user record the current user as committer
(some details hidden, use --verbose to show complete help)
@@ -733,6 +741,7 @@
adding file changes
added 2 changesets with 2 changes to 1 files (+1 heads)
3 new obsolescence markers
+ obsoleted 2 changesets
remote get a warning that current working directory is based on an obsolete changeset
--- a/tests/test-uncommit.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-uncommit.t Tue Jul 25 05:52:14 2017 +0200
@@ -1,11 +1,10 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ glog() {
- > hg glog --template '{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n' "$@"
+ > hg log -G --template '{rev}:{node|short}@{branch}({separate("/", obsolete, phase)}) {desc|firstline}\n' "$@"
> }
$ hg init repo
@@ -14,7 +13,8 @@
Cannot uncommit null changeset
$ hg uncommit
- abort: cannot rewrite immutable changeset
+ abort: cannot uncommit the null revision
+ (no changeset checked out)
[255]
Cannot uncommit public changeset
@@ -23,7 +23,8 @@
$ hg ci -Am adda a
$ hg phase --public .
$ hg uncommit
- abort: cannot rewrite immutable changeset
+ abort: cannot uncommit public changesets: 07f494440405
+ (see 'hg help phases' for details)
[255]
$ hg phase --force --draft .
@@ -358,7 +359,103 @@
Test uncommiting precursors
- $ hg uncommit --hidden --rev 'precursors(.)' b
+ $ hg uncommit --hidden --rev 'precursors(.)' b --traceback
$ hg cat b --rev .
b
b
+
+Test date, message and user update
+
+ $ hg log -r .
+ changeset: 12:912ed871207c
+ branch: bar
+ tag: tip
+ parent: 7:4f1c269eab68
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: touncommit
+
+ $ hg uncommit -m 'to-uncommit' d --user test2 --date '1337 0'
+ $ hg log -r .
+ changeset: 13:f1efd9ec508c
+ branch: bar
+ tag: tip
+ parent: 7:4f1c269eab68
+ user: test2
+ date: Thu Jan 01 00:22:17 1970 +0000
+ summary: to-uncommit
+
+
+test -U option
+
+ $ hg uncommit -U b
+ $ hg log -r .
+ changeset: 14:288da4a95941
+ branch: bar
+ tag: tip
+ parent: 7:4f1c269eab68
+ user: test
+ date: Thu Jan 01 00:22:17 1970 +0000
+ summary: to-uncommit
+
+
+test the `hg amend --extract` entry point
+
+ $ hg status --change .
+ M j
+ M o
+ A e
+ A ff
+ A h
+ A k
+ A l
+ R c
+ R f
+ R g
+ R m
+ R n
+ $ hg status
+ M d
+ A aa
+ R b
+ $ hg amend --extract j
+ $ hg status --change .
+ M o
+ A e
+ A ff
+ A h
+ A k
+ A l
+ R c
+ R f
+ R g
+ R m
+ R n
+ $ hg status
+ M d
+ M j
+ A aa
+ R b
+
+(with all)
+
+ $ hg amend --extract --all
+ new changeset is empty
+ (use 'hg prune .' to remove it)
+ $ hg status --change .
+ $ hg status
+ M d
+ M j
+ M o
+ A aa
+ A e
+ A ff
+ A h
+ A k
+ A l
+ R b
+ R c
+ R f
+ R g
+ R m
+ R n
--- a/tests/test-unstable.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-unstable.t Tue Jul 25 05:52:14 2017 +0200
@@ -13,7 +13,6 @@
> [ui]
> logtemplate = {rev}:{node|short}@{branch}({phase}) {desc|firstline}\n
> [extensions]
- > hgext.graphlog=
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
--- a/tests/test-userguide.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-userguide.t Tue Jul 25 05:52:14 2017 +0200
@@ -18,7 +18,7 @@
example 2: unsafe amend with plain vanilla Mercurial: the original
commit is stripped
$ hg commit --amend -u alice -d '1 0' -m 'implement feature Y'
- saved backup bundle to $TESTTMP/t/.hg/strip-backup/6e725fd2be6f-42cc74d4-amend-backup.hg (glob)
+ saved backup bundle to $TESTTMP/t/.hg/strip-backup/6e725fd2be6f-42cc74d4-amend.hg (glob)
$ hg log -r 23fe4ac6d3f1
abort: unknown revision '23fe4ac6d3f1'!
[255]
--- a/tests/test-wireproto-bundle1.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-wireproto-bundle1.t Tue Jul 25 05:52:14 2017 +0200
@@ -70,6 +70,7 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 2 new obsolescence markers
+ remote: obsoleted 1 changesets
$ hg push
pushing to ssh://user@dummy/server
searching for changes
@@ -87,6 +88,7 @@
adding file changes
added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
2 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads)
$ hg -R ../other pull
pulling from ssh://user@dummy/server
--- a/tests/test-wireproto.t Sun Jul 09 15:01:32 2017 +0300
+++ b/tests/test-wireproto.t Tue Jul 25 05:52:14 2017 +0200
@@ -74,6 +74,7 @@
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: obsmarker-exchange: 151 bytes received
remote: 2 new obsolescence markers
+ remote: obsoleted 1 changesets
$ hg push
pushing to ssh://user@dummy/server
searching for changes
@@ -92,6 +93,7 @@
added 1 changesets with 1 changes to [12] files \(\+1 heads\) (re)
obsmarker-exchange: 151 bytes received
2 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads)
$ hg -R ../other pull
pulling from ssh://user@dummy/server
@@ -136,8 +138,9 @@
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 0 changes to 1 files (+1 heads)
- remote: obsmarker-exchange: 227 bytes received
+ remote: obsmarker-exchange: 226 bytes received
remote: 1 new obsolescence markers
+ remote: obsoleted 1 changesets
$ hg -R ../other pull
pulling from ssh://user@dummy/server
searching for changes
@@ -145,8 +148,9 @@
adding manifests
adding file changes
added 1 changesets with 0 changes to 1 files (+1 heads)
- obsmarker-exchange: 227 bytes received
+ obsmarker-exchange: 226 bytes received
1 new obsolescence markers
+ obsoleted 1 changesets
(run 'hg heads' to see heads)
test discovery avoid exchanging known markers
@@ -169,7 +173,7 @@
(skipping discovery of obsolescence markers, will exchange everything)
(controled by 'experimental.evolution.obsdiscovery' configuration)
no changes found
- remote: obsmarker-exchange: 377 bytes received
+ remote: obsmarker-exchange: 376 bytes received
[1]
$ hg -R ../other pull --config experimental.evolution.obsdiscovery=no
pulling from ssh://user@dummy/server
@@ -177,6 +181,6 @@
no changes found
(skipping discovery of obsolescence markers, will exchange everything)
(controled by 'experimental.evolution.obsdiscovery' configuration)
- obsmarker-exchange: 377 bytes received
+ obsmarker-exchange: 376 bytes received
$ cd ..