obshistory: add _predecessorsverb() similar to _successorsetverb()
from__future__importabsolute_importfrommercurialimport(error,registrar,revset,util,)from.import(destination,stack,)try:mkmatcher=revset._stringmatcherexceptAttributeError:try:frommercurial.utilsimportstringutilmkmatcher=stringutil.stringmatcherexcept(ImportError,AttributeError):mkmatcher=util.stringmatcherrevsetpredicate=registrar.revsetpredicate()defgetstringstrict(x,err):ifxandx[0]==b'string':returnx[1]raiseerror.ParseError(err)@revsetpredicate(b'topic([string or set])')deftopicset(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. If `string` starts with `re:` the remainder of the name is treated as a regular expression. """args=revset.getargs(x,0,1,b'topic takes one or no arguments')mutable=revset._notpublic(repo,revset.fullreposet(repo),())ifnotargs:return(subset&mutable).filter(lambdar:bool(repo[r].topic()))try:topic=getstringstrict(args[0],b'')excepterror.ParseError:# not a string, but another revsetpasselse:kind,pattern,matcher=mkmatcher(topic)iftopic.startswith(b'literal:')andpatternnotinrepo.topics:raiseerror.RepoLookupError(b"topic '%s' does not exist"%pattern)defmatches(r):topic=repo[r].topic()ifnottopic:returnFalsereturnmatcher(topic)return(subset&mutable).filter(matches)s=revset.getset(repo,revset.fullreposet(repo),x)topics={repo[r].topic()forrins}topics.discard(b'')defmatches(r):ifrins:returnTruetopic=repo[r].topic()ifnottopic:returnFalsereturntopicintopicsreturn(subset&mutable).filter(matches)@revsetpredicate(b'ngtip([branch])')defngtipset(repo,subset,x):"""The untopiced tip. Name is horrible so that people change it. """args=revset.getargs(x,1,1,b'ngtip takes one argument')# match a specific topicbranch=revset.getstring(args[0],b'ngtip requires a string')ifbranch==b'.':branch=repo[b'.'].branch()returnsubset&revset.baseset(destination.ngtip(repo,branch))@revsetpredicate(b'stack()')defstackset(repo,subset,x):"""All relevant changes in the current topic, This is roughly equivalent to 'topic(.) - obsolete' with a sorting moving unstable changeset after there future parent (as if evolve where already run). """err=b'stack takes no arguments, it works on current topic'revset.getargs(x,0,0,err)topic=Nonebranch=Noneifrepo.currenttopic:topic=repo.currenttopicelse:branch=repo[None].branch()returnrevset.baseset(stack.stack(repo,branch=branch,topic=topic)[1:])&subsetifutil.safehasattr(revset,'subscriptrelations'):defstackrel(repo,subset,x,rel,z,order):"""This is a revset-flavored implementation of stack aliases. The syntax is: rev#stack[n] or rev#s[n]. Plenty of logic is borrowed from topic._namemap, but unlike that function, which prefers to abort (e.g. when stack index is too high), this returns empty set to be more revset-friendly. """# hg 4.9 provides a number or None, hg 5.0 provides a tuple of tokensifisinstance(z,tuple):a,b=revset.getintrange(z,b'relation subscript must be an integer or a range',b'relation subscript bounds must be integers',None,None)else:# hg <= 4.9 (431cf2c8c839+13f7a6a4f0db)a=b=zs=revset.getset(repo,revset.fullreposet(repo),x)ifnots:returnrevset.baseset()defgetrange(st,a,b):start=1ifaisNoneelseaend=len(st.revs)ifbisNoneelseb+1returnrange(start,end)revs=[]forrins:topic=repo[r].topic()iftopic:st=stack.stack(repo,topic=topic)else:st=stack.stack(repo,branch=repo[r].branch())forningetrange(st,a,b):ifabs(n)>=len(st.revs):# also means stack base is not accessible with n < 0, which# is by designcontinueifn==0andb!=0anda!=0:# quirk: we don't want stack base unless specifically asked# for it (at least one of the indices is 0)continuerev=st.revs[n]ifrev==-1andn==0:continueifrevnotinrevs:revs.append(rev)returnsubset&revset.baseset(revs)revset.subscriptrelations[b'stack']=stackrelrevset.subscriptrelations[b's']=stackreldeftopicrel(repo,subset,x,*args):subset&=topicset(repo,subset,x)# not using revset.generationssubrel directly because it was renamed# hg <= 5.3 (8859de3e83dc)generationssubrel=revset.subscriptrelations[b'generations']returngenerationssubrel(repo,subset,x,*args)revset.subscriptrelations[b'topic']=topicrelrevset.subscriptrelations[b't']=topicrel