diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2029,6 +2029,8 @@ def help_(ui, name=None, with_version=Fa ui.write(_('use "hg help extensions" for information on enabling ' 'extensions\n')) + help.addtopichook('revsets', revset.makedoc) + if name and name != 'shortlist': i = None if unknowncmd: diff --git a/mercurial/help/revsets.txt b/mercurial/help/revsets.txt --- a/mercurial/help/revsets.txt +++ b/mercurial/help/revsets.txt @@ -45,123 +45,7 @@ These are the supported infix operators: The following predicates are supported: -``adds(pattern)`` - Changesets that add a file matching pattern. - -``all()`` - All changesets, the same as ``0:tip``. - -``ancestor(single, single)`` - Greatest common ancestor of the two changesets. - -``ancestors(set)`` - Changesets that are ancestors of a changeset in set. - -``author(string)`` - Alias for ``user(string)``. - -``branch(set)`` - All changesets belonging to the branches of changesets in set. - -``children(set)`` - Child changesets of changesets in set. - -``closed()`` - Changeset is closed. - -``contains(pattern)`` - Revision contains pattern. - -``date(interval)`` - Changesets within the interval, see :hg:`help dates`. - -``descendants(set)`` - Changesets which are descendants of changesets in set. - -``file(pattern)`` - Changesets affecting files matched by pattern. - -``follow()`` - An alias for ``::.`` (ancestors of the working copy's first parent). - -``grep(regex)`` - Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')`` - to ensure special escape characters are handled correctly. - -``head()`` - Changeset is a named branch head. - -``heads(set)`` - Members of set with no children in set. - -``id(string)`` - Revision non-ambiguously specified by the given hex string prefix - -``keyword(string)`` - Search commit message, user name, and names of changed files for - string. - -``limit(set, n)`` - First n members of set. - -``max(set)`` - Changeset with highest revision number in set. - -``min(set)`` - Changeset with lowest revision number in set. - -``merge()`` - Changeset is a merge changeset. - -``modifies(pattern)`` - Changesets modifying files matched by pattern. - -``outgoing([path])`` - Changesets not found in the specified destination repository, or the - default push location. - -``p1(set)`` - First parent of changesets in set. - -``p2(set)`` - Second parent of changesets in set. - -``parents(set)`` - The set of all parents for all changesets in set. - -``present(set)`` - An empty set, if any revision in set isn't found; otherwise, - all revisions in set. - -``removes(pattern)`` - Changesets which remove files matching pattern. - -``rev(number)`` - Revision with the given numeric identifier. - -``reverse(set)`` - Reverse order of set. - -``roots(set)`` - Changesets with no parent changeset in set. - -``sort(set[, [-]key...])`` - Sort set by keys. The default sort order is ascending, specify a key - as ``-key`` to sort in descending order. - - The keys can be: - - - ``rev`` for the revision number, - - ``branch`` for the branch name, - - ``desc`` for the commit message (description), - - ``user`` for user name (``author`` can be used as an alias), - - ``date`` for the commit date - -``tag(name)`` - The specified tag by name, or all tagged revisions if no name is given. - -``user(string)`` - User name is string. +.. predicatesmarker Command line equivalents for :hg:`log`:: diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -174,6 +174,9 @@ def func(repo, subset, a, b): # functions def node(repo, subset, x): + """``id(string)`` + Revision non-ambiguously specified by the given hex string prefix + """ # i18n: "id" is a keyword l = getargs(x, 1, 1, _("id requires one argument")) # i18n: "id" is a keyword @@ -185,6 +188,9 @@ def node(repo, subset, x): return [r for r in subset if r == rn] def rev(repo, subset, x): + """``rev(number)`` + Revision with the given numeric identifier. + """ # i18n: "rev" is a keyword l = getargs(x, 1, 1, _("rev requires one argument")) try: @@ -196,6 +202,9 @@ def rev(repo, subset, x): return [r for r in subset if r == l] def p1(repo, subset, x): + """``p1(set)`` + First parent of changesets in set. + """ ps = set() cl = repo.changelog for r in getset(repo, range(len(repo)), x): @@ -203,6 +212,9 @@ def p1(repo, subset, x): return [r for r in subset if r in ps] def p2(repo, subset, x): + """``p2(set)`` + Second parent of changesets in set. + """ ps = set() cl = repo.changelog for r in getset(repo, range(len(repo)), x): @@ -210,6 +222,9 @@ def p2(repo, subset, x): return [r for r in subset if r in ps] def parents(repo, subset, x): + """``parents(set)`` + The set of all parents for all changesets in set. + """ ps = set() cl = repo.changelog for r in getset(repo, range(len(repo)), x): @@ -217,6 +232,9 @@ def parents(repo, subset, x): return [r for r in subset if r in ps] def maxrev(repo, subset, x): + """``max(set)`` + Changeset with highest revision number in set. + """ s = getset(repo, subset, x) if s: m = max(s) @@ -225,6 +243,9 @@ def maxrev(repo, subset, x): return [] def minrev(repo, subset, x): + """``min(set)`` + Changeset with lowest revision number in set. + """ s = getset(repo, subset, x) if s: m = min(s) @@ -233,6 +254,9 @@ def minrev(repo, subset, x): return [] def limit(repo, subset, x): + """``limit(set, n)`` + First n members of set. + """ # i18n: "limit" is a keyword l = getargs(x, 2, 2, _("limit requires two arguments")) try: @@ -244,6 +268,9 @@ def limit(repo, subset, x): return getset(repo, subset, l[0])[:lim] def children(repo, subset, x): + """``children(set)`` + Child changesets of changesets in set. + """ cs = set() cl = repo.changelog s = set(getset(repo, range(len(repo)), x)) @@ -254,6 +281,9 @@ def children(repo, subset, x): return [r for r in subset if r in cs] def branch(repo, subset, x): + """``branch(set)`` + All changesets belonging to the branches of changesets in set. + """ s = getset(repo, range(len(repo)), x) b = set() for r in s: @@ -262,6 +292,9 @@ def branch(repo, subset, x): return [r for r in subset if r in s or repo[r].branch() in b] def ancestor(repo, subset, x): + """``ancestor(single, single)`` + Greatest common ancestor of the two changesets. + """ # i18n: "ancestor" is a keyword l = getargs(x, 2, 2, _("ancestor requires two arguments")) r = range(len(repo)) @@ -275,6 +308,9 @@ def ancestor(repo, subset, x): return [r for r in an if r in subset] def ancestors(repo, subset, x): + """``ancestors(set)`` + Changesets that are ancestors of a changeset in set. + """ args = getset(repo, range(len(repo)), x) if not args: return [] @@ -282,6 +318,9 @@ def ancestors(repo, subset, x): return [r for r in subset if r in s] def descendants(repo, subset, x): + """``descendants(set)`` + Changesets which are descendants of changesets in set. + """ args = getset(repo, range(len(repo)), x) if not args: return [] @@ -289,6 +328,9 @@ def descendants(repo, subset, x): return [r for r in subset if r in s] def follow(repo, subset, x): + """``follow()`` + An alias for ``::.`` (ancestors of the working copy's first parent). + """ # i18n: "follow" is a keyword getargs(x, 0, 0, _("follow takes no arguments")) p = repo['.'].rev() @@ -296,12 +338,19 @@ def follow(repo, subset, x): return [r for r in subset if r in s] def date(repo, subset, x): + """``date(interval)`` + Changesets within the interval, see :hg:`help dates`. + """ # i18n: "date" is a keyword ds = getstring(x, _("date requires a string")) dm = util.matchdate(ds) return [r for r in subset if dm(repo[r].date()[0])] def keyword(repo, subset, x): + """``keyword(string)`` + Search commit message, user name, and names of changed files for + string. + """ # i18n: "keyword" is a keyword kw = getstring(x, _("keyword requires a string")).lower() l = [] @@ -313,6 +362,10 @@ def keyword(repo, subset, x): return l def grep(repo, subset, x): + """``grep(regex)`` + Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')`` + to ensure special escape characters are handled correctly. + """ try: # i18n: "grep" is a keyword gr = re.compile(getstring(x, _("grep requires a string"))) @@ -328,11 +381,23 @@ def grep(repo, subset, x): return l def author(repo, subset, x): + """``author(string)`` + Alias for ``user(string)``. + """ # i18n: "author" is a keyword n = getstring(x, _("author requires a string")).lower() return [r for r in subset if n in repo[r].user().lower()] +def user(repo, subset, x): + """``user(string)`` + User name is string. + """ + return author(repo, subset, x) + def hasfile(repo, subset, x): + """``file(pattern)`` + Changesets affecting files matched by pattern. + """ # i18n: "file" is a keyword pat = getstring(x, _("file requires a pattern")) m = matchmod.match(repo.root, repo.getcwd(), [pat]) @@ -345,6 +410,9 @@ def hasfile(repo, subset, x): return s def contains(repo, subset, x): + """``contains(pattern)`` + Revision contains pattern. + """ # i18n: "contains" is a keyword pat = getstring(x, _("contains requires a pattern")) m = matchmod.match(repo.root, repo.getcwd(), [pat]) @@ -390,32 +458,50 @@ def checkstatus(repo, subset, pat, field return s def modifies(repo, subset, x): + """``modifies(pattern)`` + Changesets modifying files matched by pattern. + """ # i18n: "modifies" is a keyword pat = getstring(x, _("modifies requires a pattern")) return checkstatus(repo, subset, pat, 0) def adds(repo, subset, x): + """``adds(pattern)`` + Changesets that add a file matching pattern. + """ # i18n: "adds" is a keyword pat = getstring(x, _("adds requires a pattern")) return checkstatus(repo, subset, pat, 1) def removes(repo, subset, x): + """``removes(pattern)`` + Changesets which remove files matching pattern. + """ # i18n: "removes" is a keyword pat = getstring(x, _("removes requires a pattern")) return checkstatus(repo, subset, pat, 2) def merge(repo, subset, x): + """``merge()`` + Changeset is a merge changeset. + """ # i18n: "merge" is a keyword getargs(x, 0, 0, _("merge takes no arguments")) cl = repo.changelog return [r for r in subset if cl.parentrevs(r)[1] != -1] def closed(repo, subset, x): + """``closed()`` + Changeset is closed. + """ # i18n: "closed" is a keyword getargs(x, 0, 0, _("closed takes no arguments")) return [r for r in subset if repo[r].extra().get('close')] def head(repo, subset, x): + """``head()`` + Changeset is a named branch head. + """ # i18n: "head" is a keyword getargs(x, 0, 0, _("head takes no arguments")) hs = set() @@ -424,17 +510,36 @@ def head(repo, subset, x): return [r for r in subset if r in hs] def reverse(repo, subset, x): + """``reverse(set)`` + Reverse order of set. + """ l = getset(repo, subset, x) l.reverse() return l def present(repo, subset, x): + """``present(set)`` + An empty set, if any revision in set isn't found; otherwise, + all revisions in set. + """ try: return getset(repo, subset, x) except error.RepoLookupError: return [] def sort(repo, subset, x): + """``sort(set[, [-]key...])`` + Sort set by keys. The default sort order is ascending, specify a key + as ``-key`` to sort in descending order. + + The keys can be: + + - ``rev`` for the revision number, + - ``branch`` for the branch name, + - ``desc`` for the commit message (description), + - ``user`` for user name (``author`` can be used as an alias), + - ``date`` for the commit date + """ # i18n: "sort" is a keyword l = getargs(x, 1, 2, _("sort requires one or two arguments")) keys = "rev" @@ -478,21 +583,34 @@ def sort(repo, subset, x): return [e[-1] for e in l] def getall(repo, subset, x): + """``all()`` + All changesets, the same as ``0:tip``. + """ # i18n: "all" is a keyword getargs(x, 0, 0, _("all takes no arguments")) return subset def heads(repo, subset, x): + """``heads(set)`` + Members of set with no children in set. + """ s = getset(repo, subset, x) ps = set(parents(repo, subset, x)) return [r for r in s if r not in ps] def roots(repo, subset, x): + """``roots(set)`` + Changesets with no parent changeset in set. + """ s = getset(repo, subset, x) cs = set(children(repo, subset, x)) return [r for r in s if r not in cs] def outgoing(repo, subset, x): + """``outgoing([path])`` + Changesets not found in the specified destination repository, or the + default push location. + """ import hg # avoid start-up nasties # i18n: "outgoing" is a keyword l = getargs(x, 0, 1, _("outgoing requires a repository path")) @@ -512,6 +630,9 @@ def outgoing(repo, subset, x): return [r for r in subset if r in o] def tag(repo, subset, x): + """``tag(name)`` + The specified tag by name, or all tagged revisions if no name is given. + """ # i18n: "tag" is a keyword args = getargs(x, 0, 1, _("tag takes one or no arguments")) cl = repo.changelog @@ -524,6 +645,9 @@ def tag(repo, subset, x): s = set([cl.rev(n) for t, n in repo.tagslist() if t != 'tip']) return [r for r in subset if r in s] +def tagged(repo, subset, x): + return tag(repo, subset, x) + symbols = { "adds": adds, "all": getall, @@ -559,8 +683,8 @@ symbols = { "roots": roots, "sort": sort, "tag": tag, - "tagged": tag, - "user": author, + "tagged": tagged, + "user": user, } methods = { @@ -653,3 +777,17 @@ def match(spec): def mfunc(repo, subset): return getset(repo, subset, tree) return mfunc + +def makedoc(topic, doc): + """Generate and include predicates help in revsets topic.""" + predicates = [] + for name in sorted(symbols): + text = symbols[name].__doc__ + if not text: + continue + lines = text.splitlines() + lines[1:] = [(' ' + l.strip()) for l in lines[1:]] + predicates.append('\n'.join(lines)) + predicates = '\n'.join(predicates) + doc = doc.replace('.. predicatesmarker', predicates) + return doc