Mercurial > evolve
view hgext3rd/evolve/compat.py @ 3611:c912eaf29eec stable
compat: call current obsolete.createmarkers(), not one from load time
Other extensions may wrap obsolete.createmarkers(). If they do, we
should call their wrapped version. However, since f61a23a84dac
(compat: add wrapper for obsolete.createmarkers() that accepts
"operation" arg, 2018-03-16), we started storing the version of the
function as it was when our compat module was loaded. This broke an
extension we use internally at Google.
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Fri, 23 Mar 2018 09:08:21 -0700 |
parents | 97530d6e340d |
children | a6bac0492eff |
line wrap: on
line source
# Copyright 2017 Octobus <contact@octobus.net> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. """ Compatibility module """ import inspect import functools from mercurial import ( copies, context, hg, mdiff, obsolete, revset, util, wireproto, ) from mercurial.hgweb import hgweb_mod # hg < 4.2 compat try: from mercurial import vfs as vfsmod vfsmod.vfs except ImportError: from mercurial import scmutil as vfsmod try: from mercurial import obsutil obsutil.closestpredecessors except ImportError: obsutil = None # hg < 4.6 compat (c8e2d6ed1f9e) try: from mercurial import logcmdutil changesetdisplayer = logcmdutil.changesetdisplayer changesetprinter = logcmdutil.changesetprinter displaygraph = logcmdutil.displaygraph except (AttributeError, ImportError): from mercurial import cmdutil changesetdisplayer = cmdutil.show_changeset changesetprinter = cmdutil.changeset_printer displaygraph = cmdutil.displaygraph from . import ( exthelper, ) eh = exthelper.exthelper() # Wrap obsolete.creatmarkers and make it accept but ignore "operation" argument # for hg < 4.3 originalcreatemarkers = obsolete.createmarkers while isinstance(originalcreatemarkers, functools.partial): originalcreatemarkers = originalcreatemarkers.func if originalcreatemarkers.__code__.co_argcount < 6: def createmarkers(repo, relations, flag=0, date=None, metadata=None, operation=None): return obsolete.createmarkers(repo, relations, flag, date, metadata) else: def createmarkers(*args, **kwargs): return obsolete.createmarkers(*args, **kwargs) if not util.safehasattr(hg, '_copycache'): # exact copy of relevantmarkers as in Mercurial-176d1a0ce385 # this fixes relevant markers computation for version < hg-4.3 @eh.wrapfunction(obsolete.obsstore, 'relevantmarkers') def relevantmarkers(orig, self, nodes): """return a set of all obsolescence markers relevant to a set of nodes. "relevant" to a set of nodes mean: - marker that use this changeset as successor - prune marker of direct children on this changeset - recursive application of the two rules on precursors of these markers It is a set so you cannot rely on order. Backport of mercurial changeset 176d1a0ce385 for version < 4.3 """ pendingnodes = set(nodes) seenmarkers = set() seennodes = set(pendingnodes) precursorsmarkers = self.predecessors succsmarkers = self.successors children = self.children while pendingnodes: direct = set() for current in pendingnodes: direct.update(precursorsmarkers.get(current, ())) pruned = [m for m in children.get(current, ()) if not m[1]] direct.update(pruned) pruned = [m for m in succsmarkers.get(current, ()) if not m[1]] direct.update(pruned) direct -= seenmarkers pendingnodes = set([m[0] for m in direct]) seenmarkers |= direct pendingnodes -= seennodes seennodes |= pendingnodes return seenmarkers # successors set move from mercurial.obsolete to mercurial.obsutil in 4.3 def successorssets(*args, **kwargs): func = getattr(obsutil, 'successorssets', None) if func is None: func = obsolete.successorssets return func(*args, **kwargs) # allprecursors set move from mercurial.obsolete to mercurial.obsutil in 4.3 # allprecursors was renamed into allpredecessors in 4.4 def allprecursors(*args, **kwargs): func = getattr(obsutil, 'allpredecessors', None) if func is None: func = getattr(obsutil, 'allprecursors', None) if func is None: func = obsolete.allprecursors return func(*args, **kwargs) # compatibility layer for mercurial < 4.3 def bookmarkapplychanges(repo, tr, changes): """Apply a list of changes to bookmarks """ bookmarks = repo._bookmarks if util.safehasattr(bookmarks, 'applychanges'): return bookmarks.applychanges(repo, tr, changes) for name, node in changes: if node is None: del bookmarks[name] else: bookmarks[name] = node bookmarks.recordchange(tr) def isobsnotesupported(): # hack to know obsnote is supported. The patches for obsnote support was # pushed before the obsfateprinter patches, so this will serve as a good # check if not obsutil: return False return util.safehasattr(obsutil, 'obsfateprinter') # Evolution renaming compat TROUBLES = {} if not util.safehasattr(context.basectx, 'orphan'): TROUBLES['ORPHAN'] = 'unstable' context.basectx.orphan = context.basectx.unstable else: TROUBLES['ORPHAN'] = 'orphan' if not util.safehasattr(context.basectx, 'contentdivergent'): TROUBLES['CONTENTDIVERGENT'] = 'divergent' context.basectx.contentdivergent = context.basectx.divergent else: TROUBLES['CONTENTDIVERGENT'] = 'content-divergent' if not util.safehasattr(context.basectx, 'phasedivergent'): TROUBLES['PHASEDIVERGENT'] = 'bumped' context.basectx.phasedivergent = context.basectx.bumped else: TROUBLES['PHASEDIVERGENT'] = 'phase-divergent' if not util.safehasattr(context.basectx, 'isunstable'): context.basectx.isunstable = context.basectx.troubled if not util.safehasattr(revset, 'orphan'): @eh.revset('orphan') def oprhanrevset(*args, **kwargs): return revset.unstable(*args, **kwargs) if not util.safehasattr(revset, 'contentdivergent'): @eh.revset('contentdivergent') def contentdivergentrevset(*args, **kwargs): return revset.divergent(*args, **kwargs) if not util.safehasattr(revset, 'phasedivergent'): @eh.revset('phasedivergent') def phasedivergentrevset(*args, **kwargs): return revset.bumped(*args, **kwargs) if not util.safehasattr(context.basectx, 'instabilities'): def instabilities(self): """return the list of instabilities affecting this changeset. Instabilities are returned as strings. possible values are: - orphan, - phase-divergent, - content-divergent. """ instabilities = [] if self.orphan(): instabilities.append('orphan') if self.phasedivergent(): instabilities.append('phase-divergent') if self.contentdivergent(): instabilities.append('content-divergent') return instabilities context.basectx.instabilities = instabilities # XXX: Better detection of property cache if 'predecessors' not in dir(obsolete.obsstore): @property def predecessors(self): return self.precursors obsolete.obsstore.predecessors = predecessors if not util.safehasattr(obsolete, '_computeorphanset'): obsolete._computeorphanset = obsolete.cachefor('orphan')(obsolete._computeunstableset) if not util.safehasattr(obsolete, '_computecontentdivergentset'): obsolete._computecontentdivergentset = obsolete.cachefor('contentdivergent')(obsolete._computedivergentset) if not util.safehasattr(obsolete, '_computephasedivergentset'): obsolete._computephasedivergentset = obsolete.cachefor('phasedivergent')(obsolete._computebumpedset) def startpager(ui, cmd): """function to start a pager in case ui.pager() exists""" if util.safehasattr(ui, 'pager'): ui.pager(cmd) def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None): # cannot use anything else until 4.3 support is dropped. assert wctx.rev() is None if copies.duplicatecopies.__code__.co_argcount < 5: # pre 4.4 duplicatecopies compat copies.duplicatecopies(repo, rev, fromrev, skiprev=skiprev) else: copies.duplicatecopies(repo, wctx, rev, fromrev, skiprev=skiprev) def memfilectx(repo, ctx, fctx, flags, copied, path): # XXX Would it be better at the module level? varnames = context.memfilectx.__init__.__code__.co_varnames ctxmandatory = varnames[2] == "changectx" if ctxmandatory: mctx = context.memfilectx(repo, ctx, fctx.path(), fctx.data(), islink='l' in flags, isexec='x' in flags, copied=copied.get(path)) else: mctx = context.memfilectx(repo, fctx.path(), fctx.data(), islink='l' in flags, isexec='x' in flags, copied=copied.get(path)) return mctx def getcachevfs(repo): cachevfs = getattr(repo, 'cachevfs', None) if cachevfs is None: cachevfs = vfsmod.vfs(repo.vfs.join('cache')) cachevfs.createmode = repo.store.createmode return cachevfs def strdiff(a, b, fn1, fn2): """ A version of mdiff.unidiff for comparing two strings """ args = [a, '', b, '', fn1, fn2] # hg < 4.6 compat 8b6dd3922f70 argspec = inspect.getargspec(mdiff.unidiff) if 'binary' in argspec.args: args.append(False) return mdiff.unidiff(*args) # date related try: import mercurial.utils.dateutil makedate = mercurial.utils.dateutil.makedate parsedate = mercurial.utils.dateutil.parsedate except ImportError as e: import mercurial.util makedate = mercurial.util.makedate parsedate = mercurial.util.parsedate def wireprotocommand(exthelper, name, args='', permission='pull'): if 3 <= len(wireproto.wireprotocommand.func_defaults): return wireproto.wireprotocommand(name, args, permission=permission) else: # <= hg-4.5 permission must be registered in dictionnary def decorator(func): @eh.extsetup def install(ui): hgweb_mod.perms[name] = permission wireproto.commands[name] = (func, args) return decorator