mercurial/revset.py
branchstable
changeset 12821 165079e564f0
parent 12815 079a618ea89d
child 12823 80deae3bc5ea
equal deleted inserted replaced
12820:0edc0aa7432d 12821:165079e564f0
   172     raise error.ParseError(_("not a function: %s") % a[1])
   172     raise error.ParseError(_("not a function: %s") % a[1])
   173 
   173 
   174 # functions
   174 # functions
   175 
   175 
   176 def node(repo, subset, x):
   176 def node(repo, subset, x):
       
   177     """``id(string)``
       
   178     Revision non-ambiguously specified by the given hex string prefix
       
   179     """
   177     # i18n: "id" is a keyword
   180     # i18n: "id" is a keyword
   178     l = getargs(x, 1, 1, _("id requires one argument"))
   181     l = getargs(x, 1, 1, _("id requires one argument"))
   179     # i18n: "id" is a keyword
   182     # i18n: "id" is a keyword
   180     n = getstring(l[0], _("id requires a string"))
   183     n = getstring(l[0], _("id requires a string"))
   181     if len(n) == 40:
   184     if len(n) == 40:
   183     else:
   186     else:
   184         rn = repo.changelog.rev(repo.changelog._partialmatch(n))
   187         rn = repo.changelog.rev(repo.changelog._partialmatch(n))
   185     return [r for r in subset if r == rn]
   188     return [r for r in subset if r == rn]
   186 
   189 
   187 def rev(repo, subset, x):
   190 def rev(repo, subset, x):
       
   191     """``rev(number)``
       
   192     Revision with the given numeric identifier.
       
   193     """
   188     # i18n: "rev" is a keyword
   194     # i18n: "rev" is a keyword
   189     l = getargs(x, 1, 1, _("rev requires one argument"))
   195     l = getargs(x, 1, 1, _("rev requires one argument"))
   190     try:
   196     try:
   191         # i18n: "rev" is a keyword
   197         # i18n: "rev" is a keyword
   192         l = int(getstring(l[0], _("rev requires a number")))
   198         l = int(getstring(l[0], _("rev requires a number")))
   194         # i18n: "rev" is a keyword
   200         # i18n: "rev" is a keyword
   195         raise error.ParseError(_("rev expects a number"))
   201         raise error.ParseError(_("rev expects a number"))
   196     return [r for r in subset if r == l]
   202     return [r for r in subset if r == l]
   197 
   203 
   198 def p1(repo, subset, x):
   204 def p1(repo, subset, x):
       
   205     """``p1(set)``
       
   206     First parent of changesets in set.
       
   207     """
   199     ps = set()
   208     ps = set()
   200     cl = repo.changelog
   209     cl = repo.changelog
   201     for r in getset(repo, range(len(repo)), x):
   210     for r in getset(repo, range(len(repo)), x):
   202         ps.add(cl.parentrevs(r)[0])
   211         ps.add(cl.parentrevs(r)[0])
   203     return [r for r in subset if r in ps]
   212     return [r for r in subset if r in ps]
   204 
   213 
   205 def p2(repo, subset, x):
   214 def p2(repo, subset, x):
       
   215     """``p2(set)``
       
   216     Second parent of changesets in set.
       
   217     """
   206     ps = set()
   218     ps = set()
   207     cl = repo.changelog
   219     cl = repo.changelog
   208     for r in getset(repo, range(len(repo)), x):
   220     for r in getset(repo, range(len(repo)), x):
   209         ps.add(cl.parentrevs(r)[1])
   221         ps.add(cl.parentrevs(r)[1])
   210     return [r for r in subset if r in ps]
   222     return [r for r in subset if r in ps]
   211 
   223 
   212 def parents(repo, subset, x):
   224 def parents(repo, subset, x):
       
   225     """``parents(set)``
       
   226     The set of all parents for all changesets in set.
       
   227     """
   213     ps = set()
   228     ps = set()
   214     cl = repo.changelog
   229     cl = repo.changelog
   215     for r in getset(repo, range(len(repo)), x):
   230     for r in getset(repo, range(len(repo)), x):
   216         ps.update(cl.parentrevs(r))
   231         ps.update(cl.parentrevs(r))
   217     return [r for r in subset if r in ps]
   232     return [r for r in subset if r in ps]
   218 
   233 
   219 def maxrev(repo, subset, x):
   234 def maxrev(repo, subset, x):
       
   235     """``max(set)``
       
   236     Changeset with highest revision number in set.
       
   237     """
   220     s = getset(repo, subset, x)
   238     s = getset(repo, subset, x)
   221     if s:
   239     if s:
   222         m = max(s)
   240         m = max(s)
   223         if m in subset:
   241         if m in subset:
   224             return [m]
   242             return [m]
   225     return []
   243     return []
   226 
   244 
   227 def minrev(repo, subset, x):
   245 def minrev(repo, subset, x):
       
   246     """``min(set)``
       
   247     Changeset with lowest revision number in set.
       
   248     """
   228     s = getset(repo, subset, x)
   249     s = getset(repo, subset, x)
   229     if s:
   250     if s:
   230         m = min(s)
   251         m = min(s)
   231         if m in subset:
   252         if m in subset:
   232             return [m]
   253             return [m]
   233     return []
   254     return []
   234 
   255 
   235 def limit(repo, subset, x):
   256 def limit(repo, subset, x):
       
   257     """``limit(set, n)``
       
   258     First n members of set.
       
   259     """
   236     # i18n: "limit" is a keyword
   260     # i18n: "limit" is a keyword
   237     l = getargs(x, 2, 2, _("limit requires two arguments"))
   261     l = getargs(x, 2, 2, _("limit requires two arguments"))
   238     try:
   262     try:
   239         # i18n: "limit" is a keyword
   263         # i18n: "limit" is a keyword
   240         lim = int(getstring(l[1], _("limit requires a number")))
   264         lim = int(getstring(l[1], _("limit requires a number")))
   242         # i18n: "limit" is a keyword
   266         # i18n: "limit" is a keyword
   243         raise error.ParseError(_("limit expects a number"))
   267         raise error.ParseError(_("limit expects a number"))
   244     return getset(repo, subset, l[0])[:lim]
   268     return getset(repo, subset, l[0])[:lim]
   245 
   269 
   246 def children(repo, subset, x):
   270 def children(repo, subset, x):
       
   271     """``children(set)``
       
   272     Child changesets of changesets in set.
       
   273     """
   247     cs = set()
   274     cs = set()
   248     cl = repo.changelog
   275     cl = repo.changelog
   249     s = set(getset(repo, range(len(repo)), x))
   276     s = set(getset(repo, range(len(repo)), x))
   250     for r in xrange(0, len(repo)):
   277     for r in xrange(0, len(repo)):
   251         for p in cl.parentrevs(r):
   278         for p in cl.parentrevs(r):
   252             if p in s:
   279             if p in s:
   253                 cs.add(r)
   280                 cs.add(r)
   254     return [r for r in subset if r in cs]
   281     return [r for r in subset if r in cs]
   255 
   282 
   256 def branch(repo, subset, x):
   283 def branch(repo, subset, x):
       
   284     """``branch(set)``
       
   285     All changesets belonging to the branches of changesets in set.
       
   286     """
   257     s = getset(repo, range(len(repo)), x)
   287     s = getset(repo, range(len(repo)), x)
   258     b = set()
   288     b = set()
   259     for r in s:
   289     for r in s:
   260         b.add(repo[r].branch())
   290         b.add(repo[r].branch())
   261     s = set(s)
   291     s = set(s)
   262     return [r for r in subset if r in s or repo[r].branch() in b]
   292     return [r for r in subset if r in s or repo[r].branch() in b]
   263 
   293 
   264 def ancestor(repo, subset, x):
   294 def ancestor(repo, subset, x):
       
   295     """``ancestor(single, single)``
       
   296     Greatest common ancestor of the two changesets.
       
   297     """
   265     # i18n: "ancestor" is a keyword
   298     # i18n: "ancestor" is a keyword
   266     l = getargs(x, 2, 2, _("ancestor requires two arguments"))
   299     l = getargs(x, 2, 2, _("ancestor requires two arguments"))
   267     r = range(len(repo))
   300     r = range(len(repo))
   268     a = getset(repo, r, l[0])
   301     a = getset(repo, r, l[0])
   269     b = getset(repo, r, l[1])
   302     b = getset(repo, r, l[1])
   273     an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
   306     an = [repo[a[0]].ancestor(repo[b[0]]).rev()]
   274 
   307 
   275     return [r for r in an if r in subset]
   308     return [r for r in an if r in subset]
   276 
   309 
   277 def ancestors(repo, subset, x):
   310 def ancestors(repo, subset, x):
       
   311     """``ancestors(set)``
       
   312     Changesets that are ancestors of a changeset in set.
       
   313     """
   278     args = getset(repo, range(len(repo)), x)
   314     args = getset(repo, range(len(repo)), x)
   279     if not args:
   315     if not args:
   280         return []
   316         return []
   281     s = set(repo.changelog.ancestors(*args)) | set(args)
   317     s = set(repo.changelog.ancestors(*args)) | set(args)
   282     return [r for r in subset if r in s]
   318     return [r for r in subset if r in s]
   283 
   319 
   284 def descendants(repo, subset, x):
   320 def descendants(repo, subset, x):
       
   321     """``descendants(set)``
       
   322     Changesets which are descendants of changesets in set.
       
   323     """
   285     args = getset(repo, range(len(repo)), x)
   324     args = getset(repo, range(len(repo)), x)
   286     if not args:
   325     if not args:
   287         return []
   326         return []
   288     s = set(repo.changelog.descendants(*args)) | set(args)
   327     s = set(repo.changelog.descendants(*args)) | set(args)
   289     return [r for r in subset if r in s]
   328     return [r for r in subset if r in s]
   290 
   329 
   291 def follow(repo, subset, x):
   330 def follow(repo, subset, x):
       
   331     """``follow()``
       
   332     An alias for ``::.`` (ancestors of the working copy's first parent).
       
   333     """
   292     # i18n: "follow" is a keyword
   334     # i18n: "follow" is a keyword
   293     getargs(x, 0, 0, _("follow takes no arguments"))
   335     getargs(x, 0, 0, _("follow takes no arguments"))
   294     p = repo['.'].rev()
   336     p = repo['.'].rev()
   295     s = set(repo.changelog.ancestors(p)) | set([p])
   337     s = set(repo.changelog.ancestors(p)) | set([p])
   296     return [r for r in subset if r in s]
   338     return [r for r in subset if r in s]
   297 
   339 
   298 def date(repo, subset, x):
   340 def date(repo, subset, x):
       
   341     """``date(interval)``
       
   342     Changesets within the interval, see :hg:`help dates`.
       
   343     """
   299     # i18n: "date" is a keyword
   344     # i18n: "date" is a keyword
   300     ds = getstring(x, _("date requires a string"))
   345     ds = getstring(x, _("date requires a string"))
   301     dm = util.matchdate(ds)
   346     dm = util.matchdate(ds)
   302     return [r for r in subset if dm(repo[r].date()[0])]
   347     return [r for r in subset if dm(repo[r].date()[0])]
   303 
   348 
   304 def keyword(repo, subset, x):
   349 def keyword(repo, subset, x):
       
   350     """``keyword(string)``
       
   351     Search commit message, user name, and names of changed files for
       
   352     string.
       
   353     """
   305     # i18n: "keyword" is a keyword
   354     # i18n: "keyword" is a keyword
   306     kw = getstring(x, _("keyword requires a string")).lower()
   355     kw = getstring(x, _("keyword requires a string")).lower()
   307     l = []
   356     l = []
   308     for r in subset:
   357     for r in subset:
   309         c = repo[r]
   358         c = repo[r]
   311         if kw in t.lower():
   360         if kw in t.lower():
   312             l.append(r)
   361             l.append(r)
   313     return l
   362     return l
   314 
   363 
   315 def grep(repo, subset, x):
   364 def grep(repo, subset, x):
       
   365     """``grep(regex)``
       
   366     Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')``
       
   367     to ensure special escape characters are handled correctly.
       
   368     """
   316     try:
   369     try:
   317         # i18n: "grep" is a keyword
   370         # i18n: "grep" is a keyword
   318         gr = re.compile(getstring(x, _("grep requires a string")))
   371         gr = re.compile(getstring(x, _("grep requires a string")))
   319     except re.error, e:
   372     except re.error, e:
   320         raise error.ParseError(_('invalid match pattern: %s') % e)
   373         raise error.ParseError(_('invalid match pattern: %s') % e)
   326                 l.append(r)
   379                 l.append(r)
   327                 continue
   380                 continue
   328     return l
   381     return l
   329 
   382 
   330 def author(repo, subset, x):
   383 def author(repo, subset, x):
       
   384     """``author(string)``
       
   385     Alias for ``user(string)``.
       
   386     """
   331     # i18n: "author" is a keyword
   387     # i18n: "author" is a keyword
   332     n = getstring(x, _("author requires a string")).lower()
   388     n = getstring(x, _("author requires a string")).lower()
   333     return [r for r in subset if n in repo[r].user().lower()]
   389     return [r for r in subset if n in repo[r].user().lower()]
   334 
   390 
       
   391 def user(repo, subset, x):
       
   392     """``user(string)``
       
   393     User name is string.
       
   394     """
       
   395     return author(repo, subset, x)
       
   396 
   335 def hasfile(repo, subset, x):
   397 def hasfile(repo, subset, x):
       
   398     """``file(pattern)``
       
   399     Changesets affecting files matched by pattern.
       
   400     """
   336     # i18n: "file" is a keyword
   401     # i18n: "file" is a keyword
   337     pat = getstring(x, _("file requires a pattern"))
   402     pat = getstring(x, _("file requires a pattern"))
   338     m = matchmod.match(repo.root, repo.getcwd(), [pat])
   403     m = matchmod.match(repo.root, repo.getcwd(), [pat])
   339     s = []
   404     s = []
   340     for r in subset:
   405     for r in subset:
   343                 s.append(r)
   408                 s.append(r)
   344                 continue
   409                 continue
   345     return s
   410     return s
   346 
   411 
   347 def contains(repo, subset, x):
   412 def contains(repo, subset, x):
       
   413     """``contains(pattern)``
       
   414     Revision contains pattern.
       
   415     """
   348     # i18n: "contains" is a keyword
   416     # i18n: "contains" is a keyword
   349     pat = getstring(x, _("contains requires a pattern"))
   417     pat = getstring(x, _("contains requires a pattern"))
   350     m = matchmod.match(repo.root, repo.getcwd(), [pat])
   418     m = matchmod.match(repo.root, repo.getcwd(), [pat])
   351     s = []
   419     s = []
   352     if m.files() == [pat]:
   420     if m.files() == [pat]:
   388                     s.append(r)
   456                     s.append(r)
   389                     continue
   457                     continue
   390     return s
   458     return s
   391 
   459 
   392 def modifies(repo, subset, x):
   460 def modifies(repo, subset, x):
       
   461     """``modifies(pattern)``
       
   462     Changesets modifying files matched by pattern.
       
   463     """
   393     # i18n: "modifies" is a keyword
   464     # i18n: "modifies" is a keyword
   394     pat = getstring(x, _("modifies requires a pattern"))
   465     pat = getstring(x, _("modifies requires a pattern"))
   395     return checkstatus(repo, subset, pat, 0)
   466     return checkstatus(repo, subset, pat, 0)
   396 
   467 
   397 def adds(repo, subset, x):
   468 def adds(repo, subset, x):
       
   469     """``adds(pattern)``
       
   470     Changesets that add a file matching pattern.
       
   471     """
   398     # i18n: "adds" is a keyword
   472     # i18n: "adds" is a keyword
   399     pat = getstring(x, _("adds requires a pattern"))
   473     pat = getstring(x, _("adds requires a pattern"))
   400     return checkstatus(repo, subset, pat, 1)
   474     return checkstatus(repo, subset, pat, 1)
   401 
   475 
   402 def removes(repo, subset, x):
   476 def removes(repo, subset, x):
       
   477     """``removes(pattern)``
       
   478     Changesets which remove files matching pattern.
       
   479     """
   403     # i18n: "removes" is a keyword
   480     # i18n: "removes" is a keyword
   404     pat = getstring(x, _("removes requires a pattern"))
   481     pat = getstring(x, _("removes requires a pattern"))
   405     return checkstatus(repo, subset, pat, 2)
   482     return checkstatus(repo, subset, pat, 2)
   406 
   483 
   407 def merge(repo, subset, x):
   484 def merge(repo, subset, x):
       
   485     """``merge()``
       
   486     Changeset is a merge changeset.
       
   487     """
   408     # i18n: "merge" is a keyword
   488     # i18n: "merge" is a keyword
   409     getargs(x, 0, 0, _("merge takes no arguments"))
   489     getargs(x, 0, 0, _("merge takes no arguments"))
   410     cl = repo.changelog
   490     cl = repo.changelog
   411     return [r for r in subset if cl.parentrevs(r)[1] != -1]
   491     return [r for r in subset if cl.parentrevs(r)[1] != -1]
   412 
   492 
   413 def closed(repo, subset, x):
   493 def closed(repo, subset, x):
       
   494     """``closed()``
       
   495     Changeset is closed.
       
   496     """
   414     # i18n: "closed" is a keyword
   497     # i18n: "closed" is a keyword
   415     getargs(x, 0, 0, _("closed takes no arguments"))
   498     getargs(x, 0, 0, _("closed takes no arguments"))
   416     return [r for r in subset if repo[r].extra().get('close')]
   499     return [r for r in subset if repo[r].extra().get('close')]
   417 
   500 
   418 def head(repo, subset, x):
   501 def head(repo, subset, x):
       
   502     """``head()``
       
   503     Changeset is a named branch head.
       
   504     """
   419     # i18n: "head" is a keyword
   505     # i18n: "head" is a keyword
   420     getargs(x, 0, 0, _("head takes no arguments"))
   506     getargs(x, 0, 0, _("head takes no arguments"))
   421     hs = set()
   507     hs = set()
   422     for b, ls in repo.branchmap().iteritems():
   508     for b, ls in repo.branchmap().iteritems():
   423         hs.update(repo[h].rev() for h in ls)
   509         hs.update(repo[h].rev() for h in ls)
   424     return [r for r in subset if r in hs]
   510     return [r for r in subset if r in hs]
   425 
   511 
   426 def reverse(repo, subset, x):
   512 def reverse(repo, subset, x):
       
   513     """``reverse(set)``
       
   514     Reverse order of set.
       
   515     """
   427     l = getset(repo, subset, x)
   516     l = getset(repo, subset, x)
   428     l.reverse()
   517     l.reverse()
   429     return l
   518     return l
   430 
   519 
   431 def present(repo, subset, x):
   520 def present(repo, subset, x):
       
   521     """``present(set)``
       
   522     An empty set, if any revision in set isn't found; otherwise,
       
   523     all revisions in set.
       
   524     """
   432     try:
   525     try:
   433         return getset(repo, subset, x)
   526         return getset(repo, subset, x)
   434     except error.RepoLookupError:
   527     except error.RepoLookupError:
   435         return []
   528         return []
   436 
   529 
   437 def sort(repo, subset, x):
   530 def sort(repo, subset, x):
       
   531     """``sort(set[, [-]key...])``
       
   532     Sort set by keys. The default sort order is ascending, specify a key
       
   533     as ``-key`` to sort in descending order.
       
   534 
       
   535     The keys can be:
       
   536 
       
   537     - ``rev`` for the revision number,
       
   538     - ``branch`` for the branch name,
       
   539     - ``desc`` for the commit message (description),
       
   540     - ``user`` for user name (``author`` can be used as an alias),
       
   541     - ``date`` for the commit date
       
   542     """
   438     # i18n: "sort" is a keyword
   543     # i18n: "sort" is a keyword
   439     l = getargs(x, 1, 2, _("sort requires one or two arguments"))
   544     l = getargs(x, 1, 2, _("sort requires one or two arguments"))
   440     keys = "rev"
   545     keys = "rev"
   441     if len(l) == 2:
   546     if len(l) == 2:
   442         keys = getstring(l[1], _("sort spec must be a string"))
   547         keys = getstring(l[1], _("sort spec must be a string"))
   476         l.append(e)
   581         l.append(e)
   477     l.sort()
   582     l.sort()
   478     return [e[-1] for e in l]
   583     return [e[-1] for e in l]
   479 
   584 
   480 def getall(repo, subset, x):
   585 def getall(repo, subset, x):
       
   586     """``all()``
       
   587     All changesets, the same as ``0:tip``.
       
   588     """
   481     # i18n: "all" is a keyword
   589     # i18n: "all" is a keyword
   482     getargs(x, 0, 0, _("all takes no arguments"))
   590     getargs(x, 0, 0, _("all takes no arguments"))
   483     return subset
   591     return subset
   484 
   592 
   485 def heads(repo, subset, x):
   593 def heads(repo, subset, x):
       
   594     """``heads(set)``
       
   595     Members of set with no children in set.
       
   596     """
   486     s = getset(repo, subset, x)
   597     s = getset(repo, subset, x)
   487     ps = set(parents(repo, subset, x))
   598     ps = set(parents(repo, subset, x))
   488     return [r for r in s if r not in ps]
   599     return [r for r in s if r not in ps]
   489 
   600 
   490 def roots(repo, subset, x):
   601 def roots(repo, subset, x):
       
   602     """``roots(set)``
       
   603     Changesets with no parent changeset in set.
       
   604     """
   491     s = getset(repo, subset, x)
   605     s = getset(repo, subset, x)
   492     cs = set(children(repo, subset, x))
   606     cs = set(children(repo, subset, x))
   493     return [r for r in s if r not in cs]
   607     return [r for r in s if r not in cs]
   494 
   608 
   495 def outgoing(repo, subset, x):
   609 def outgoing(repo, subset, x):
       
   610     """``outgoing([path])``
       
   611     Changesets not found in the specified destination repository, or the
       
   612     default push location.
       
   613     """
   496     import hg # avoid start-up nasties
   614     import hg # avoid start-up nasties
   497     # i18n: "outgoing" is a keyword
   615     # i18n: "outgoing" is a keyword
   498     l = getargs(x, 0, 1, _("outgoing requires a repository path"))
   616     l = getargs(x, 0, 1, _("outgoing requires a repository path"))
   499     # i18n: "outgoing" is a keyword
   617     # i18n: "outgoing" is a keyword
   500     dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
   618     dest = l and getstring(l[0], _("outgoing requires a repository path")) or ''
   510     cl = repo.changelog
   628     cl = repo.changelog
   511     o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, revs)[0]])
   629     o = set([cl.rev(r) for r in repo.changelog.nodesbetween(o, revs)[0]])
   512     return [r for r in subset if r in o]
   630     return [r for r in subset if r in o]
   513 
   631 
   514 def tag(repo, subset, x):
   632 def tag(repo, subset, x):
       
   633     """``tag(name)``
       
   634     The specified tag by name, or all tagged revisions if no name is given.
       
   635     """
   515     # i18n: "tag" is a keyword
   636     # i18n: "tag" is a keyword
   516     args = getargs(x, 0, 1, _("tag takes one or no arguments"))
   637     args = getargs(x, 0, 1, _("tag takes one or no arguments"))
   517     cl = repo.changelog
   638     cl = repo.changelog
   518     if args:
   639     if args:
   519         tn = getstring(args[0],
   640         tn = getstring(args[0],
   521                        _('the argument to tag must be a string'))
   642                        _('the argument to tag must be a string'))
   522         s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
   643         s = set([cl.rev(n) for t, n in repo.tagslist() if t == tn])
   523     else:
   644     else:
   524         s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
   645         s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip'])
   525     return [r for r in subset if r in s]
   646     return [r for r in subset if r in s]
       
   647 
       
   648 def tagged(repo, subset, x):
       
   649     return tag(repo, subset, x)
   526 
   650 
   527 symbols = {
   651 symbols = {
   528     "adds": adds,
   652     "adds": adds,
   529     "all": getall,
   653     "all": getall,
   530     "ancestor": ancestor,
   654     "ancestor": ancestor,
   557     "reverse": reverse,
   681     "reverse": reverse,
   558     "rev": rev,
   682     "rev": rev,
   559     "roots": roots,
   683     "roots": roots,
   560     "sort": sort,
   684     "sort": sort,
   561     "tag": tag,
   685     "tag": tag,
   562     "tagged": tag,
   686     "tagged": tagged,
   563     "user": author,
   687     "user": user,
   564 }
   688 }
   565 
   689 
   566 methods = {
   690 methods = {
   567     "range": rangeset,
   691     "range": rangeset,
   568     "string": stringset,
   692     "string": stringset,
   651     tree = parse(spec)
   775     tree = parse(spec)
   652     weight, tree = optimize(tree, True)
   776     weight, tree = optimize(tree, True)
   653     def mfunc(repo, subset):
   777     def mfunc(repo, subset):
   654         return getset(repo, subset, tree)
   778         return getset(repo, subset, tree)
   655     return mfunc
   779     return mfunc
       
   780 
       
   781 def makedoc(topic, doc):
       
   782     """Generate and include predicates help in revsets topic."""
       
   783     predicates = []
       
   784     for name in sorted(symbols):
       
   785         text = symbols[name].__doc__
       
   786         if not text:
       
   787             continue
       
   788         lines = text.splitlines()
       
   789         lines[1:] = [('  ' + l.strip()) for l in lines[1:]]
       
   790         predicates.append('\n'.join(lines))
       
   791     predicates = '\n'.join(predicates)
       
   792     doc = doc.replace('.. predicatesmarker', predicates)
       
   793     return doc