Mercurial > evolve
changeset 4784:ecf0f3bc7468 mercurial-4.6
test-compat: merge mercurial-4.7 into mercurial-4.6
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Mon, 29 Jul 2019 14:43:17 +0200 |
parents | 5d50f3de4714 (diff) c6fc1000af1e (current diff) |
children | f7bf347a17bb 769b907e644e |
files | tests/test-discovery-obshashrange.t tests/test-evolve-content-divergent-basic.t tests/test-evolve-content-divergent-corner-cases.t tests/test-evolve-content-divergent-interrupted.t tests/test-evolve-content-divergent-relocation.t tests/test-evolve-obshistory-lots-of-splits.t tests/test-evolve-obshistory-split.t tests/test-evolve-phase-divergence.t tests/test-evolve-public-content-divergent-corner-cases.t tests/test-evolve-public-content-divergent-main.t tests/test-evolve-templates.t tests/test-evolve-topic.t tests/test-evolve.t tests/test-topic-stack-complex.t tests/test-topic.t tests/test-touch.t |
diffstat | 66 files changed, 875 insertions(+), 425 deletions(-) [+] |
line wrap: on
line diff
--- a/CHANGELOG Mon Jul 29 11:40:22 2019 +0200 +++ b/CHANGELOG Mon Jul 29 14:43:17 2019 +0200 @@ -1,6 +1,18 @@ Changelog ========= +9.1.0 - in progress +------------------- + + * evolve: use the same wording as core in case of unresolved conflict + * evolve: minor output message improvements + * evolve: improve `hg evolve --all` behavior when "." is obsolete + * topic: fix confusion in branch heads checking logic + * touch: now works on merge commit too + * rewind: fix behavior for merge commit + * fold: allow fold with merge commit + * metaedit: now also operates on merge commit + 9.0.1 - in progress -------------------
--- a/hgext3rd/evolve/__init__.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/__init__.py Mon Jul 29 14:43:17 2019 +0200 @@ -278,6 +278,7 @@ lock as lockmod, node, patch, + pycompat, revset, scmutil, ) @@ -298,7 +299,6 @@ obshashtree, obshistory, rewind, - rewriteutil, safeguard, templatekw, utility, @@ -329,10 +329,7 @@ _pack = struct.pack _unpack = struct.unpack -aliases, entry = cmdutil.findcmd('commit', commands.table) -commitopts3 = cmdrewrite.commitopts3 -interactiveopt = cmdrewrite.interactiveopt -rewrite = rewriteutil.rewrite +aliases, entry = cmdutil.findcmd(b'commit', commands.table) # This extension contains the following code # @@ -403,7 +400,7 @@ repo.ui.setconfig('experimental', 'evolution', evolveopts, 'evolve') if obsolete.isenabled(repo, 'exchange'): # if no config explicitly set, disable bundle1 - if not isinstance(repo.ui.config('server', 'bundle1'), str): + if not isinstance(repo.ui.config('server', 'bundle1'), bytes): repo.ui.setconfig('server', 'bundle1', False) class trdescrepo(repo.__class__): @@ -433,8 +430,9 @@ if not matchingevolvecommands: raise error.Abort(_('unknown command: %s') % cmd) elif len(matchingevolvecommands) > 1: - msg = _('ambiguous command specification: "%s" matches %r') - raise error.Abort(msg % (cmd, matchingevolvecommands)) + matchstr = ', '.join(matchingevolvecommands) + msg = _("ambiguous command specification: '%s' matches [%s]") + raise error.Abort(msg % (cmd, matchstr)) else: whitelist.add(matchingevolvecommands[0]) for disabledcmd in set(cmdtable) - whitelist: @@ -467,7 +465,7 @@ _alias, statuscmd = cmdutil.findcmd('status', commands.table) pstatusopts = [o for o in statuscmd[1] if o[1] != 'rev'] - @eh.command('pstatus', pstatusopts) + @eh.command(b'pstatus', pstatusopts) def pstatus(ui, repo, *args, **kwargs): """show status combining committed and uncommited changes @@ -482,7 +480,7 @@ _alias, diffcmd = cmdutil.findcmd('diff', commands.table) pdiffopts = [o for o in diffcmd[1] if o[1] != 'rev'] - @eh.command('pdiff', pdiffopts) + @eh.command(b'pdiff', pdiffopts) def pdiff(ui, repo, *args, **kwargs): """show diff combining committed and uncommited changes @@ -503,7 +501,7 @@ ### Unstable revset symbol -@eh.revsetpredicate('unstable()') +@eh.revsetpredicate(b'unstable()') def revsetunstable(repo, subset, x): """Changesets with instabilities. """ @@ -516,7 +514,7 @@ troubled.sort() # set is non-ordered, enforce order return subset & troubled -@eh.revsetpredicate('troubled()') # legacy name +@eh.revsetpredicate(b'troubled()') # legacy name def revsettroubled(repo, subset, x): return revsetunstable(repo, subset, x) @@ -615,7 +613,7 @@ ### XXX I'm not sure this revset is useful -@eh.revsetpredicate('suspended()') +@eh.revsetpredicate(b'suspended()') def revsetsuspended(repo, subset, x): """Obsolete changesets with non-obsolete descendants. """ @@ -625,7 +623,7 @@ return subset & suspended -@eh.revsetpredicate('predecessors(set)') +@eh.revsetpredicate(b'predecessors(set)') def revsetpredecessors(repo, subset, x): """Immediate predecessors of changesets in set. """ @@ -635,12 +633,12 @@ return subset & s -@eh.revsetpredicate('precursors(set)') # legacy name for predecessors +@eh.revsetpredicate(b'precursors(set)') # legacy name for predecessors def revsetprecursors(repo, subset, x): return revsetpredecessors(repo, subset, x) -@eh.revsetpredicate('allpredecessors(set)') +@eh.revsetpredicate(b'allpredecessors(set)') def revsetallpredecessors(repo, subset, x): """Transitive predecessors of changesets in set. """ @@ -650,12 +648,12 @@ return subset & s -@eh.revsetpredicate('allprecursors(set)') # legacy name for allpredecessors +@eh.revsetpredicate(b'allprecursors(set)') # legacy name for allpredecessors def revsetallprecursors(repo, subset, x): return revsetallpredecessors(repo, subset, x) -@eh.revsetpredicate('successors(set)') +@eh.revsetpredicate(b'successors(set)') def revsetsuccessors(repo, subset, x): """Immediate successors of changesets in set. """ @@ -664,7 +662,7 @@ s.sort() return subset & s -@eh.revsetpredicate('allsuccessors(set)') +@eh.revsetpredicate(b'allsuccessors(set)') def revsetallsuccessors(repo, subset, x): """Transitive successors of changesets in set. """ @@ -890,7 +888,7 @@ ui = args[0] ui.warn(deprecationwarning) util.checksignature(fn)(*args, **kwargs) - newfn.__doc__ = deprecationwarning + ' (DEPRECATED)' + newfn.__doc__ = pycompat.sysstr(deprecationwarning + ' (DEPRECATED)') cmdwrapper = eh.command(oldalias, opts, synopsis) cmdwrapper(newfn) @@ -983,14 +981,14 @@ return target, bookmark @eh.command( - 'previous', - [('B', 'move-bookmark', False, - _('move active bookmark after update')), - ('m', 'merge', False, _('bring uncommitted change along')), - ('', 'no-topic', False, _('ignore topic and move topologically')), - ('n', 'dry-run', False, - _('do not perform actions, just print what would be done'))], - '[OPTION]...', + b'previous', + [(b'B', b'move-bookmark', False, + _(b'move active bookmark after update')), + (b'm', b'merge', False, _(b'bring uncommitted change along')), + (b'', b'no-topic', False, _(b'ignore topic and move topologically')), + (b'n', b'dry-run', False, + _(b'do not perform actions, just print what would be done'))], + b'[OPTION]...', helpbasic=True) def cmdprevious(ui, repo, **opts): """update to parent revision @@ -1041,15 +1039,15 @@ lockmod.release(wlock) @eh.command( - 'next', - [('B', 'move-bookmark', False, - _('move active bookmark after update')), - ('m', 'merge', False, _('bring uncommitted change along')), - ('', 'evolve', True, _('evolve the next changeset if necessary')), - ('', 'no-topic', False, _('ignore topic and move topologically')), - ('n', 'dry-run', False, - _('do not perform actions, just print what would be done'))], - '[OPTION]...', + b'next', + [(b'B', b'move-bookmark', False, + _(b'move active bookmark after update')), + (b'm', b'merge', False, _(b'bring uncommitted change along')), + (b'', b'evolve', True, _(b'evolve the next changeset if necessary')), + (b'', b'no-topic', False, _(b'ignore topic and move topologically')), + (b'n', b'dry-run', False, + _(b'do not perform actions, just print what would be done'))], + b'[OPTION]...', helpbasic=True) def cmdnext(ui, repo, **opts): """update to next child revision @@ -1175,18 +1173,18 @@ # making sure a next commit is formed if result[0] and result[1]: ui.status(_('working directory is now at %s\n') - % ui.label(str(repo['.']), 'evolve.node')) + % ui.label(bytes(repo['.']), 'evolve.node')) return 0 -def _updatetonext(ui, repo, children, displayer, opts): +def _updatetonext(ui, repo, child, displayer, opts): """ logic for `hg next` command to update to children and move bookmarks if required """ bm = repo._activebookmark shouldmove = opts.get('move_bookmark') and bm is not None if opts.get('dry_run'): - ui.write(_('hg update %s;\n') % children) + ui.write(_('hg update %s;\n') % child) if shouldmove: - ui.write(_('hg bookmark %s -r %s;\n') % (bm, children)) + ui.write(_('hg bookmark %s -r %s;\n') % (bm, child)) else: updatecheck = None # --merge is passed, we don't need to care about commands.update.check @@ -1194,7 +1192,7 @@ if opts['merge']: updatecheck = 'none' try: - ret = hg.updatetotally(ui, repo, children.node(), None, + ret = hg.updatetotally(ui, repo, child.node(), None, updatecheck=updatecheck) except error.Abort as exc: # replace the hint to mention about --merge option @@ -1207,7 +1205,7 @@ lock = repo.lock() tr = repo.transaction('next') if shouldmove: - bmchanges = [(bm, children.node())] + bmchanges = [(bm, child.node())] repo._bookmarks.applychanges(repo, tr, bmchanges) else: bookmarksmod.deactivate(repo) @@ -1215,7 +1213,7 @@ finally: lockmod.release(tr, lock) if not ui.quiet: - displayer.show(children) + displayer.show(child) return 0 @eh.wrapcommand('commit') @@ -1302,9 +1300,9 @@ raise error.Abort(msg, hint=hint) @eh.command( - 'debugobsconvert', - [('', 'new-format', obsexchange._bestformat, _('Destination format for markers.'))], - '') + b'debugobsconvert', + [(b'', b'new-format', obsexchange._bestformat, _(b'Destination format for markers.'))], + b'') def debugobsconvert(ui, repo, new_format): origmarkers = repo.obsstore._all # settle version if new_format == repo.obsstore._version: @@ -1326,7 +1324,8 @@ 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)) + for data in obsolete.encodemarkers(markers, True, new_format): + f.write(data) f.close() ui.write(_('Done!\n')) @@ -1355,17 +1354,29 @@ @eh.uisetup def setupevolveunfinished(ui): - estate = ('evolvestate', False, False, _('evolve in progress'), - _("use 'hg evolve --continue' or 'hg evolve --abort' to abort")) - cmdutil.unfinishedstates.append(estate) - pstate = ('pickstate', False, False, _('pick in progress'), - _("use 'hg pick --continue' or 'hg pick --abort' to abort")) - cmdutil.unfinishedstates.append(pstate) + if not util.safehasattr(cmdutil, 'unfinishedstates'): + from mercurial import state as statemod + _msg = _('To continue: hg evolve --continue\n' + 'To abort: hg evolve --abort\n' + 'To stop: hg evolve --stop\n' + '(also see `hg help evolve.interrupted`)') + statemod.addunfinished('evolve', fname='evolvestate', + continueflag=True, stopflag=True, + statushint=_msg) + statemod.addunfinished('pick', fname='pickstate', continueflag=True) + else: + # compat <= hg-5.0 (5f2f6912c9e6) + estate = ('evolvestate', False, False, _('evolve in progress'), + _("use 'hg evolve --continue' or 'hg evolve --abort' to abort")) + cmdutil.unfinishedstates.append(estate) + pstate = ('pickstate', False, False, _('pick in progress'), + _("use 'hg pick --continue' or 'hg pick --abort' to abort")) + cmdutil.unfinishedstates.append(pstate) - afterresolved = ('evolvestate', _('hg evolve --continue')) - pickresolved = ('pickstate', _('hg pick --continue')) - cmdutil.afterresolvedstates.append(afterresolved) - cmdutil.afterresolvedstates.append(pickresolved) + afterresolved = ('evolvestate', _('hg evolve --continue')) + pickresolved = ('pickstate', _('hg pick --continue')) + cmdutil.afterresolvedstates.append(afterresolved) + cmdutil.afterresolvedstates.append(pickresolved) if util.safehasattr(cmdutil, 'STATES'): statedata = ('evolve', cmdutil.fileexistspredicate('evolvestate'),
--- a/hgext3rd/evolve/cmdrewrite.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/cmdrewrite.py Mon Jul 29 14:43:17 2019 +0200 @@ -29,6 +29,7 @@ obsutil, patch, phases, + pycompat, scmutil, util, ) @@ -86,28 +87,28 @@ 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')), + (b'D', b'current-date', None, + _(b'record the current date as commit date')), + (b'U', b'current-user', None, + _(b'record the current user as committer')), ] -interactiveopt = [['i', 'interactive', None, _('use interactive mode')]] +interactiveopt = [[b'i', b'interactive', None, _(b'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')), - ('', 'patch', False, _('make changes to wdir parent by editing patch')), - ('', 'close-branch', None, - _('mark a branch as closed, hiding it from the branch list')), - ('s', 'secret', None, _('use the secret phase for committing')), - ('n', 'note', '', _('store a note on amend'), _('TEXT')), - ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt, - _('[OPTION]... [FILE]...'), + b'amend|refresh', + [(b'A', b'addremove', None, + _(b'mark new/missing files as added/removed before committing')), + (b'a', b'all', False, _(b"match all files")), + (b'e', b'edit', False, _(b'invoke editor on commit messages')), + (b'', b'extract', False, _(b'extract changes from the commit to the working copy')), + (b'', b'patch', False, _(b'make changes to wdir parent by editing patch')), + (b'', b'close-branch', None, + _(b'mark a branch as closed, hiding it from the branch list')), + (b's', b'secret', None, _(b'use the secret phase for committing')), + (b'n', b'note', b'', _(b'store a note on amend'), _(b'TEXT')), + ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt, + _(b'[OPTION]... [FILE]...'), helpbasic=True) def amend(ui, repo, *pats, **opts): """combine a changeset with updates and replace it with a new one @@ -182,10 +183,7 @@ while newnode is None: fp.seek(0) previous_patch = fp.getvalue() - if 5 <= len(ui.edit.im_func.func_defaults): - newpatch = ui.edit(fp.getvalue(), old.user(), action="diff") - else: - newpatch = ui.edit(fp.getvalue(), old.user()) + newpatch = ui.edit(fp.getvalue(), old.user(), action="diff") afp = stringio() afp.write(newpatch) @@ -320,7 +318,7 @@ # Filter copies copied = copies.pathcopies(target, ctx) - copied = dict((dst, src) for dst, src in copied.iteritems() + copied = dict((dst, src) for dst, src in copied.items() if dst in files) def filectxfn(repo, memctx, path, contentctx=ctx, redirect=newcontent): @@ -441,22 +439,22 @@ oldcopies[f] = src[0] oldcopies.update(copies) copies = dict((dst, oldcopies.get(src, src)) - for dst, src in oldcopies.iteritems()) + for dst, src in oldcopies.items()) # Adjust the dirstate copies - for dst, src in copies.iteritems(): + for dst, src in copies.items(): 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')), - ('i', 'interactive', False, _('interactive mode to uncommit (EXPERIMENTAL)')), - ('r', 'rev', '', _('revert commit content to REV instead'), _('REV')), - ('', 'revert', False, _('discard working directory changes after uncommit')), - ('n', 'note', '', _('store a note on uncommit'), _('TEXT')), + b'uncommit', + [(b'a', b'all', None, _(b'uncommit all changes when no arguments given')), + (b'i', b'interactive', False, _(b'interactive mode to uncommit (EXPERIMENTAL)')), + (b'r', b'rev', b'', _(b'revert commit content to REV instead'), _(b'REV')), + (b'', b'revert', False, _(b'discard working directory changes after uncommit')), + (b'n', b'note', b'', _(b'store a note on uncommit'), _(b'TEXT')), ] + commands.walkopts + commitopts + commitopts2 + commitopts3, - _('[OPTION]... [NAME]')) + _(b'[OPTION]... [NAME]')) def uncommit(ui, repo, *pats, **opts): """move changes from parent revision to working directory @@ -511,7 +509,7 @@ if disallowunstable and not onahead: raise error.Abort(_("cannot uncommit in the middle of a stack")) - match = scmutil.match(old, pats, opts) + match = scmutil.match(old, pats, pycompat.byteskwargs(opts)) # Check all explicitly given files; abort if there's a problem. if match.files(): @@ -554,7 +552,7 @@ if (pats or includeorexclude or opts.get('all')): if not (opts['message'] or opts['logfile']): opts['message'] = old.description() - message = cmdutil.logmessage(ui, opts) + message = cmdutil.logmessage(ui, pycompat.byteskwargs(opts)) newid = _commitfiltered(repo, old, match, target=rev, message=message, user=opts.get('user'), date=opts.get('date')) @@ -668,7 +666,7 @@ patch.patchrepo(ui, repo, pold, store, fp, 1, '', files=files, eolmode=None) except patch.PatchError as err: - raise error.Abort(str(err)) + raise error.Abort(pycompat.bytestr(err)) finally: del fp @@ -685,13 +683,13 @@ return newcm @eh.command( - 'fold|squash', - [('r', 'rev', [], _("revision to fold"), _('REV')), - ('', 'exact', None, _("only fold specified revisions")), - ('', 'from', None, _("fold revisions linearly to working copy parent")), - ('n', 'note', '', _('store a note on fold'), _('TEXT')), - ] + commitopts + commitopts2 + commitopts3, - _('hg fold [OPTION]... [-r] REV'), + b'fold|squash', + [(b'r', b'rev', [], _(b"revision to fold"), _(b'REV')), + (b'', b'exact', None, _(b"only fold specified revisions")), + (b'', b'from', None, _(b"fold revisions linearly to working copy parent")), + (b'n', b'note', b'', _(b'store a note on fold'), _(b'TEXT')), + ] + commitopts + commitopts2 + commitopts3, + _(b'hg fold [OPTION]... [-r] REV'), helpbasic=True) def fold(ui, repo, *revs, **opts): """fold multiple revisions into a single one @@ -773,7 +771,7 @@ wlock = repo.wlock() lock = repo.lock() - root, head = rewriteutil.foldcheck(repo, revs) + root, head, p2 = rewriteutil.foldcheck(repo, revs) tr = repo.transaction('fold') try: @@ -785,7 +783,7 @@ 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" % + msgs += ["HG: Commit message of changeset %d.\n\n%s\n" % (c.rev(), c.description()) for c in allctx] commitopts['message'] = "\n".join(msgs) commitopts['edit'] = True @@ -794,10 +792,14 @@ if opts.get('note'): metadata['note'] = opts['note'] - newid, unusedvariable = rewriteutil.rewrite(repo, root, allctx, + updates = allctx[:] + if p2 is not None and root.p2() != p2: + updates.append(p2) + commitopts = pycompat.byteskwargs(commitopts) + newid, unusedvariable = rewriteutil.rewrite(repo, root, updates, head, [root.p1().node(), - root.p2().node()], + p2.node()], commitopts=commitopts) phases.retractboundary(repo, tr, targetphase, [newid]) replacements = {ctx.node(): [newid] for ctx in allctx} @@ -813,12 +815,12 @@ lockmod.release(lock, wlock) @eh.command( - 'metaedit', - [('r', 'rev', [], _("revision to edit"), _('REV')), - ('', 'fold', None, _("also fold specified revisions into one")), - ('n', 'note', '', _('store a note on metaedit'), _('TEXT')), - ] + commitopts + commitopts2 + commitopts3, - _('hg metaedit [OPTION]... [-r] [REV]')) + b'metaedit', + [(b'r', b'rev', [], _(b"revision to edit"), _(b'REV')), + (b'', b'fold', None, _(b"also fold specified revisions into one")), + (b'n', b'note', b'', _(b'store a note on metaedit'), _(b'TEXT')), + ] + commitopts + commitopts2 + commitopts3, + _(b'hg metaedit [OPTION]... [-r] [REV]')) def metaedit(ui, repo, *revs, **opts): """edit commit information @@ -872,7 +874,7 @@ 'not currently supported')) if opts['fold']: - root, head = rewriteutil.foldcheck(repo, revs) + root, head, p2 = rewriteutil.foldcheck(repo, revs) else: if repo.revs("%ld and public()", revs): raise error.Abort(_('cannot edit commit information for public ' @@ -886,6 +888,7 @@ hint %= repo[newunstable.first()] raise error.Abort(msg, hint=hint) root = head = repo[revs.first()] + p2 = root.p2() wctx = repo[None] p1 = wctx.p1() @@ -901,19 +904,23 @@ 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" % + msgs += ["HG: Commit message of changeset %d.\n\n%s\n" % (c.rev(), c.description()) for c in allctx] else: msgs = [head.description()] commitopts['message'] = "\n".join(msgs) commitopts['edit'] = True + updates = allctx[:] + if p2 is not None and (root.p2() != p2 or not opts['fold']): + updates.append(p2) # 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, + commitopts = pycompat.byteskwargs(commitopts) + newid, created = rewriteutil.rewrite(repo, root, updates, head, [root.p1().node(), - root.p2().node()], + p2.node()], commitopts=commitopts) if created: if p1.rev() in revs: @@ -939,10 +946,10 @@ hg.update(repo, newp1) metadataopts = [ - ('d', 'date', '', - _('record the specified date in metadata'), _('DATE')), - ('u', 'user', '', - _('record the specified user in metadata'), _('USER')), + (b'd', b'date', b'', + _(b'record the specified date in metadata'), _(b'DATE')), + (b'u', b'user', b'', + _(b'record the specified user in metadata'), _(b'USER')), ] def _getmetadata(**opts): @@ -956,22 +963,22 @@ return metadata @eh.command( - 'prune|obsolete', - [('n', 'new', [], _("successor changeset (DEPRECATED)")), - ('s', 'successor', [], _("successor changeset"), _('REV')), - ('r', 'rev', [], _("revisions to prune"), _('REV')), - ('k', 'keep', None, _("does not modify working copy during prune")), - ('n', 'note', '', _('store a note on prune'), _('TEXT')), - ('', 'pair', False, _("record a pairing, such as a rebase or divergence resolution " - "(pairing multiple precursors to multiple successors)")), - ('', 'biject', False, _("alias to --pair (DEPRECATED)")), - ('', 'fold', False, - _("record a fold (multiple precursors, one successor)")), - ('', 'split', False, - _("record a split (one precursor, multiple successors)")), - ('B', 'bookmark', [], _("remove revs only reachable from given" - " bookmark"), _('BOOKMARK'))] + metadataopts, - _('[OPTION] [-r] REV...'), + b'prune|obsolete', + [(b'n', b'new', [], _(b"successor changeset (DEPRECATED)")), + (b's', b'successor', [], _(b"successor changeset"), _(b'REV')), + (b'r', b'rev', [], _(b"revisions to prune"), _(b'REV')), + (b'k', b'keep', None, _(b"does not modify working copy during prune")), + (b'n', b'note', b'', _(b'store a note on prune'), _(b'TEXT')), + (b'', b'pair', False, _(b"record a pairing, such as a rebase or divergence resolution " + b"(pairing multiple precursors to multiple successors)")), + (b'', b'biject', False, _(b"alias to --pair (DEPRECATED)")), + (b'', b'fold', False, + _(b"record a fold (multiple precursors, one successor)")), + (b'', b'split', False, + _(b"record a split (one precursor, multiple successors)")), + (b'B', b'bookmark', [], _(b"remove revs only reachable from given" + b" bookmark"), _(b'BOOKMARK'))] + metadataopts, + _(b'[OPTION] [-r] REV...'), helpbasic=True) # XXX -U --noupdate option to prevent wc update and or bookmarks update ? def cmdprune(ui, repo, *revs, **opts): @@ -1010,7 +1017,8 @@ options = [o for o in ('pair', 'fold', 'split') if opts.get(o)] if 1 < len(options): - raise error.Abort(_("can only specify one of %s") % ', '.join(options)) + _opts = pycompat.sysbytes(', '.join(options)) + raise error.Abort(_("can only specify one of %s") % _opts) if bookmarks: reachablefrombookmark = rewriteutil.reachablefrombookmark @@ -1115,7 +1123,7 @@ repo._bookmarks.applychanges(repo, tr, bmchanges) commands.update(ui, repo, newnode.hex()) ui.status(_('working directory is now at %s\n') - % ui.label(str(newnode), 'evolve.node')) + % ui.label(bytes(newnode), 'evolve.node')) if movebookmark: bookmarksmod.activate(repo, bookactive) @@ -1153,12 +1161,12 @@ lockmod.release(tr, lock, wlock) @eh.command( - 'split', - [('i', 'interactive', True, _('use interactive mode')), - ('r', 'rev', [], _("revision to split"), _('REV')), - ('n', 'note', '', _("store a note on split"), _('TEXT')), - ] + commitopts + commitopts2 + commitopts3, - _('hg split [OPTION] [-r REV] [FILES]'), + b'split', + [(b'i', b'interactive', True, _(b'use interactive mode')), + (b'r', b'rev', [], _(b"revision to split"), _(b'REV')), + (b'n', b'note', b'', _(b"store a note on split"), _(b'TEXT')), + ] + commitopts + commitopts2 + commitopts3, + _(b'hg split [OPTION] [-r REV] [FILES]'), helpbasic=True) def cmdsplit(ui, repo, *pats, **opts): """split a changeset into smaller changesets @@ -1178,7 +1186,7 @@ newcommits = [] iselect = opts.pop('interactive') - revs = opts.get('rev') or '.' + revs = opts.get('rev') if not revs: revarg = '.' elif len(revs) == 1: @@ -1325,14 +1333,14 @@ lockmod.release(tr, lock, wlock) @eh.command( - 'touch', - [('r', 'rev', [], _('revision to update'), _('REV')), - ('n', 'note', '', _('store a note on touch'), _('TEXT')), - ('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')], + b'touch', + [(b'r', b'rev', [], _(b'revision to update'), _(b'REV')), + (b'n', b'note', b'', _(b'store a note on touch'), _(b'TEXT')), + (b'D', b'duplicate', False, + b'do not mark the new revision as successor of the old one'), + (b'A', b'allowdivergence', False, + b'mark the new revision as successor of the old one potentially creating ' + b'divergence')], # allow to choose the seed ? _('[-r] revs')) def touch(ui, repo, *revs, **opts): @@ -1355,10 +1363,8 @@ rewriteutil.precheck(repo, revs, 'touch') tmpl = utility.shorttemplate displayer = compat.changesetdisplayer(ui, repo, {'template': tmpl}) - with repo.wlock(), repo.lock(): - tr = repo.transaction('touch') - with util.acceptintervention(tr): - touchnodes(ui, repo, revs, displayer, **opts) + with repo.wlock(), repo.lock(), repo.transaction('touch'): + touchnodes(ui, repo, revs, displayer, **opts) def touchnodes(ui, repo, revs, displayer, **opts): duplicate = opts['duplicate'] @@ -1409,8 +1415,11 @@ else: duplicate = True + updates = [] + if len(ctx.parents()) > 1: + updates = ctx.parents() extradict = {'extra': extra} - new, unusedvariable = rewriteutil.rewrite(repo, ctx, [], ctx, + new, unusedvariable = rewriteutil.rewrite(repo, ctx, updates, ctx, [p1, p2], commitopts=extradict) # store touched version to help potential children @@ -1429,12 +1438,12 @@ repo.dirstate.setparents(new, node.nullid) @eh.command( - 'pick|grab', - [('r', 'rev', '', _('revision to pick'), _('REV')), - ('c', 'continue', False, 'continue interrupted pick'), - ('a', 'abort', False, 'abort interrupted pick'), + b'pick|grab', + [(b'r', b'rev', b'', _(b'revision to pick'), _(b'REV')), + (b'c', b'continue', False, b'continue interrupted pick'), + (b'a', b'abort', False, b'abort interrupted pick'), ] + mergetoolopts, - _('[-r] rev')) + _(b'[-r] rev')) def cmdpick(ui, repo, *revs, **opts): """move a commit on the top of working directory parent and updates to it.""" @@ -1448,8 +1457,7 @@ if opts.get('rev'): revs.append(opts['rev']) - overrides = {('ui', 'forcemerge'): opts.get('tool', '')} - with repo.wlock(), repo.lock(), ui.configoverride(overrides, 'pick'): + with repo.wlock(), repo.lock(): pickstate = state.cmdstate(repo, path='pickstate') pctx = repo['.'] @@ -1471,8 +1479,10 @@ ui.status(_('picking %d:%s "%s"\n') % (origctx.rev(), origctx, origctx.description().split("\n", 1)[0])) - stats = merge.graft(repo, origctx, origctx.p1(), ['local', - 'destination']) + overrides = {('ui', 'forcemerge'): opts.get('tool', '')} + with ui.configoverride(overrides, 'pick'): + stats = merge.graft(repo, origctx, origctx.p1(), + ['local', 'destination']) if compat.hasconflict(stats): pickstate.addopts({'orignode': origctx.node(), 'oldpctx': pctx.node()})
--- a/hgext3rd/evolve/compat.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/compat.py Mon Jul 29 14:43:17 2019 +0200 @@ -7,6 +7,7 @@ """ import inspect +import array from mercurial import ( context, @@ -15,6 +16,7 @@ mdiff, obsolete, obsutil, + pycompat, repair, scmutil, util, @@ -22,6 +24,13 @@ ) from mercurial.hgweb import hgweb_mod +if pycompat.ispy3: + arraytobytes = array.array.tobytes + arrayfrombytes = array.array.frombytes +else: + arraytobytes = array.array.tostring + arrayfrombytes = array.array.fromstring + # hg < 4.6 compat (c8e2d6ed1f9e) try: from mercurial import logcmdutil @@ -105,9 +114,14 @@ args = [a, '', b, '', fn1, fn2] # hg < 4.6 compat 8b6dd3922f70 - argspec = inspect.getargspec(mdiff.unidiff) + if util.safehasattr(inspect, 'signature'): + signature = inspect.signature(mdiff.unidiff) + needsbinary = 'binary' in signature.parameters + else: + argspec = inspect.getargspec(mdiff.unidiff) + needsbinary = 'binary' in argspec.args - if 'binary' in argspec.args: + if needsbinary: args.append(False) return mdiff.unidiff(*args) @@ -123,7 +137,7 @@ makedate = mercurial.util.makedate parsedate = mercurial.util.parsedate -def wireprotocommand(exthelper, name, args='', permission='pull'): +def wireprotocommand(exthelper, name, args=b'', permission=b'pull'): try: # Since b4d85bc1 from mercurial.wireprotov1server import wireprotocommand @@ -371,7 +385,7 @@ # examine each file copy for a potential directory move, which is # when all the files in a directory are moved to a new directory - for dst, src in fullcopy.iteritems(): + for dst, src in fullcopy.items(): dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst) if dsrc in invalid: # already seen to be uninteresting
--- a/hgext3rd/evolve/debugcmd.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/debugcmd.py Mon Jul 29 14:43:17 2019 +0200 @@ -21,7 +21,7 @@ eh = exthelper.exthelper() -@eh.command('debugobsstorestat', [], '') +@eh.command(b'debugobsstorestat', [], b'') def cmddebugobsstorestat(ui, repo): """print statistics about obsolescence markers in the repo""" def _updateclustermap(nodes, mark, clustersmap):
--- a/hgext3rd/evolve/depthcache.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/depthcache.py Mon Jul 29 14:43:17 2019 +0200 @@ -35,12 +35,12 @@ return len(repo.revs('::%d', rev)) @eh.command( - 'debugdepth', + b'debugdepth', [ - ('r', 'rev', [], 'revs to print depth for'), - ('', 'method', 'cached', "one of 'simple', 'cached', 'compare'"), + (b'r', b'rev', [], b'revs to print depth for'), + (b'', b'method', b'cached', b"one of 'simple', 'cached', 'compare'"), ], - _('REVS')) + _(b'REVS')) def debugdepth(ui, repo, **opts): """display depth of REVS """ @@ -112,16 +112,17 @@ cl = repo.unfiltered().changelog total = len(data) - def progress(pos, rev): + def progress(pos, rev=None): + revstr = '' if rev is None else ('rev %d' % rev) compat.progress(repo.ui, 'updating depth cache', - pos, 'rev %s' % rev, unit='revision', total=total) - progress(0, '') + pos, revstr, unit='revision', total=total) + progress(0) for idx, rev in enumerate(data, 1): assert rev == len(self._data), (rev, len(self._data)) self._data.append(self._depth(cl, rev)) if not (idx % 10000): # progress as a too high performance impact progress(idx, rev) - progress(None, '') + progress(None) def _depth(self, changelog, rev): cl = changelog @@ -185,7 +186,7 @@ else: headerdata = data[:self._cachekeysize] self._cachekey = self._deserializecachekey(headerdata) - self._data.fromstring(data[self._cachekeysize:]) + compat.arrayfrombytes(self._data, data[self._cachekeysize:]) self._ondiskkey = self._cachekey def save(self, repo): @@ -201,7 +202,7 @@ cachefile = repo.cachevfs(self._filepath, 'w', atomictemp=True) headerdata = self._serializecachekey() cachefile.write(headerdata) - cachefile.write(self._data.tostring()) + cachefile.write(compat.arraytobytes(self._data)) cachefile.close() self._ondiskkey = self._cachekey except (IOError, OSError) as exc:
--- a/hgext3rd/evolve/evolvecmd.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/evolvecmd.py Mon Jul 29 14:43:17 2019 +0200 @@ -26,6 +26,7 @@ obsolete, obsutil, phases, + pycompat, repair, scmutil, simplemerge, @@ -204,7 +205,7 @@ msg = _('skipping %s : we do not handle merge yet\n') % bumped ui.write_err(msg) return (False, ".") - prec = repo.set('last(allpredecessors(%d) and public())', bumped.rev()).next() + prec = next(repo.set('last(allpredecessors(%d) and public())', bumped.rev())) # For now we deny target merge if len(prec.parents()) > 1: msg = _('skipping: %s: public version is a merge, ' @@ -217,7 +218,7 @@ displayer.show(bumped) repo.ui.write(_('atop:')) displayer.show(prec) - if confirm and ui.prompt('perform evolve? [Ny]', 'n') != 'y': + if confirm and ui.prompt(_('perform evolve? [Ny]'), 'n') != 'y': raise error.Abort(_('evolve aborted by user')) if dryrun: todo = 'hg rebase --rev %s --dest %s;\n' % (bumped, prec.p1()) @@ -336,7 +337,7 @@ # we don't handle split in content-divergence yet if len(others) > 1: - othersstr = "[%s]" % (','.join([str(i) for i in others])) + othersstr = "[%s]" % (','.join([bytes(i) for i in others])) msg = _("skipping %s: %s with a changeset that got split" " into multiple ones:\n" "|[%s]\n" @@ -542,8 +543,8 @@ return (res, newnode) if newnode == publicdiv.node(): # case 2) - pubstr = str(publicdiv) - othstr = str(other) + pubstr = bytes(publicdiv) + othstr = bytes(other) msg = _('content divergence resolution between %s ' '(public) and %s has same content as %s, ' 'discarding %s\n') @@ -578,8 +579,9 @@ # conflicts while merging content-divergent changesets if compat.hasconflict(stats): evolvestate.save() - raise error.InterventionRequired(_("fix conflicts and see `hg help " - "evolve.interrupted`")) + hint = _("see 'hg help evolve.interrupted'") + raise error.InterventionRequired(_("unresolved merge conflicts"), + hint=hint) def _completecontentdivergent(ui, repo, progresscb, divergent, other, base, evolvestate): @@ -690,8 +692,8 @@ if aspects: # warn user - locstr = str(local) - othstr = str(other) + locstr = bytes(local) + othstr = bytes(other) if 'close' in aspects: filteredasp = aspects - {'close'} if filteredasp: @@ -984,8 +986,9 @@ copies.duplicatecopies(repo, repo[None], dest.rev(), orig.p1().rev()) dirstatedance(repo, dest, orig.node(), None) - raise error.InterventionRequired(_("fix conflicts and see `hg help " - "evolve.interrupted`")) + hint = _("see 'hg help evolve.interrupted'") + raise error.InterventionRequired(_("unresolved merge conflicts"), + hint=hint) nodenew = _relocatecommit(repo, orig, commitmsg) _finalizerelocate(repo, orig, dest, nodenew, tr, category, evolvestate) return nodenew @@ -1089,7 +1092,7 @@ if 1 < len(revs): msg = "multiple evolve candidates" hint = (_("select one of %s with --rev") - % ', '.join([str(repo[r]) for r in sorted(revs)])) + % ', '.join([bytes(repo[r]) for r in sorted(revs)])) raise error.Abort(msg, hint=hint) elif instabilities_map.get(targetcat, targetcat) in repo['.'].instabilities(): revs = set([repo['.'].rev()]) @@ -1314,7 +1317,7 @@ if opts.get('rev'): revs = scmutil.revrange(repo, opts.get('rev')) - fm = ui.formatter('evolvelist', opts) + fm = ui.formatter('evolvelist', pycompat.byteskwargs(opts)) for rev in revs: ctx = repo[rev] unpars = _preparelistctxs(ctx.parents(), lambda p: p.orphan()) @@ -1476,7 +1479,7 @@ continue base[tuple(nsuccset)] = n divergence = [] - for divset, b in base.iteritems(): + for divset, b in base.items(): divergence.append({ 'divergentnodes': divset, 'commonprecursor': b @@ -1593,8 +1596,8 @@ situation: - `hg evolve --continue`: - fix all the conflicts using `hg resolve` and then run this to continue the - interrupted evolve + resolve all the conflicts using `hg resolve` and then run this to + continue the interrupted evolve - `hg evolve --stop`: stops the current interrupted evolve, keeping all the successful steps, @@ -1620,25 +1623,23 @@ abortopt = opts['abort'] shouldupdate = opts['update'] - troublecategories = ['phase_divergent', 'content_divergent', 'orphan'] - specifiedcategories = [t.replace('_', '') - for t in troublecategories - if opts[t]] + troublecategories = { + 'phasedivergent': 'phase_divergent', + 'contentdivergent': 'content_divergent', + 'orphan': 'orphan', + } + specifiedcategories = [k for k, v in troublecategories.items() if opts[v]] if opts['list']: ui.pager('evolve') listtroubles(ui, repo, specifiedcategories, **opts) return targetcat = 'orphan' - has_some_opts = bool(revopt or anyopt or allopt or contopt or stopopt or abortopt) if 1 < len(specifiedcategories): msg = _('cannot specify more than one trouble category to solve (yet)') raise error.Abort(msg) elif len(specifiedcategories) == 1: targetcat = specifiedcategories[0] - elif repo['.'].obsolete() and not has_some_opts: - # if no args and parent is obsolete, update to successors - return solveobswdp(ui, repo, opts) ui.setconfig('ui', 'forcemerge', opts.get('tool', ''), 'evolve') @@ -1665,7 +1666,7 @@ return elif abortopt: if not evolvestate: - raise error.Abort(_('no interrupted evolve to stop')) + raise error.Abort(_('no interrupted evolve to abort')) evolvestate.load() # `hg next --evolve` in play if evolvestate['command'] != 'evolve': @@ -1680,19 +1681,20 @@ else: cmdutil.bailifchanged(repo) + obswdir = repo['.'].obsolete() revs = _selectrevs(repo, allopt, revopt, anyopt, targetcat) - # Case: when wdir parent is obsolete and args passed. - # Handling it here otherwise `revs` set would change, after - # performing update to successor of obsolete wdir parent. - # (in case when user passes a revset related to wdir parent '.::') - if repo['.'].obsolete(): + if not (revs or obswdir): + return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat) + obswdironly = not revs and obswdir + + if obswdir: result = solveobswdp(ui, repo, opts) if result != 0 or result is True: + # return as solving obswdp wasn't successful return result - - if not revs: - return _handlenotrouble(ui, repo, allopt, revopt, anyopt, targetcat) + if obswdironly: + return 0 # Progress handling seen = 1 @@ -1839,7 +1841,7 @@ # boolean value to say whether we should strip or not cleanup = True startnode = evolvestate['startnode'] - for old, new in evolvestate['replacements'].iteritems(): + for old, new in evolvestate['replacements'].items(): if new: evolvedctx.append(repo[new]) for temp in evolvestate['temprevs']: @@ -1851,7 +1853,7 @@ immutable = [c for c in evolvedctx if not c.mutable()] if immutable: repo.ui.warn(_("cannot clean up public changesets: %s\n") - % ', '.join(str(c) for c in immutable), + % ', '.join(bytes(c) for c in immutable), hint=_("see 'hg help phases' for details")) cleanup = False
--- a/hgext3rd/evolve/exthelper.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/exthelper.py Mon Jul 29 14:43:17 2019 +0200 @@ -111,7 +111,7 @@ self._functionwrappers.extend(other._functionwrappers) self._duckpunchers.extend(other._duckpunchers) self.cmdtable.update(other.cmdtable) - for section, items in other.configtable.iteritems(): + for section, items in other.configtable.items(): if section in self.configtable: self.configtable[section].update(items) else:
--- a/hgext3rd/evolve/firstmergecache.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/firstmergecache.py Mon Jul 29 14:43:17 2019 +0200 @@ -74,16 +74,17 @@ cl = repo.unfiltered().changelog total = len(data) - def progress(pos, rev): + def progress(pos, rev=None): + revstr = '' if rev is None else ('rev %d' % rev) compat.progress(repo.ui, 'updating firstmerge cache', - pos, 'rev %s' % rev, unit='revision', total=total) - progress(0, '') + pos, revstr, unit='revision', total=total) + progress(0) for idx, rev in enumerate(data, 1): assert rev == len(self._data), (rev, len(self._data)) self._data.append(self._firstmerge(cl, rev)) if not (idx % 10000): # progress as a too high performance impact progress(idx, rev) - progress(None, '') + progress(None) def _firstmerge(self, changelog, rev): cl = changelog @@ -122,7 +123,7 @@ else: headerdata = data[:self._cachekeysize] self._cachekey = self._deserializecachekey(headerdata) - self._data.fromstring(data[self._cachekeysize:]) + compat.arrayfrombytes(self._data, data[self._cachekeysize:]) self._ondiskkey = self._cachekey def save(self, repo): @@ -138,7 +139,7 @@ cachefile = repo.cachevfs(self._filepath, 'w', atomictemp=True) headerdata = self._serializecachekey() cachefile.write(headerdata) - cachefile.write(self._data.tostring()) + cachefile.write(compat.arraytobytes(self._data)) cachefile.close() self._ondiskkey = self._cachekey except (IOError, OSError) as exc:
--- a/hgext3rd/evolve/legacy.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/legacy.py Mon Jul 29 14:43:17 2019 +0200 @@ -139,7 +139,7 @@ oldmark['date'] = '%i %i' % tuple(oldmark['date']) meta = dict((k.encode('utf-8'), v.encode('utf-8')) - for k, v in oldmark.iteritems()) + for k, v in oldmark.items()) try: succs = [bin(n) for n in oldsubjects] succs = [n for n in succs if n != nullid]
--- a/hgext3rd/evolve/metadata.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/metadata.py Mon Jul 29 14:43:17 2019 +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__ = '9.0.1.dev' -testedwith = '4.5.2 4.6.2 4.7 4.8 4.9 5.0' -minimumhgversion = '4.5' -buglink = 'https://bz.mercurial-scm.org/' +__version__ = b'9.1.0.dev' +testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0' +minimumhgversion = b'4.5' +buglink = b'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obscache.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/obscache.py Mon Jul 29 14:43:17 2019 +0200 @@ -186,7 +186,7 @@ obsmarkers = list(obsmarkers) self._updatefrom(repo, revs, obsmarkers) duration = util.timer() - starttime - repo.ui.log('evoext-cache', 'updated %s in %.4f seconds (%sr, %so)\n', + repo.ui.log('evoext-cache', 'updated %s in %.4f seconds (%dr, %do)\n', self._cachename, duration, len(revs), len(obsmarkers)) # update the key from the new data
--- a/hgext3rd/evolve/obsdiscovery.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/obsdiscovery.py Mon Jul 29 14:43:17 2019 +0200 @@ -22,6 +22,7 @@ import weakref from mercurial import ( + encoding, error, exchange, extensions, @@ -186,12 +187,12 @@ ############################## @eh.command( - 'debugobshashrange', + b'debugobshashrange', [ - ('', 'rev', [], 'display obshash for all (rev, 0) range in REVS'), - ('', 'subranges', False, 'display all subranges'), + (b'', b'rev', [], b'display obshash for all (rev, 0) range in REVS'), + (b'', b'subranges', False, b'display all subranges'), ], - _('')) + _(b'')) def debugobshashrange(ui, repo, **opts): """display the ::REVS set topologically sorted in a stable way """ @@ -465,15 +466,16 @@ repo.depthcache.update(repo) total = len(revs) - def progress(pos, rev): + def progress(pos, rev=None): + revstr = '' if rev is None else ('rev %d' % rev) compat.progress(repo.ui, 'updating obshashrange cache', - pos, 'rev %s' % rev, unit='revision', total=total) + pos, revstr, unit='revision', total=total) # warm the cache for the new revs - progress(0, '') + progress(0) for idx, r in enumerate(revs): _obshashrange(repo, (r, 0)) progress(idx, r) - progress(None, '') + progress(None) del self._updating @@ -492,8 +494,9 @@ util.makedirs(self._vfs.dirname(self._path)) except OSError: return None - con = sqlite3.connect(self._path, timeout=30, isolation_level="IMMEDIATE") - con.text_factory = str + con = sqlite3.connect(encoding.strfromlocal(self._path), timeout=30, + isolation_level="IMMEDIATE") + con.text_factory = bytes return con @util.propertycache @@ -688,7 +691,7 @@ except ValueError: self._abort(error.ResponseError(_("unexpected response:"), d)) -@compat.wireprotocommand(eh, 'evoext_obshashrange_v1', 'ranges') +@compat.wireprotocommand(eh, b'evoext_obshashrange_v1', b'ranges') def srv_obshashrange_v1(repo, proto, ranges): ranges = decodelist(ranges) ranges = [_decrange(r) for r in ranges]
--- a/hgext3rd/evolve/obsexchange.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/obsexchange.py Mon Jul 29 14:43:17 2019 +0200 @@ -221,7 +221,7 @@ from mercurial import wireproto as wireprototypes wireprotov1server = wireprototypes opts = wireprotov1server.options('', ['heads', 'common'], others) - for k, v in opts.iteritems(): + for k, v in opts.items(): if k in ('heads', 'common'): opts[k] = wireprototypes.decodelist(v) obsdata = _getobsmarkersstream(repo, **opts)
--- a/hgext3rd/evolve/obshashtree.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/obshashtree.py Mon Jul 29 14:43:17 2019 +0200 @@ -28,9 +28,9 @@ # the obshash of its parents. This is similar to what happend for changeset # node where the parent is used in the computation @eh.command( - 'debugobsrelsethashtree', - [('', 'v0', None, 'hash on marker format "0"'), - ('', 'v1', None, 'hash on marker format "1" (default)')], _('')) + b'debugobsrelsethashtree', + [(b'', b'v0', None, b'hash on marker format "0"'), + (b'', b'v1', None, b'hash on marker format "1" (default)')], _(b'')) def debugobsrelsethashtree(ui, repo, v0=False, v1=False): """display Obsolete markers, Relevant Set, Hash Tree changeset-node obsrelsethashtree-node
--- a/hgext3rd/evolve/obshistory.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/obshistory.py Mon Jul 29 14:43:17 2019 +0200 @@ -16,6 +16,7 @@ patch, obsutil, node as nodemod, + pycompat, scmutil, util, ) @@ -42,14 +43,14 @@ efd.clear() @eh.command( - 'obslog|olog', - [('G', 'graph', True, _("show the revision DAG")), - ('r', 'rev', [], _('show the specified revision or revset'), _('REV')), - ('a', 'all', False, _('show all related changesets, not only precursors')), - ('p', 'patch', False, _('show the patch between two obs versions')), - ('f', 'filternonlocal', False, _('filter out non local commits')), - ] + commands.formatteropts, - _('hg olog [OPTION]... [REV]')) + b'obslog|olog', + [(b'G', b'graph', True, _(b"show the revision DAG")), + (b'r', b'rev', [], _(b'show the specified revision or revset'), _(b'REV')), + (b'a', b'all', False, _(b'show all related changesets, not only precursors')), + (b'p', b'patch', False, _(b'show the patch between two obs versions')), + (b'f', b'filternonlocal', False, _(b'filter out non local commits')), + ] + commands.formatteropts, + _(b'hg olog [OPTION]... [REV]')) def cmdobshistory(ui, repo, *revs, **opts): """show the obsolescence history of the specified revisions @@ -322,7 +323,7 @@ # Filter out candidates, returns only nodes with all their successors # already shown - validcandidates = filter(isvalidcandidate, candidates) + validcandidates = list(filter(isvalidcandidate, candidates)) # If we likely have a cycle if not validcandidates: @@ -423,15 +424,18 @@ def _debugobshistorygraph(ui, repo, revs, opts): - displayer = obsmarker_printer(ui, repo.unfiltered(), obspatch=True, diffopts=opts, buffered=True) + displayer = obsmarker_printer(ui, repo.unfiltered(), obspatch=True, + diffopts=pycompat.byteskwargs(opts), + buffered=True) edges = graphmod.asciiedges - walker = _obshistorywalker(repo.unfiltered(), revs, opts.get('all', False), opts.get('filternonlocal', False)) + walker = _obshistorywalker(repo.unfiltered(), revs, opts.get('all', False), + opts.get('filternonlocal', False)) compat.displaygraph(ui, repo, walker, displayer, edges) def _debugobshistoryrevs(ui, repo, revs, opts): """ Display the obsolescence history for revset """ - fm = ui.formatter('debugobshistory', opts) + fm = ui.formatter('debugobshistory', pycompat.byteskwargs(opts)) precursors = repo.obsstore.predecessors successors = repo.obsstore.successors nodec = repo.changelog.node @@ -473,7 +477,7 @@ shortdescription = shortdescription.splitlines()[0] fm.startitem() - fm.write('node', '%s', str(ctx), + fm.write('node', '%s', bytes(ctx), label="evolve.node") fm.plain(' ') @@ -793,7 +797,7 @@ def _getdifflines(iterdiff): """return a cleaned up lines""" try: - lines = iterdiff.next() + lines = next(iterdiff) except StopIteration: return None return _prepare_hunk(lines)
--- a/hgext3rd/evolve/rewind.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/rewind.py Mon Jul 29 14:43:17 2019 +0200 @@ -26,14 +26,14 @@ identicalflag = 4 @eh.command( - 'rewind|undo', - [('', 'to', [], _("rewind to these revisions"), _('REV')), - ('', 'as-divergence', None, _("preserve current latest successors")), - ('', 'exact', None, _("only rewind explicitly selected revisions")), - ('', 'from', [], - _("rewind these revisions to their predecessors"), _('REV')), - ], - _(''), + b'rewind|undo', + [(b'', b'to', [], _(b"rewind to these revisions"), _(b'REV')), + (b'', b'as-divergence', None, _(b"preserve current latest successors")), + (b'', b'exact', None, _(b"only rewind explicitly selected revisions")), + (b'', b'from', [], + _(b"rewind these revisions to their predecessors"), _(b'REV')), + ], + _(b''), helpbasic=True) def rewind(ui, repo, **opts): """rewind a stack of changesets to a previous state @@ -166,9 +166,12 @@ p2 = ctx.p2().node() p2 = rewindmap.get(p2, p2) + updates = [] + if len(ctx.parents()) > 1: + updates = ctx.parents() extradict = {'extra': extra} - new, unusedvariable = rewriteutil.rewrite(unfi, ctx, [], ctx, + new, unusedvariable = rewriteutil.rewrite(unfi, ctx, updates, ctx, [p1, p2], commitopts=extradict)
--- a/hgext3rd/evolve/rewriteutil.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/rewriteutil.py Mon Jul 29 14:43:17 2019 +0200 @@ -113,7 +113,14 @@ raise error.Abort(_("cannot fold non-linear revisions " "(multiple heads given)")) head = repo[heads.first()] - return root, head + baseparents = repo.revs('parents(%ld) - %ld', revs, revs) + if len(baseparents) > 2: + raise error.Abort(_("cannot fold revisions that merge with more than " + "one external changeset (not in revisions)")) + # root's p1 is already used as the target ctx p1 + baseparents -= {root.p1().rev()} + p2 = repo[baseparents.first()] + return root, head, p2 def deletebookmark(repo, repomarks, bookmarks): wlock = lock = tr = None @@ -150,7 +157,7 @@ # 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(): + for mark, bnode in repomarks.items(): nodetobookmarks.setdefault(bnode, []).append(mark) for marks in nodetobookmarks.values(): if bookmarks.issuperset(marks): @@ -171,8 +178,6 @@ 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)
--- a/hgext3rd/evolve/serveronly.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/serveronly.py Mon Jul 29 14:43:17 2019 +0200 @@ -23,8 +23,9 @@ obscache, obsexchange, ) -except ValueError as exc: - if str(exc) != 'Attempted relative import in non-package': +except (ValueError, ImportError) as exc: + if (isinstance(exc, ValueError) + and str(exc) != 'Attempted relative import in non-package'): raise # extension imported using direct path sys.path.insert(0, os.path.dirname(os.path.dirname(__file__))) @@ -59,5 +60,5 @@ repo.ui.setconfig('experimental', 'evolution', evolveopts) if obsolete.isenabled(repo, 'exchange'): # if no config explicitly set, disable bundle1 - if not isinstance(repo.ui.config('server', 'bundle1'), str): + if not isinstance(repo.ui.config('server', 'bundle1'), bytes): repo.ui.setconfig('server', 'bundle1', False)
--- a/hgext3rd/evolve/stablerange.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/stablerange.py Mon Jul 29 14:43:17 2019 +0200 @@ -72,15 +72,15 @@ } @eh.command( - 'debugstablerange', + b'debugstablerange', [ - ('r', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'), - ('', 'subranges', False, 'recursively display data for subranges too'), - ('', 'verify', False, 'checks subranges content (EXPENSIVE)'), - ('', 'method', 'branchpoint', - 'method to use, one of "branchpoint", "mergepoint"') + (b'r', b'rev', [], b'operate on (rev, 0) ranges for rev in REVS'), + (b'', b'subranges', False, b'recursively display data for subranges too'), + (b'', b'verify', False, b'checks subranges content (EXPENSIVE)'), + (b'', b'method', b'branchpoint', + b'method to use, one of "branchpoint", "mergepoint"') ], - _('')) + _(b'')) def debugstablerange(ui, repo, **opts): """display standard stable subrange for a set of ranges @@ -502,7 +502,7 @@ elif skips < size: revs = walkfrom(jumphead) next(revs) - for i in xrange(skips): + for i in range(skips): jumphead = next(revs) assert jumphead is not None skipped = skips @@ -764,7 +764,7 @@ if value is None: revs = self.revsfromrange(repo, (merge, 0)) i = reversed(revs) - i.next() # pop the merge + next(i) # pop the merge expected = len(revs) - 1 # Since we do warmup properly, we can expect the cache to be hot # for everythin under the merge we investigate
--- a/hgext3rd/evolve/stablerangecache.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/stablerangecache.py Mon Jul 29 14:43:17 2019 +0200 @@ -14,6 +14,7 @@ import time from mercurial import ( + encoding, error, localrepo, node as nodemod, @@ -207,7 +208,11 @@ # 1) check the in memory cache # 2) check the sqlcaches (and warm in memory cache we want we find) cache = self._subrangescache - if rangeid not in cache and rangeid[0] <= self._ondisktiprev and self._con is not None: + if (rangeid not in cache + and self._ondisktiprev is not None + and rangeid[0] <= self._ondisktiprev + and self._con is not None): + value = None try: result = self._con.execute(_queryrange, rangeid).fetchone() @@ -234,8 +239,9 @@ util.makedirs(self._vfs.dirname(self._path)) except OSError: return None - con = sqlite3.connect(self._path, timeout=30, isolation_level="IMMEDIATE") - con.text_factory = str + con = sqlite3.connect(encoding.strfromlocal(self._path), timeout=30, + isolation_level="IMMEDIATE") + con.text_factory = bytes return con @util.propertycache
--- a/hgext3rd/evolve/stablesort.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/stablesort.py Mon Jul 29 14:43:17 2019 +0200 @@ -16,6 +16,7 @@ localrepo, error, node as nodemod, + pycompat, scmutil, ) @@ -52,14 +53,14 @@ return key @eh.command( - 'debugstablesort', + b'debugstablesort', [ - ('r', 'rev', [], 'heads to start from'), - ('', 'method', 'branchpoint', "method used for sorting, one of: " - "branchpoint, basic-mergepoint and basic-headstart"), - ('l', 'limit', '', 'number of revision display (default to all)') + (b'r', b'rev', [], b'heads to start from'), + (b'', b'method', b'branchpoint', b"method used for sorting, one of: " + b"branchpoint, basic-mergepoint and basic-headstart"), + (b'l', b'limit', b'', b'number of revision display (default to all)') ] + commands.formatteropts, - _('')) + _(b'')) def debugstablesort(ui, repo, **opts): """display the ::REVS set topologically sorted in a stable way """ @@ -72,7 +73,8 @@ raise error.Abort('unknown sorting method: "%s"' % method, hint='pick one of: %s' % valid_method) - displayer = compat.changesetdisplayer(ui, repo, opts, buffered=True) + displayer = compat.changesetdisplayer(ui, repo, pycompat.byteskwargs(opts), + buffered=True) kwargs = {} if opts['limit']: kwargs['limit'] = int(opts['limit']) @@ -434,7 +436,7 @@ def popready(stack): """pop the top most ready item in the list""" - for idx in xrange(len(stack) - 1, -1, -1): + for idx in range(len(stack) - 1, -1, -1): if children[stack[idx]].issubset(seen): return stack.pop(idx) return None @@ -549,7 +551,7 @@ # merge revision def jumps(): - for idx in xrange(index[rev - 1], index[rev]): + for idx in range(index[rev - 1], index[rev]): i = idx * 3 yield tuple(data[i:i + 3]) return jumps() @@ -576,11 +578,11 @@ total = len(data) - def progress(pos, rev): + def progress(pos, rev=None): + revstr = '' if rev is None else ('rev %d' % rev) compat.progress(repo.ui, 'updating stablesort cache', - pos, 'rev %s' % rev, unit='revision', total=total) + pos, revstr, unit='revision', total=total) - progress(0, '') for idx, rev in enumerate(data): parents = filterparents(repo.changelog.parentrevs(rev)) if len(parents) <= 1: @@ -594,7 +596,7 @@ break if not (idx % 1000): # progress as a too high performance impact progress(idx, rev) - progress(None, '') + progress(None) def clear(self, reset=False): super(ondiskstablesortcache, self).clear() @@ -620,9 +622,9 @@ indexsizedata = data[offset:offset + S_INDEXSIZE.size] indexsize = S_INDEXSIZE.unpack(indexsizedata)[0] offset += S_INDEXSIZE.size - self._index.fromstring(data[offset:offset + indexsize]) + compat.arrayfrombytes(self._index, data[offset:offset + indexsize]) offset += indexsize - self._data.fromstring(data[offset:]) + compat.arrayfrombytes(self._data, data[offset:]) self._ondiskkey = self._cachekey pass @@ -638,8 +640,8 @@ # data to write headerdata = self._serializecachekey() - indexdata = self._index.tostring() - data = self._data.tostring() + indexdata = compat.arraytobytes(self._index) + data = compat.arraytobytes(self._data) indexsize = S_INDEXSIZE.pack(len(indexdata)) # writing
--- a/hgext3rd/evolve/state.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/state.py Mon Jul 29 14:43:17 2019 +0200 @@ -45,6 +45,8 @@ def __nonzero__(self): return self.exists() + __bool__ = __nonzero__ + def __contains__(self, key): return key in self.opts @@ -134,7 +136,7 @@ elif rtype.lower(): repo.ui.debug('ignore evolve state record type %s' % rtype) else: - raise error.Abort(_('unknown evolvestate field type %r') + raise error.Abort(_("unknown evolvestate field type '%s'") % rtype, hint=_('upgrade your evolve')) return state finally:
--- a/hgext3rd/evolve/templatekw.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/templatekw.py Mon Jul 29 14:43:17 2019 +0200 @@ -24,7 +24,7 @@ ### template keywords if util.safehasattr(templatekw, 'compatlist'): - @eh.templatekeyword('instabilities', requires=set(['ctx', 'templ'])) + @eh.templatekeyword(b'instabilities', requires=set([b'ctx', b'templ'])) def showinstabilities(context, mapping): """List of strings. Evolution instabilities affecting the changeset (zero or more of "orphan", "content-divergent" or "phase-divergent").""" @@ -33,14 +33,14 @@ ctx.instabilities(), plural='instabilities') - @eh.templatekeyword('troubles', requires=set(['ctx', 'templ'])) + @eh.templatekeyword(b'troubles', requires=set([b'ctx', b'templ'])) def showtroubles(context, mapping): # legacy name for instabilities ctx = context.resource(mapping, 'ctx') return templatekw.compatlist(context, mapping, 'trouble', ctx.instabilities(), plural='troubles') else: # older template API in hg < 4.6 - @eh.templatekeyword('instabilities') + @eh.templatekeyword(b'instabilities') def showinstabilities(**args): """List of strings. Evolution instabilities affecting the changeset (zero or more of "orphan", "content-divergent" or "phase-divergent").""" @@ -48,7 +48,7 @@ return templatekw.showlist('instability', ctx.instabilities(), args, plural='instabilities') - @eh.templatekeyword('troubles') + @eh.templatekeyword(b'troubles') def showtroubles(**args): ctx = args['ctx'] return templatekw.showlist('trouble', ctx.instabilities(), args, @@ -59,10 +59,10 @@ def showprecursors(context, mapping): return _sp(context, mapping) showprecursors.__doc__ = _sp._origdoc - _tk = templatekw.templatekeyword("precursors", requires=_sp._requires) + _tk = templatekw.templatekeyword(b"precursors", requires=_sp._requires) _tk(showprecursors) else: - templatekw.keywords["precursors"] = _sp + templatekw.keywords[b"precursors"] = _sp def closestsuccessors(repo, nodeid): @@ -75,10 +75,10 @@ def showsuccessors(context, mapping): return _ss(context, mapping) showsuccessors.__doc__ = _ss._origdoc - _tk = templatekw.templatekeyword("successors", requires=_ss._requires) + _tk = templatekw.templatekeyword(b"successors", requires=_ss._requires) _tk(showsuccessors) else: - templatekw.keywords["successors"] = _ss + templatekw.keywords[b"successors"] = _ss def _getusername(ui): """the default username in the config or None""" @@ -207,7 +207,7 @@ return "\n".join(lines) if not util.safehasattr(templatekw, 'obsfateverb'): # <= hg-4.5 - @eh.templatekeyword("obsfatedata") + @eh.templatekeyword(b"obsfatedata") def showobsfatedata(repo, ctx, **args): # Get the needed obsfate data values = obsfatedata(repo, ctx) @@ -264,7 +264,7 @@ # Empty the generator try: while True: - chunkstr.append(chunk.next()) + chunkstr.append(next(chunk)) except StopIteration: pass
--- a/hgext3rd/evolve/thirdparty/cbor.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/evolve/thirdparty/cbor.py Mon Jul 29 14:43:17 2019 +0200 @@ -193,7 +193,7 @@ parts.append(dumps(k, sort_keys=sort_keys)) parts.append(dumps(v, sort_keys=sort_keys)) else: - for k,v in d.iteritems(): + for k,v in d.items(): parts.append(dumps(k, sort_keys=sort_keys)) parts.append(dumps(v, sort_keys=sort_keys)) return b''.join(parts)
--- a/hgext3rd/pullbundle.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/pullbundle.py Mon Jul 29 14:43:17 2019 +0200 @@ -168,7 +168,7 @@ slices = sliceoutgoing(repo, outgoing) end = util.timer() msg = _('pullbundle-cache: "missing" set sliced into %d subranges ' - 'in %s seconds\n') + 'in %f seconds\n') repo.ui.write(msg % (len(slices), end - start)) for sliceid, sliceout in slices: makeonecgpart(newpart, repo, sliceid, sliceout, version, source, bundlecaps, @@ -507,7 +507,7 @@ % (count, len(actionrevs))) if 1 < min_cache: repo.ui.write(" not caching ranges smaller than %d changesets\n" % min_cache) - for i in xrange(count): + for i in range(count): repo.ui.progress('gathering data', i, total=count) outgoing = takeonesample(repo, actionrevs) ranges = sliceoutgoing(repo, outgoing)
--- a/hgext3rd/serverminitopic.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/serverminitopic.py Mon Jul 29 14:43:17 2019 +0200 @@ -120,7 +120,7 @@ if revs: s = hashlib.sha1() for rev in revs: - s.update('%s;' % rev) + s.update('%d;' % rev) key = s.digest() return key
--- a/hgext3rd/topic/__init__.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/__init__.py Mon Jul 29 14:43:17 2019 +0200 @@ -137,6 +137,7 @@ obsolete, patch, phases, + pycompat, registrar, scmutil, templatefilters, @@ -186,11 +187,11 @@ 'topic.active': 'green', } -__version__ = '0.15.1.dev' +__version__ = b'0.16.0.dev' -testedwith = '4.5.2 4.6.2 4.7 4.8 4.9 5.0' -minimumhgversion = '4.5' -buglink = 'https://bz.mercurial-scm.org/' +testedwith = b'4.5.2 4.6.2 4.7 4.8 4.9 5.0' +minimumhgversion = b'4.5' +buglink = b'https://bz.mercurial-scm.org/' if util.safehasattr(registrar, 'configitem'): @@ -436,6 +437,15 @@ return super(topicrepo, self).branchmap() return self.filtered(topicfilter).branchmap() + def branchheads(self, branch=None, start=None, closed=False): + if branch is None: + branch = self[None].branch() + if self.currenttopic: + branch = "%s:%s" % (branch, self.currenttopic) + return super(topicrepo, self).branchheads(branch=branch, + start=start, + closed=closed) + def invalidatevolatilesets(self): # XXX we might be able to move this to something invalidated less often super(topicrepo, self).invalidatevolatilesets() @@ -537,7 +547,7 @@ csetcount = stack.stack(repo, topic=ct).changesetcount empty = csetcount == 0 if empty and not ctwasempty: - ui.status('active topic %r is now empty\n' % ct) + ui.status("active topic '%s' is now empty\n" % ct) trnames = getattr(tr, 'names', getattr(tr, '_names', ())) if ('phase' in trnames or any(n.startswith('push-response') @@ -546,10 +556,10 @@ hint = _("(see 'hg help topics' for more information)\n") if ctwasempty and not empty: if csetcount == 1: - msg = _('active topic %r grew its first changeset\n%s') + msg = _("active topic '%s' grew its first changeset\n%s") ui.status(msg % (ct, hint)) else: - msg = _('active topic %r grew its %s first changesets\n%s') + msg = _("active topic '%s' grew its %s first changesets\n%s") ui.status(msg % (ct, csetcount, hint)) tr.addpostclose('signalcurrenttopicempty', currenttopicempty) @@ -563,13 +573,13 @@ listnames=lambda repo: repo.topics)) if post45template: - @templatekeyword('topic', requires={'ctx'}) + @templatekeyword(b'topic', requires={b'ctx'}) def topickw(context, mapping): """:topic: String. The topic of the changeset""" ctx = context.resource(mapping, 'ctx') return ctx.topic() - @templatekeyword('topicidx', requires={'ctx'}) + @templatekeyword(b'topicidx', requires={b'ctx'}) def topicidxkw(context, mapping): """:topicidx: Integer. Index of the changeset as a stack alias""" ctx = context.resource(mapping, 'ctx') @@ -617,14 +627,14 @@ # revset predicates are automatically registered at loading via this symbol revsetpredicate = topicrevset.revsetpredicate -@command('topics', [ - ('', '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'), - ('', 'current', None, 'display the current topic only'), +@command(b'topics', [ + (b'', b'clear', False, b'clear active topic if any'), + (b'r', b'rev', [], b'revset of existing revisions', _(b'REV')), + (b'l', b'list', False, b'show the stack of changeset in the topic'), + (b'', b'age', False, b'show when you last touched the topics'), + (b'', b'current', None, b'display the current topic only'), ] + commands.formatteropts, - _('hg topics [TOPIC]')) + _(b'hg topics [TOPIC]')) def topics(ui, repo, topic=None, **opts): """View current topic, set current topic, change topic for a set of revisions, or see all topics. @@ -702,7 +712,8 @@ topic = repo.currenttopic if not topic: raise error.Abort(_('no active topic to list')) - return stack.showstack(ui, repo, topic=topic, opts=opts) + return stack.showstack(ui, repo, topic=topic, + opts=pycompat.byteskwargs(opts)) if touchedrevs: if not obsolete.isenabled(repo, obsolete.createmarkersopt): @@ -752,7 +763,7 @@ ui.write_err(_('no active topic\n')) ret = 1 elif current: - fm = ui.formatter('topic', opts) + fm = ui.formatter('topic', pycompat.byteskwargs(opts)) namemask = '%s\n' label = 'topic.active' fm.startitem() @@ -782,7 +793,8 @@ if topic is None: branch = repo[None].branch() ui.pager('stack') - return stack.showstack(ui, repo, branch=branch, topic=topic, opts=opts) + return stack.showstack(ui, repo, branch=branch, topic=topic, + opts=pycompat.byteskwargs(opts)) @command('debugcb|debugconvertbookmark', [ ('b', 'bookmark', '', _('bookmark to convert to topic')), @@ -804,7 +816,7 @@ bmstore = repo._bookmarks nodetobook = {} - for book, revnode in bmstore.iteritems(): + for book, revnode in bmstore.items(): if nodetobook.get(revnode): nodetobook[revnode].append(book) else: @@ -836,7 +848,7 @@ actions[(bookmark, revnum)] = targetrevs elif convertall: - for bmark, revnode in sorted(bmstore.iteritems()): + for bmark, revnode in sorted(bmstore.items()): revnum = repo[revnode].rev() if revnum in skipped: continue @@ -854,7 +866,7 @@ if actions: try: tr = repo.transaction('debugconvertbookmark') - for ((bmark, revnum), targetrevs) in sorted(actions.iteritems()): + for ((bmark, revnum), targetrevs) in sorted(actions.items()): _applyconvertbmarktopic(ui, repo, targetrevs, revnum, bmark, tr) tr.close() finally: @@ -952,7 +964,7 @@ # to not be so invasive. del fixedextra['amend_source'] ui.debug('changing topic of %s from %s to %s\n' % ( - c, oldtopic, newtopic)) + c, oldtopic or '<none>', newtopic or '<none>')) ui.debug('fixedextra: %r\n' % fixedextra) # While changing topic of set of linear commits, make sure that # we base our commits on new parent rather than old parent which @@ -997,7 +1009,7 @@ return rewrote def _listtopics(ui, repo, opts): - fm = ui.formatter('topics', opts) + fm = ui.formatter('topics', pycompat.byteskwargs(opts)) activetopic = repo.currenttopic namemask = '%s' if repo.topics:
--- a/hgext3rd/topic/compat.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/compat.py Mon Jul 29 14:43:17 2019 +0200 @@ -9,6 +9,7 @@ from mercurial import ( obsolete, + pycompat, ) getmarkers = None @@ -24,3 +25,10 @@ getmarkers = obsolete.getmarkers if successorssets is None: successorssets = obsolete.successorssets + +if pycompat.ispy3: + def branchmapitems(branchmap): + return branchmap.items() +else: + def branchmapitems(branchmap): + return branchmap.iteritems()
--- a/hgext3rd/topic/discovery.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/discovery.py Mon Jul 29 14:43:17 2019 +0200 @@ -14,6 +14,7 @@ ) from . import ( common, + compat, ) try: @@ -49,7 +50,7 @@ def remotebranchmap(): # drop topic information from changeset about to be published result = collections.defaultdict(list) - for branch, heads in origremotebranchmap().iteritems(): + for branch, heads in compat.branchmapitems(origremotebranchmap()): if ':' not in branch: result[branch].extend(heads) else: @@ -110,7 +111,7 @@ repo.unfiltered = lambda: unxx pushop.repo = repo summary = orig(pushop) - for key, value in summary.iteritems(): + for key, value in summary.items(): if ':' in key: # This is a topic if value[0] is None and value[1]: summary[key] = ([value[1][0]], ) + value[1:] @@ -171,12 +172,12 @@ if repo is not None: repo.invalidatecaches() finalheads = _nbheads(repo) - for branch, oldnb in tr._prepushheads.iteritems(): + for branch, oldnb in tr._prepushheads.items(): newnb = finalheads.pop(branch, 0) if oldnb < newnb: msg = _('push create a new head on branch "%s"' % branch) raise error.Abort(msg) - for branch, newnb in finalheads.iteritems(): + for branch, newnb in finalheads.items(): if 1 < newnb: msg = _('push create more than 1 head on new branch "%s"' % branch)
--- a/hgext3rd/topic/flow.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/flow.py Mon Jul 29 14:43:17 2019 +0200 @@ -11,8 +11,13 @@ from mercurial.i18n import _ +from . import ( + compat, +) + def enforcesinglehead(repo, tr): - for name, heads in repo.filtered('visible').branchmap().iteritems(): + branchmap = repo.filtered('visible').branchmap() + for name, heads in compat.branchmapitems(branchmap): if len(heads) > 1: hexs = [node.short(n) for n in heads] raise error.Abort(_('%d heads on "%s"') % (len(heads), name),
--- a/hgext3rd/topic/randomname.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/randomname.py Mon Jul 29 14:43:17 2019 +0200 @@ -1005,6 +1005,9 @@ ] def randomtopicname(ui): + # Re-implement random.choice() in the way it was written in Python 2. + def choice(things): + return things[int(len(things) * random.random())] if ui.configint("devel", "randomseed"): random.seed(ui.configint("devel", "randomseed")) - return random.choice(adjectives) + "-" + random.choice(animals) + return choice(adjectives) + "-" + choice(animals)
--- a/hgext3rd/topic/revset.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/revset.py Mon Jul 29 14:43:17 2019 +0200 @@ -28,7 +28,7 @@ return x[1] raise error.ParseError(err) -@revsetpredicate('topic([string or set])') +@revsetpredicate(b'topic([string or set])') def topicset(repo, subset, x): """All changesets with the specified topic or the topics of the given changesets. Without the argument, all changesets with any topic specified. @@ -76,7 +76,7 @@ return (subset & mutable).filter(matches) -@revsetpredicate('ngtip([branch])') +@revsetpredicate(b'ngtip([branch])') def ngtipset(repo, subset, x): """The untopiced tip. @@ -89,7 +89,7 @@ branch = repo['.'].branch() return subset & revset.baseset(destination.ngtip(repo, branch)) -@revsetpredicate('stack()') +@revsetpredicate(b'stack()') def stackset(repo, subset, x): """All relevant changes in the current topic,
--- a/hgext3rd/topic/stack.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/stack.py Mon Jul 29 14:43:17 2019 +0200 @@ -8,6 +8,7 @@ error, node, phases, + pycompat, obsolete, util, ) @@ -204,7 +205,7 @@ return 0 except error.ManyMergeDestAbort as exc: # XXX we should make it easier for upstream to provide the information - self.behinderror = str(exc).split('-', 1)[0].rstrip() + self.behinderror = pycompat.bytestr(exc).split('-', 1)[0].rstrip() return -1 return 0
--- a/hgext3rd/topic/topicmap.py Mon Jul 29 11:40:22 2019 +0200 +++ b/hgext3rd/topic/topicmap.py Mon Jul 29 14:43:17 2019 +0200 @@ -80,7 +80,7 @@ if revs: s = hashlib.sha1() for rev in revs: - s.update('%s;' % rev) + s.update('%d;' % rev) key = s.digest() return key @@ -100,8 +100,7 @@ # wrap commit status use the topic branch heads ctx = repo[node] if ctx.topic() and ctx.branch() == branch: - subbranch = "%s:%s" % (branch, ctx.topic()) - bheads = repo.branchheads("%s:%s" % (subbranch, ctx.topic())) + bheads = repo.branchheads("%s:%s" % (branch, ctx.topic())) ret = orig(repo, node, branch, bheads=bheads, opts=opts)
--- a/tests/test-evolve-abort-orphan.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-abort-orphan.t Mon Jul 29 14:43:17 2019 +0200 @@ -42,7 +42,7 @@ ============================================= $ hg evolve --abort - abort: no interrupted evolve to stop + abort: no interrupted evolve to abort [255] Testing with wrong combination of flags @@ -85,7 +85,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg parents @@ -132,7 +133,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > d $ hg resolve -m @@ -159,7 +161,8 @@ move:[5] added c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] testing that interrupted evolve shows up in morestatus @@ -270,7 +273,8 @@ atop:[7] added a merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg glog @@ -334,7 +338,8 @@ atop:[7] added a merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg glog o 9:7f8e8bd9f0b6 added c @@ -411,7 +416,8 @@ atop:[7] added a merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg glog @@ -486,7 +492,8 @@ move:[3] added c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg glog @@ -532,7 +539,8 @@ atop:[5] added b merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort
--- a/tests/test-evolve-abort-phasediv.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-abort-phasediv.t Mon Jul 29 14:43:17 2019 +0200 @@ -87,7 +87,8 @@ rebasing to destination parent: ca1b80f7960a merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] testing that interrupted evolve shows up in morestatus @@ -213,7 +214,8 @@ rebasing to destination parent: b1661037fa25 merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort @@ -282,7 +284,8 @@ rebasing to destination parent: b1661037fa25 merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo watwat > c @@ -297,7 +300,8 @@ rebasing to destination parent: ca1b80f7960a merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort
--- a/tests/test-evolve-content-divergent-basic.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-content-divergent-basic.t Mon Jul 29 14:43:17 2019 +0200 @@ -340,7 +340,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foobar > d @@ -399,7 +400,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo watbar > d @@ -609,7 +611,8 @@ merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ cat > a <<EOF
--- a/tests/test-evolve-content-divergent-corner-cases.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-content-divergent-corner-cases.t Mon Jul 29 14:43:17 2019 +0200 @@ -277,7 +277,8 @@ rebasing "other" content-divergent changeset de4ea3103326 on 9150fe93bec6 merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff --no-git --config diff.unified=3
--- a/tests/test-evolve-content-divergent-interrupted.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-content-divergent-interrupted.t Mon Jul 29 14:43:17 2019 +0200 @@ -86,7 +86,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg status -v @@ -197,7 +198,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort @@ -303,7 +305,8 @@ rebasing "other" content-divergent changeset 69bdd23a9b0d on ca1b80f7960a merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort @@ -356,7 +359,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --abort @@ -447,7 +451,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --stop @@ -499,7 +504,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --stop @@ -548,7 +554,8 @@ rebasing "other" content-divergent changeset 8fd1c4bd144c on ca1b80f7960a merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff
--- a/tests/test-evolve-content-divergent-relocation.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-content-divergent-relocation.t Mon Jul 29 14:43:17 2019 +0200 @@ -254,7 +254,8 @@ merging y warning: conflicts while merging y! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo watbar > y @@ -388,7 +389,8 @@ rebasing "other" content-divergent changeset 3f7a1f693080 on 7bbcf24ddecf merging y warning: conflicts while merging y! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -417,7 +419,8 @@ merging y warning: conflicts while merging y! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff
--- a/tests/test-evolve-continue.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-continue.t Mon Jul 29 14:43:17 2019 +0200 @@ -58,7 +58,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > d @@ -118,7 +119,8 @@ atop:[8] added d merging e warning: conflicts while merging e! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo bar > e @@ -158,7 +160,8 @@ atop:[9] added a merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > b @@ -242,7 +245,8 @@ move:[13] added f merging f warning: conflicts while merging f! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > f @@ -256,7 +260,8 @@ move:[15] added h merging h warning: conflicts while merging h! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > h @@ -302,7 +307,8 @@ perform evolve? [Ny] y merging g warning: conflicts while merging g! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > g @@ -350,7 +356,8 @@ atop:[24] added f merging g warning: conflicts while merging g! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > g $ hg resolve -m @@ -416,7 +423,8 @@ atop:[5] added c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] Status mentions file 'b' (copied from 'a') here, even though it wasn't
--- a/tests/test-evolve-issue5966.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-issue5966.t Mon Jul 29 14:43:17 2019 +0200 @@ -57,7 +57,8 @@ $ hg evolve -t :fail --rev 'first(orphan())' move:[2] banana atop:[4] apricot - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --list 34a690fcf6ab: banana
--- a/tests/test-evolve-issue5967.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-issue5967.t Mon Jul 29 14:43:17 2019 +0200 @@ -41,7 +41,8 @@ atop:[2] apricot merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo apricot > a
--- a/tests/test-evolve-orphan-merge.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-orphan-merge.t Mon Jul 29 14:43:17 2019 +0200 @@ -219,7 +219,8 @@ atop:[11] foo to c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo FOObar > c @@ -274,7 +275,8 @@ atop:[13] foo to c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foobar > c
--- a/tests/test-evolve-phase-divergence.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-phase-divergence.t Mon Jul 29 14:43:17 2019 +0200 @@ -802,7 +802,8 @@ rebasing to destination parent: 8c2bb6fb44e9 merging x warning: conflicts while merging x! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff
--- a/tests/test-evolve-phase.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-phase.t Mon Jul 29 14:43:17 2019 +0200 @@ -85,7 +85,8 @@ atop:[3] b merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff
--- a/tests/test-evolve-progress.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-progress.t Mon Jul 29 14:43:17 2019 +0200 @@ -133,7 +133,8 @@ picked tool ':merge' for a (binary False symlink False changedelete False) my a@f8d7d38c0a88+ other a@df5d742141b0 ancestor a@152c368c622b warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo resolved > a $ hg resolve -m a
--- a/tests/test-evolve-public-content-divergent-corner-cases.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-public-content-divergent-corner-cases.t Mon Jul 29 14:43:17 2019 +0200 @@ -389,7 +389,8 @@ rebasing "other" content-divergent changeset e568fd1029bb on 155349b645be merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -418,7 +419,8 @@ local changed d which other deleted use (c)hanged version, (d)elete, or leave (u)nresolved? u 1 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg sum
--- a/tests/test-evolve-public-content-divergent-discard.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-public-content-divergent-discard.t Mon Jul 29 14:43:17 2019 +0200 @@ -269,7 +269,8 @@ merging ch warning: conflicts while merging ch! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -383,7 +384,8 @@ rebasing "other" content-divergent changeset f89a8e2f86ac on 155349b645be merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo c > c @@ -488,7 +490,8 @@ merging dh warning: conflicts while merging dh! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo dh > dh @@ -591,7 +594,8 @@ rebasing "other" content-divergent changeset 67b19bbd770f on 155349b645be merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo c > c @@ -604,7 +608,8 @@ merging dh warning: conflicts while merging dh! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo dh > dh
--- a/tests/test-evolve-public-content-divergent-main.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-public-content-divergent-main.t Mon Jul 29 14:43:17 2019 +0200 @@ -170,7 +170,8 @@ merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo "I am foobar" > b @@ -356,7 +357,8 @@ rebasing "other" content-divergent changeset f31bcc378766 on 155349b645be merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -486,7 +488,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 0 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo d > d @@ -578,7 +581,8 @@ rebasing "other" content-divergent changeset 3c17c7afaf6e on 155349b645be merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -612,7 +616,8 @@ merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') 2 files updated, 0 files merged, 0 files removed, 1 files unresolved - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo d > d
--- a/tests/test-evolve-stop-orphan.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-stop-orphan.t Mon Jul 29 14:43:17 2019 +0200 @@ -90,7 +90,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --stop @@ -135,7 +136,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg diff @@ -195,7 +197,8 @@ atop:[5] added c merging d warning: conflicts while merging d! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foo > d $ hg resolve -m @@ -244,7 +247,8 @@ move:[5] added c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg status @@ -281,7 +285,8 @@ atop:[9] added b merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo foobar > c @@ -356,7 +361,8 @@ move:[10] added c merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --stop
--- a/tests/test-evolve-stop-phasediv.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-stop-phasediv.t Mon Jul 29 14:43:17 2019 +0200 @@ -84,7 +84,8 @@ rebasing to destination parent: ca1b80f7960a merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg evolve --stop
--- a/tests/test-evolve-topic.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve-topic.t Mon Jul 29 14:43:17 2019 +0200 @@ -426,7 +426,8 @@ move:[s3] add hhh merging hhh warning: conflicts while merging hhh! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ echo "resolved hhh" > hhh $ hg resolve --mark hhh @@ -438,3 +439,22 @@ atop:[s3] add hhh move:[s5] add jjj working directory is now at 2c295936ac04 + +Test to make sure that evolve don't crash with FilteredRepoLookupError when obsolete revs are in play: +------------------------------------------------------------------------------------------------------ + +update to obsolete revision + $ hg up -r 'min(desc("add fff"))' --hidden + updating to a hidden changeset 6a6b7365c751 + (hidden revision '6a6b7365c751' was rewritten as: 2c295936ac04) + switching to topic foo + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + working directory parent is obsolete! (6a6b7365c751) + (use 'hg evolve' to update to its successor: 2c295936ac04) + +Evolve: + $ hg evolve + update:[26] add fff + switching to topic bar + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + working directory is now at 2c295936ac04
--- a/tests/test-evolve.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-evolve.t Mon Jul 29 14:43:17 2019 +0200 @@ -1456,7 +1456,8 @@ move:[31] will cause conflict at evolve merging newfile warning: conflicts while merging newfile! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ glog -r "desc('add unstableifparentisfolded')::" --hidden @@ -1508,7 +1509,6 @@ update:[1] added a 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory is now at ab832e43dd5a - no troubled changesets $ hg log -GT "{rev}:{node|short} {desc} ({bookmarks})\n" --hidden @ 1:ab832e43dd5a added a (book)
--- a/tests/test-fold.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-fold.t Mon Jul 29 14:43:17 2019 +0200 @@ -7,9 +7,17 @@ > fold=-d "0 0" > [extensions] > evolve= + > [alias] + > glog = log -GT "{rev}: {desc}" + > glf = log -GT "{rev}: {desc} ({files})" > [ui] > logtemplate = '{rev} - {node|short} {desc|firstline} [{author}] ({phase}) {bookmarks}\n' > EOF + $ mkcommit() { + > echo "$1" > "$1" + > hg add "$1" + > hg ci -qm "$1" + > } $ hg init fold-tests $ cd fold-tests/ @@ -270,3 +278,106 @@ $ cd .. +One merge commit + + $ hg init fold-a-merge + $ cd fold-a-merge + + $ mkcommit zebra + + $ hg up null + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit apple + $ mkcommit banana + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m merge + + $ mkcommit coconut + + $ hg glf + @ 4: coconut (coconut) + | + o 3: merge () + |\ + | o 2: banana (banana) + | | + | o 1: apple (apple) + | + o 0: zebra (zebra) + + +now we merge some of the fruits + + $ hg fold --exact -r 'desc("banana")::desc("coconut")' -m 'banana+coconut in a merge with zebra' + 3 changesets folded + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg glf + @ 5: banana+coconut in a merge with zebra (banana coconut) + |\ + | o 1: apple (apple) + | + o 0: zebra (zebra) + + +let's go even further: zebra becomes a parent of the squashed fruit commit + + $ hg fold --from -r 'desc("apple")' -m 'apple+banana+coconut is a child of zebra' + 2 changesets folded + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg glf + @ 6: apple+banana+coconut is a child of zebra (apple banana coconut) + | + o 0: zebra (zebra) + + +make sure zebra exists at tip and has expected contents + + $ hg cat -r tip zebra + zebra + + $ cd .. + +Multiple merge commits + + $ hg init fold-many-merges + $ cd fold-many-merges + + $ hg debugbuilddag '+3 *3 /3 /4 /4' + $ hg glog + o 6: r6 + |\ + | o 5: r5 + | |\ + | | o 4: r4 + | |/| + | | o 3: r3 + | | | + o | | 2: r2 + |/ / + o / 1: r1 + |/ + o 0: r0 + + +cannot fold 5 and 6 because they have 3 external parents in total: 1, 2, 4 + + $ hg fold --exact -r 5:6 -m r5+r6 + abort: cannot fold revisions that merge with more than one external changeset (not in revisions) + [255] + +now many of the parents are included in the revisions to fold, only 0 and 3 are external + + $ hg fold --exact -r 1+2+4+5+6 -m r1+r2+r4+r5+r6 + 5 changesets folded + + $ hg glog + o 7: r1+r2+r4+r5+r6 + |\ + | o 3: r3 + |/ + o 0: r0 + + $ cd ..
--- a/tests/test-issue-5720.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-issue-5720.t Mon Jul 29 14:43:17 2019 +0200 @@ -61,7 +61,8 @@ atop:[3] b merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] Fix the conflict
--- a/tests/test-metaedit.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-metaedit.t Mon Jul 29 14:43:17 2019 +0200 @@ -10,6 +10,7 @@ > publish = False > [alias] > qlog = log --template='{rev} - {node|short} {desc} ({phase})\n' + > gluf = log -GT "{rev}: {desc|firstline} - {author|user} ({files})" > [diff] > git = 1 > unified = 0 @@ -229,3 +230,54 @@ 1 changesets folded $ hg log -r "tip" --template '{rev}: {author}\n' 12: foobar3 + +working on merge commits too + + $ hg up -q 11 + $ hg merge -q 12 + $ hg ci -m 'merge commit' + $ hg st --change . + A D + $ hg metaedit --user someone-else + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg st --change . + A D + $ hg gluf + @ 14: merge commit - someone-else () + |\ + | o 12: D2 - foobar3 (D) + | | + o | 11: E - foobar2 (E F) + |/ + o 3: C - test (C) + | + | o 2: B - test (B) + |/ + o 1: A - test (A) + | + o 0: ROOT - test (ROOT) + + $ hg metaedit --user mr-squasher -r 3:14 --fold --message squashed + 4 changesets folded + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg st --change . + A C + A D + A E + A F + $ hg gluf + @ 15: squashed - mr-squasher (C D E F) + | + | o 2: B - test (B) + |/ + o 1: A - test (A) + | + o 0: ROOT - test (ROOT) + + $ hg files + A + C + D + E + F + ROOT
--- a/tests/test-rewind.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-rewind.t Mon Jul 29 14:43:17 2019 +0200 @@ -9,6 +9,8 @@ > interactive = true > [phases] > publish=False + > [alias] + > glf = log -GT "{rev}: {desc} ({files})" > [extensions] > evolve = > EOF @@ -935,3 +937,45 @@ $ hg rewind abort: uncommitted changes [255] + +Merge commits +------------- + + $ hg up --clean .^ + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo foo > foo + $ hg ci -qAm foo + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m merge + $ hg st --change . + A B + + $ echo bar > foo + $ hg amend -m 'merge, but foo is now bar' + $ hg st --change . + M foo + A B + + $ hg rewind --from . + rewinded to 1 changesets + (1 changesets obsoleted) + working directory is now at 006fd8c2fed9 + $ hg st --change . + A B + + $ hg glf -r '. + allpredecessors(.) + parents(.)' --hidden + @ 6: merge () + |\ + +---x 5: merge, but foo is now bar (foo) + | |/ + +---x 4: merge () + | |/ + | o 3: foo (C foo) + | | + | ~ + o 2: c_B0 (B) + | + ~
--- a/tests/test-stabilize-conflict.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-stabilize-conflict.t Mon Jul 29 14:43:17 2019 +0200 @@ -128,7 +128,8 @@ atop:[5] babar count up to ten merging babar warning: conflicts while merging babar! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg resolve -l U babar @@ -220,7 +221,8 @@ output file babar appears unchanged was merge successful (yn)? n merging babar failed! - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg resolve -l U babar
--- a/tests/test-topic-stack-data.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-topic-stack-data.t Mon Jul 29 14:43:17 2019 +0200 @@ -116,7 +116,7 @@ add foo_b branch: lake commit: (clean) - update: 2 new changesets (update) + update: (current) phases: 22 draft orphan: 3 changesets topic: foo
--- a/tests/test-topic-stack.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-topic-stack.t Mon Jul 29 14:43:17 2019 +0200 @@ -315,7 +315,7 @@ c_d branch: default commit: (clean) - update: (current) + update: 2 new changesets (update) phases: 4 draft topic: foo
--- a/tests/test-topic.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-topic.t Mon Jul 29 14:43:17 2019 +0200 @@ -961,3 +961,27 @@ abort: cannot use --age while setting a topic [255] $ cd .. + +Test that topics doesn't confuse branchheads checking logic +----------------------------------------------------------- + + $ hg init hgtags + $ cd hgtags + $ echo a > a + $ hg ci -Am "added a" --config experimental.topic-mode=default + adding a + $ echo b > b + $ hg ci -Am "added b" --config experimental.topic-mode=default + adding b + + $ hg topic foo -r . + switching to topic foo + changed topic on 1 changesets to "foo" + +Try to put a tag on current rev which also has an active topic: + $ hg tag 1.0 + $ hg tags + tip 3:9efc5c3ac635 + 1.0 2:3bbb3fdb2546 + + $ cd ..
--- a/tests/test-touch.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-touch.t Mon Jul 29 14:43:17 2019 +0200 @@ -4,6 +4,8 @@ > logtemplate={rev}:{node|short} {desc}\n > [defaults] > amend=-d "0 0" + > [alias] + > glog = log -GT "{rev}: {desc}" > [extensions] > hgext.rebase= > EOF @@ -171,6 +173,34 @@ [255] $ hg touch --duplicate 2 +Reviving merge commit + + $ hg up 12 + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg merge 15 + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m merge + $ hg st --change . + A a + A b + $ hg prune -r . + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + working directory is now at * (glob) + 1 changesets pruned + $ hg touch 16 --hidden + $ hg glog -r '12+15+17' + o 17: merge + |\ + | o 15: ab + | + @ 12: move + | + ~ + $ hg st --change 17 + A a + A b + $ cd .. Make sure touch doesn't fail to warn about divergence (issue6107)
--- a/tests/test-tutorial.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-tutorial.t Mon Jul 29 14:43:17 2019 +0200 @@ -1528,7 +1528,6 @@ update:[8] animals 1 files updated, 0 files merged, 0 files removed, 0 files unresolved working directory is now at 2a2b36e14660 - no troubled changesets Relocating unstable change after prune ----------------------------------------------
--- a/tests/test-unstability-resolution-result.t Mon Jul 29 11:40:22 2019 +0200 +++ b/tests/test-unstability-resolution-result.t Mon Jul 29 14:43:17 2019 +0200 @@ -90,7 +90,8 @@ atop:[5] changea merging a warning: conflicts while merging a! (edit, then use 'hg resolve --mark') - fix conflicts and see `hg help evolve.interrupted` + unresolved merge conflicts + (see 'hg help evolve.interrupted') [1] $ hg revert -r "orphan()" a $ hg diff