[PATCH 2 of 2] graphlog: Enable revesets and log options via revsets with meaningful graph

Klaus Koch kuk42 at gmx.net
Wed Dec 15 14:52:22 CST 2010


Fix of minor bugs in build_revset ...

# HG changeset patch
# User Klaus Koch <kuk42 at gmx.net>
# Date 1292418717 -3600
# Node ID c5ffe68a71286ec7699184958239c928d13fd74b
# Parent  78934813e51e262a7d4d6e1b0b4dcdca3fa679c0
graphlog: Enable revsets and build revset out of log options and multiple FILE

Shows old behavior in case only old-style revs are given and no
formerly unsupported log option is used.  In case formerly unsupported
log options, multiple FILE patterns, or revsets are given, a revset is
built out of them all.  The -l/--limit option is never incorporated
into the final revset.

Revsets can yield sets of changesets with gaps between changesets,
e.g. if a file was changed both in revs a and d, the revisions b and c
in-between are not printed.  In such cases, the next topological
parent within the revset is searched and the connection to it is
printed in the ascii graph.

If more than one FILE is given, a revset is built (-r 'file(FILE1) and
file(FILE2)').  A revset graph may show more connections, because the
graph is produced according the revset, not according a file's
filelog.
In case the graph contains several branches where the left parent is
null, the graphs for each are printed sequentially, not in parallel as
it would with a simple filelog (see for example the graph for README
in hg-dev).

diff --git a/hgext/graphlog.py b/hgext/graphlog.py
--- a/hgext/graphlog.py
+++ b/hgext/graphlog.py
@@ -13,7 +13,7 @@
 '''
 
 import os
-from mercurial.cmdutil import revrange, show_changeset
+from mercurial.cmdutil import revrange, show_changeset, revrangesep
 from mercurial.commands import templateopts
 from mercurial.i18n import _
 from mercurial.node import nullrev
@@ -216,13 +216,52 @@
         return (len(repo) - 1, 0)
 
 def check_unsupported_flags(opts):
-    for op in ["follow", "follow_first", "date", "copies", "keyword", "remove",
-               "only_merges", "user", "branch", "only_branch", "prune",
-               "newest_first", "no_merges", "include", "exclude"]:
+    for op in ["follow_first", "copies", "newest_first"]:
         if op in opts and opts[op]:
-            raise util.Abort(_("--graph option is incompatible with --%s")
+            raise util.Abort(_("-G/--graph option is incompatible with --%s")
                              % op.replace("_", "-"))
 
+def build_revset(path, opts):
+    """Return revset str built of revisions, log options and file patterns.
+
+    None is returned, in case only 'old style' revs are given, perhaps
+    with just one FILE.
+
+    The -l/--limit option is not incorporated into revset.
+    """
+    opt2revset = dict(only_merges='merge',
+                      only_branch='branch',
+                      no_merges='not merge',
+                      include='file',
+                      exclude='not file',
+                      prune='not follow')
+    revset = ''.join(
+        [' and '.join(['%s()' % opt2revset.get(op, op)
+                       for op in ("follow", "only_merges", "no_merges")
+                       if op in opts and opts[op]]),
+         ' and '.join(['%s(%s)' % (opt2revset.get(op, op), opts[op])
+                       for op in ("date", "keyword", "remove", "user",
+                                  "branch", "only_branch", "prune")
+                       if op in opts and opts[op]]),
+         ' and '.join(['%s(%r)' % (opt2revset.get(op, op), f)
+                       for op in ("include", "exclude")
+                       if op in opts and opts[op] for f in opts[op]])])
+
+    revs = opts['rev']
+    try:                    # only simple old style revsets?
+        [int(r) for rev in revs for r in rev.split(revrangesep)
+         if r not in ('', 'tip', 'null')]
+        return
+    except ValueError:
+        if revset:
+            revset = ' and '.join([' and '.join(revs), revset])
+        else:
+            revset = ' and '.join(revs)
+    if revset:
+        if path:
+            revset += ' and file(%r)' % path
+        return revset
+
 def generate(ui, dag, displayer, showparents, edgefn):
     seen, state = [], asciistate()
     for rev, type, ctx, parents in dag:
@@ -233,6 +272,78 @@
         ascii(ui, state, type, char, lines, edgefn(seen, rev, parents))
     displayer.close()
 
+def grandparent(cl, lowestrev, roots, head):
+    """Return closest 'root' rev in topological path from 'roots' to 'heads'.
+
+    Derived from revlog.revlog.nodesbetween, but only returns next rev
+    of topologically sorted list of all nodes N that satisfy of these
+    constraints:
+
+    1. N is a descendant of some node in 'roots'
+    2. N is an ancestor of some node in 'heads'
+    3. N is some node in 'roots' or nullrev
+
+    Every node is considered to be both a descendant and an ancestor
+    of itself, so every reachable node in 'roots' and 'heads' will be
+    included in 'nodes'."""
+    ancestors = set()
+    # Start at the top and keep marking parents until we're done.
+    revstotag = set([head])
+    revstotag.discard(nullrev)
+    llowestrev = max(nullrev, lowestrev)
+    while revstotag:
+        r = revstotag.pop()
+        # A node's revision number represents its place in a
+        # topologically sorted list of nodes.
+        if r > llowestrev:
+            if r not in ancestors:
+                # If we are possibly a descendent of one of the roots
+                # and we haven't already been marked as an ancestor
+                ancestors.add(r) # Mark as ancestor
+                # Add non-nullrev parents to list of nodes to tag.
+                revstotag.update([p for p in cl.parentrevs(r)])
+    if not ancestors:
+        return
+    # Now that we have our set of ancestors, we want to remove any
+    # roots that are not ancestors.
+
+    # If one of the roots was nullrev, everything is included anyway.
+    if lowestrev > nullrev:
+        # But, since we weren't, let's recompute the lowest rev to not
+        # include roots that aren't ancestors.
+
+        # Filter out roots that aren't ancestors of heads
+        _roots = ancestors.intersection(roots)
+        # Recompute the lowest revision
+        if _roots:
+            lowestrev = min(roots)
+        else:
+            return
+    else:
+        # We are descending from nullrev, and don't need to care about
+        # any other roots.
+        lowestrev = nullrev
+        _roots = [nullrev]
+
+    # The roots are just the descendants.
+    # Don't start at nullrev since we don't want nullrev in our output list,
+    # and if nullrev shows up in descedents, empty parents will look like
+    # they're descendents.
+    lowestrevisnullrev = (lowestrev == nullrev)
+    for r in xrange(head - 1, max(lowestrev, -1), -1):
+        if lowestrevisnullrev or r in _roots:
+            pass
+        elif _roots.issuperset(cl.parentrevs(r)):
+            # A node is a descendent if either of its parents are
+            # descendents.  (We seeded the dependents list with the roots
+            # up there, remember?)
+            _roots.add(r)
+        else:
+            continue
+        if r in ancestors:
+            # Only include nodes that are both descendents and ancestors.
+            return r
+
 def graphlog(ui, repo, path=None, **opts):
     """show revision history alongside an ASCII revision graph
 
@@ -245,18 +356,54 @@
 
     check_unsupported_flags(opts)
     limit = cmdutil.loglimit(opts)
-    start, stop = get_revs(repo, opts["rev"])
-    if start == nullrev:
-        return
+    revset = build_revset(path, opts)
+    ui.debug(_('built revset: %r\n') % revset)
 
     if path:
         path = util.canonpath(repo.root, os.getcwd(), path)
-    if path: # could be reset in canonpath
-        revdag = graphmod.filerevs(repo, path, start, stop, limit)
+    if not revset:
+        start, stop = get_revs(repo, opts["rev"])
+        if start == nullrev:
+            return
+        if path: # could be reset in canonpath
+            revdag = graphmod.filerevs(repo, path, start, stop, limit)
+        else:
+            if limit is not None:
+                stop = max(stop, start - limit + 1)
+            revdag = graphmod.revisions(repo, start, stop)
     else:
-        if limit is not None:
-            stop = max(stop, start - limit + 1)
-        revdag = graphmod.revisions(repo, start, stop)
+        c = set()
+        uc = [repo[r].node() for r in revrange(repo, [revset])
+              if r not in c and not c.add(r)]
+        if not uc:
+            return
+        if repo[uc[:1][0]].rev() > repo[uc[:2][-1]].rev():
+            uc.reverse()         # no reverse graph allowed
+        revdag = list(graphrevs(repo, uc, opts))
+        cl = repo.changelog
+        lowestrev = min(c)
+        leafs = {}
+        grandparentscache = {}
+        for i, r in enumerate(revdag):
+            n, pars = r[2], r[-1]
+            mpars = [p.rev() for p in n.parents() if p.rev() not in pars]
+            grandparents = []
+            for mpar in mpars:
+                gp = (grandparentscache.get(mpar) or
+                      grandparent(cl, lowestrev, c, mpar))
+                grandparentscache[mpar] = gp
+                if gp is None:
+                    leafs.setdefault(mpar, []).append((i, n))
+                else:
+                    grandparents.append(gp)
+            if grandparents:
+                revdag[i] = (r[0], r[1], n, revdag[i][-1]+grandparents)
+        # Check for common parents of lowest revs
+        for parent, leafs in leafs.iteritems():
+            if parent != nullrev:
+                for leaf in leafs:
+                    r = revdag[leaf[0]]
+                    revdag[leaf[0]] = (r[0], r[1], r[2], r[-1]+[parent])
 
     displayer = show_changeset(ui, repo, opts, buffered=True)
     showparents = [ctx.node() for ctx in repo[None].parents()]
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -678,6 +678,437 @@
      summary:     (0) root
   
 
+File glog per revset:
+  $ hg glog -r 'file("a")'
+  @  changeset:   34:fea3ac5810e0
+  |  tag:         tip
+  |  parent:      32:d06dffa21a31
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:34 1970 +0000
+  |  summary:     (34) head
+  |
+  | o  changeset:   33:68608f5145f9
+  | |  parent:      18:1aa84d96232a
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:33 1970 +0000
+  | |  summary:     (33) head
+  | |
+  o |    changeset:   32:d06dffa21a31
+  |\ \   parent:      27:886ed638191b
+  | | |  parent:      31:621d83e11f67
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | | |  summary:     (32) expand
+  | | |
+  | o |    changeset:   31:621d83e11f67
+  | |\ \   parent:      21:d42a756af44d
+  | | | |  parent:      30:6e11cd4b648f
+  | | | |  user:        test
+  | | | |  date:        Thu Jan 01 00:00:31 1970 +0000
+  | | | |  summary:     (31) expand
+  | | | |
+  | | o |    changeset:   30:6e11cd4b648f
+  | | |\ \   parent:      28:44ecd0b9ae99
+  | | | | |  parent:      29:cd9bb2be7593
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:30 1970 +0000
+  | | | | |  summary:     (30) expand
+  | | | | |
+  | | | o |  changeset:   29:cd9bb2be7593
+  | | | | |  parent:      0:e6eb3150255d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:29 1970 +0000
+  | | | | |  summary:     (29) regular commit
+  | | | | |
+  | | o | |    changeset:   28:44ecd0b9ae99
+  | | |\ \ \   parent:      1:6db2ef61d156
+  | | | | | |  parent:      26:7f25b6c2f0b9
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
+  | | | | | |  summary:     (28) merge zero known
+  | | | | | |
+  o | | | | |  changeset:   27:886ed638191b
+  |/ / / / /   parent:      21:d42a756af44d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:27 1970 +0000
+  | | | | |    summary:     (27) collapse
+  | | | | |
+  | | o---+  changeset:   26:7f25b6c2f0b9
+  | | | | |  parent:      18:1aa84d96232a
+  | | | | |  parent:      25:91da8ed57247
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
+  | | | | |  summary:     (26) merge one known; far right
+  | | | | |
+  +---o | |  changeset:   25:91da8ed57247
+  | | | | |  parent:      21:d42a756af44d
+  | | | | |  parent:      24:a9c19a3d96b7
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
+  | | | | |  summary:     (25) merge one known; far left
+  | | | | |
+  | | o | |  changeset:   24:a9c19a3d96b7
+  | | |\| |  parent:      0:e6eb3150255d
+  | | | | |  parent:      23:a01cddf0766d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
+  | | | | |  summary:     (24) merge one known; immediate right
+  | | | | |
+  | | o | |  changeset:   23:a01cddf0766d
+  | |/| | |  parent:      1:6db2ef61d156
+  | | | | |  parent:      22:e0d9cccacb5d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
+  | | | | |  summary:     (23) merge one known; immediate left
+  | | | | |
+  +---o---+  changeset:   22:e0d9cccacb5d
+  | |   | |  parent:      18:1aa84d96232a
+  | |  / /   parent:      21:d42a756af44d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:22 1970 +0000
+  | | | |    summary:     (22) merge two known; one far left, one far right
+  | | | |
+  o | | |    changeset:   21:d42a756af44d
+  |\ \ \ \   parent:      19:31ddc2c1573b
+  | | | | |  parent:      20:d30ed6450e32
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
+  | | | | |  summary:     (21) expand
+  | | | | |
+  | o---+-+  changeset:   20:d30ed6450e32
+  |   | | |  parent:      0:e6eb3150255d
+  |  / / /   parent:      18:1aa84d96232a
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:20 1970 +0000
+  | | | |    summary:     (20) merge two known; two far right
+  | | | |
+  o | | |    changeset:   19:31ddc2c1573b
+  |\ \ \ \   parent:      15:1dda3f72782d
+  | | | | |  parent:      17:44765d7c06e0
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
+  | | | | |  summary:     (19) expand
+  | | | | |
+  +---+---o  changeset:   18:1aa84d96232a
+  | | | |    parent:      1:6db2ef61d156
+  | | | |    parent:      15:1dda3f72782d
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:18 1970 +0000
+  | | | |    summary:     (18) merge two known; two far left
+  | | | |
+  | o | |    changeset:   17:44765d7c06e0
+  | |\ \ \   parent:      12:86b91144a6e9
+  | | | | |  parent:      16:3677d192927d
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
+  | | | | |  summary:     (17) expand
+  | | | | |
+  | | o---+  changeset:   16:3677d192927d
+  | | | | |  parent:      0:e6eb3150255d
+  | | |/ /   parent:      1:6db2ef61d156
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:16 1970 +0000
+  | | | |    summary:     (16) merge two known; one immediate right, one near right
+  | | | |
+  o | | |    changeset:   15:1dda3f72782d
+  |\ \ \ \   parent:      13:22d8966a97e3
+  | | | | |  parent:      14:8eac370358ef
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:15 1970 +0000
+  | | | | |  summary:     (15) expand
+  | | | | |
+  | o-----+  changeset:   14:8eac370358ef
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      12:86b91144a6e9
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:14 1970 +0000
+  | | | |    summary:     (14) merge two known; one immediate right, one far right
+  | | | |
+  o | | |    changeset:   13:22d8966a97e3
+  |\ \ \ \   parent:      9:7010c0af0a35
+  | | | | |  parent:      11:832d76e6bdf2
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:13 1970 +0000
+  | | | | |  summary:     (13) expand
+  | | | | |
+  +---o | |  changeset:   12:86b91144a6e9
+  | | |/ /   parent:      1:6db2ef61d156
+  | | | |    parent:      9:7010c0af0a35
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:12 1970 +0000
+  | | | |    summary:     (12) merge two known; one immediate right, one far left
+  | | | |
+  | o | |    changeset:   11:832d76e6bdf2
+  | |\ \ \   parent:      6:b105a072e251
+  | | | | |  parent:      10:74c64d036d72
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
+  | | | | |  summary:     (11) expand
+  | | | | |
+  | | o---+  changeset:   10:74c64d036d72
+  | | | | |  parent:      0:e6eb3150255d
+  | |/ / /   parent:      6:b105a072e251
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:10 1970 +0000
+  | | | |    summary:     (10) merge two known; one immediate left, one near right
+  | | | |
+  o | | |    changeset:   9:7010c0af0a35
+  |\ \ \ \   parent:      7:b632bb1b1224
+  | | | | |  parent:      8:7a0b11f71937
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | | | | |  summary:     (9) expand
+  | | | | |
+  | o-----+  changeset:   8:7a0b11f71937
+  | | | | |  parent:      0:e6eb3150255d
+  |/ / / /   parent:      7:b632bb1b1224
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:08 1970 +0000
+  | | | |    summary:     (8) merge two known; one immediate left, one far right
+  | | | |
+  o | | |    changeset:   7:b632bb1b1224
+  |\ \ \ \   parent:      2:3d9a33b8d1e1
+  | | | | |  parent:      5:4409d547b708
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
+  | | | | |  summary:     (7) expand
+  | | | | |
+  +---o | |  changeset:   6:b105a072e251
+  | |/ / /   parent:      2:3d9a33b8d1e1
+  | | | |    parent:      5:4409d547b708
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:06 1970 +0000
+  | | | |    summary:     (6) merge two known; one immediate left, one far left
+  | | | |
+  | o | |    changeset:   5:4409d547b708
+  | |\ \ \   parent:      3:27eef8ed80b4
+  | | | | |  parent:      4:26a8bac39d9f
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:05 1970 +0000
+  | | | | |  summary:     (5) expand
+  | | | | |
+  | | o | |  changeset:   4:26a8bac39d9f
+  | |/|/ /   parent:      1:6db2ef61d156
+  | | | |    parent:      3:27eef8ed80b4
+  | | | |    user:        test
+  | | | |    date:        Thu Jan 01 00:00:04 1970 +0000
+  | | | |    summary:     (4) merge two known; one immediate left, one immediate right
+  | | | |
+  | o | |  changeset:   3:27eef8ed80b4
+  |/ / /   user:        test
+  | | |    date:        Thu Jan 01 00:00:03 1970 +0000
+  | | |    summary:     (3) collapse
+  | | |
+  o | |  changeset:   2:3d9a33b8d1e1
+  |/ /   user:        test
+  | |    date:        Thu Jan 01 00:00:02 1970 +0000
+  | |    summary:     (2) collapse
+  | |
+  o |  changeset:   1:6db2ef61d156
+  |/   user:        test
+  |    date:        Thu Jan 01 00:00:01 1970 +0000
+  |    summary:     (1) collapse
+  |
+  o  changeset:   0:e6eb3150255d
+     user:        test
+     date:        Thu Jan 01 00:00:00 1970 +0000
+     summary:     (0) root
+  
+
+
+File glog per revset (only merges):
+  $ hg log -G -r 'file("a")' -m
+  o    changeset:   32:d06dffa21a31
+  |\   parent:      27:886ed638191b
+  | |  parent:      31:621d83e11f67
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | |  summary:     (32) expand
+  | |
+  o |  changeset:   31:621d83e11f67
+  |\|  parent:      21:d42a756af44d
+  | |  parent:      30:6e11cd4b648f
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:31 1970 +0000
+  | |  summary:     (31) expand
+  | |
+  o |    changeset:   30:6e11cd4b648f
+  |\ \   parent:      28:44ecd0b9ae99
+  | | |  parent:      29:cd9bb2be7593
+  | | |  user:        test
+  | | |  date:        Thu Jan 01 00:00:30 1970 +0000
+  | | |  summary:     (30) expand
+  | | |
+  o | |    changeset:   28:44ecd0b9ae99
+  |\ \ \   parent:      1:6db2ef61d156
+  | | | |  parent:      26:7f25b6c2f0b9
+  | | | |  user:        test
+  | | | |  date:        Thu Jan 01 00:00:28 1970 +0000
+  | | | |  summary:     (28) merge zero known
+  | | | |
+  o | | |    changeset:   26:7f25b6c2f0b9
+  |\ \ \ \   parent:      18:1aa84d96232a
+  | | | | |  parent:      25:91da8ed57247
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:26 1970 +0000
+  | | | | |  summary:     (26) merge one known; far right
+  | | | | |
+  | o-----+  changeset:   25:91da8ed57247
+  | | | | |  parent:      21:d42a756af44d
+  | | | | |  parent:      24:a9c19a3d96b7
+  | | | | |  user:        test
+  | | | | |  date:        Thu Jan 01 00:00:25 1970 +0000
+  | | | | |  summary:     (25) merge one known; far left
+  | | | | |
+  | o | | |    changeset:   24:a9c19a3d96b7
+  | |\ \ \ \   parent:      0:e6eb3150255d
+  | | | | | |  parent:      23:a01cddf0766d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:24 1970 +0000
+  | | | | | |  summary:     (24) merge one known; immediate right
+  | | | | | |
+  | o---+ | |  changeset:   23:a01cddf0766d
+  | | | | | |  parent:      1:6db2ef61d156
+  | | | | | |  parent:      22:e0d9cccacb5d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:23 1970 +0000
+  | | | | | |  summary:     (23) merge one known; immediate left
+  | | | | | |
+  | o-------+  changeset:   22:e0d9cccacb5d
+  | | | | | |  parent:      18:1aa84d96232a
+  |/ / / / /   parent:      21:d42a756af44d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:22 1970 +0000
+  | | | | |    summary:     (22) merge two known; one far left, one far right
+  | | | | |
+  | | | | o    changeset:   21:d42a756af44d
+  | | | | |\   parent:      19:31ddc2c1573b
+  | | | | | |  parent:      20:d30ed6450e32
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:21 1970 +0000
+  | | | | | |  summary:     (21) expand
+  | | | | | |
+  +-+-------o  changeset:   20:d30ed6450e32
+  | | | | |    parent:      0:e6eb3150255d
+  | | | | |    parent:      18:1aa84d96232a
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:20 1970 +0000
+  | | | | |    summary:     (20) merge two known; two far right
+  | | | | |
+  | | | | o    changeset:   19:31ddc2c1573b
+  | | | | |\   parent:      15:1dda3f72782d
+  | | | | | |  parent:      17:44765d7c06e0
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:19 1970 +0000
+  | | | | | |  summary:     (19) expand
+  | | | | | |
+  o---+---+ |  changeset:   18:1aa84d96232a
+    | | | | |  parent:      1:6db2ef61d156
+   / / / / /   parent:      15:1dda3f72782d
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:18 1970 +0000
+  | | | | |    summary:     (18) merge two known; two far left
+  | | | | |
+  | | | | o    changeset:   17:44765d7c06e0
+  | | | | |\   parent:      12:86b91144a6e9
+  | | | | | |  parent:      16:3677d192927d
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:17 1970 +0000
+  | | | | | |  summary:     (17) expand
+  | | | | | |
+  +-+-------o  changeset:   16:3677d192927d
+  | | | | |    parent:      0:e6eb3150255d
+  | | | | |    parent:      1:6db2ef61d156
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:16 1970 +0000
+  | | | | |    summary:     (16) merge two known; one immediate right, one near right
+  | | | | |
+  | | | o |    changeset:   15:1dda3f72782d
+  | | | |\ \   parent:      13:22d8966a97e3
+  | | | | | |  parent:      14:8eac370358ef
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:15 1970 +0000
+  | | | | | |  summary:     (15) expand
+  | | | | | |
+  +-------o |  changeset:   14:8eac370358ef
+  | | | | |/   parent:      0:e6eb3150255d
+  | | | | |    parent:      12:86b91144a6e9
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:14 1970 +0000
+  | | | | |    summary:     (14) merge two known; one immediate right, one far right
+  | | | | |
+  | | | o |    changeset:   13:22d8966a97e3
+  | | | |\ \   parent:      9:7010c0af0a35
+  | | | | | |  parent:      11:832d76e6bdf2
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:13 1970 +0000
+  | | | | | |  summary:     (13) expand
+  | | | | | |
+  | +---+---o  changeset:   12:86b91144a6e9
+  | | | | |    parent:      1:6db2ef61d156
+  | | | | |    parent:      9:7010c0af0a35
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:12 1970 +0000
+  | | | | |    summary:     (12) merge two known; one immediate right, one far left
+  | | | | |
+  | | | | o    changeset:   11:832d76e6bdf2
+  | | | | |\   parent:      6:b105a072e251
+  | | | | | |  parent:      10:74c64d036d72
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:11 1970 +0000
+  | | | | | |  summary:     (11) expand
+  | | | | | |
+  +---------o  changeset:   10:74c64d036d72
+  | | | | |/   parent:      0:e6eb3150255d
+  | | | | |    parent:      6:b105a072e251
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:10 1970 +0000
+  | | | | |    summary:     (10) merge two known; one immediate left, one near right
+  | | | | |
+  | | | o |    changeset:   9:7010c0af0a35
+  | | | |\ \   parent:      7:b632bb1b1224
+  | | | | | |  parent:      8:7a0b11f71937
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | | | | | |  summary:     (9) expand
+  | | | | | |
+  +-------o |  changeset:   8:7a0b11f71937
+  | | | |/ /   parent:      0:e6eb3150255d
+  | | | | |    parent:      7:b632bb1b1224
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:08 1970 +0000
+  | | | | |    summary:     (8) merge two known; one immediate left, one far right
+  | | | | |
+  | | | o |    changeset:   7:b632bb1b1224
+  | | | |\ \   parent:      2:3d9a33b8d1e1
+  | | | | | |  parent:      5:4409d547b708
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:07 1970 +0000
+  | | | | | |  summary:     (7) expand
+  | | | | | |
+  | | | +---o  changeset:   6:b105a072e251
+  | | | | |/   parent:      2:3d9a33b8d1e1
+  | | | | |    parent:      5:4409d547b708
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:06 1970 +0000
+  | | | | |    summary:     (6) merge two known; one immediate left, one far left
+  | | | | |
+  | | | o |    changeset:   5:4409d547b708
+  | | | |\ \   parent:      3:27eef8ed80b4
+  | | | | | |  parent:      4:26a8bac39d9f
+  | | | | | |  user:        test
+  | | | | | |  date:        Thu Jan 01 00:00:05 1970 +0000
+  | | | | | |  summary:     (5) expand
+  | | | | | |
+  | +---o | |  changeset:   4:26a8bac39d9f
+  | | | |/ /   parent:      1:6db2ef61d156
+  | | | | |    parent:      3:27eef8ed80b4
+  | | | | |    user:        test
+  | | | | |    date:        Thu Jan 01 00:00:04 1970 +0000
+  | | | | |    summary:     (4) merge two known; one immediate left, one immediate right
+  | | | | |
+
+
 Unused arguments:
   $ hg glog -q foo bar
   hg glog: invalid arguments
@@ -869,6 +1300,23 @@
   | | |  summary:     (32) expand
   | | |
 
+Point out a common and an uncommon unshown parent
+  $ hg glog -r 'rev(8) or rev(9)'
+  o    changeset:   9:7010c0af0a35
+  |\   parent:      7:b632bb1b1224
+  | |  parent:      8:7a0b11f71937
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:09 1970 +0000
+  | |  summary:     (9) expand
+  | |
+  o |  changeset:   8:7a0b11f71937
+  |\|  parent:      0:e6eb3150255d
+  | |  parent:      7:b632bb1b1224
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:08 1970 +0000
+  | |  summary:     (8) merge two known; one immediate left, one far right
+  | |
+
 File + limit + -ra:b, b < tip:
   $ hg glog -l1 -r32:34 a
   o  changeset:   34:fea3ac5810e0
@@ -878,6 +1326,28 @@
   |  summary:     (34) head
   |
 
+file(File) + limit + -ra:b, b < tip:
+  $ hg glog -l1 -r32:34 -r 'file("a")'
+  o  changeset:   34:fea3ac5810e0
+  |  parent:      32:d06dffa21a31
+  |  user:        test
+  |  date:        Thu Jan 01 00:00:34 1970 +0000
+  |  summary:     (34) head
+  |
+
+limit(file(File) and a::b), b < tip:
+  $ hg glog -r 'limit(file("a") and 32::34, 1)'
+  o    changeset:   32:d06dffa21a31
+  |\   parent:      27:886ed638191b
+  | |  parent:      31:621d83e11f67
+  | |  user:        test
+  | |  date:        Thu Jan 01 00:00:32 1970 +0000
+  | |  summary:     (32) expand
+  | |
+
+File + limit + -ra:b, b < tip:
+  $ hg glog -r 'limit(file("a") and 34::32, 1)'
+
 File + limit + -ra:b, b < tip, (b - a) < limit:
   $ hg glog -l10 -r33:34 a
   o  changeset:   34:fea3ac5810e0



More information about the Mercurial-devel mailing list