graphmod: allow edges to end early
authorMartijn Pieters <mjpieters@fb.com>
Sat, 19 Mar 2016 16:37:47 -0700
changeset 28601 cd10171d6c71
parent 28600 0d6137891114
child 28602 83127a9fe76e
graphmod: allow edges to end early Rather than draw an edge all the way to the bottom of the graph, make it possible to end an edge to parents that are not part of the graph early on. This results in a far cleaner graph. Any edge type can be set to end early; set the ui.graphstyle.<edgetype> parameter to the empty string to enable this. For example, setting the following configuration: [ui] graphstyle.grandparent = : graphstyle.missing = would result in a graph like this: o changeset: 32:d06dffa21a31 |\ parent: 27:886ed638191b | : parent: 31:621d83e11f67 | : o : changeset: 31:621d83e11f67 |\: parent: 21:d42a756af44d | : parent: 30:6e11cd4b648f | : o : changeset: 30:6e11cd4b648f |\ \ parent: 28:44ecd0b9ae99 | ~ : parent: 29:cd9bb2be7593 | / o : changeset: 28:44ecd0b9ae99 |\ \ parent: 1:6db2ef61d156 | ~ : parent: 26:7f25b6c2f0b9 | / o : changeset: 26:7f25b6c2f0b9 |\ \ parent: 18:1aa84d96232a | | : parent: 25:91da8ed57247 | | : | o : changeset: 25:91da8ed57247 | |\: parent: 21:d42a756af44d | | : parent: 24:a9c19a3d96b7 | | : | o : changeset: 24:a9c19a3d96b7 | |\ \ parent: 0:e6eb3150255d | | ~ : parent: 23:a01cddf0766d | | / | o : changeset: 23:a01cddf0766d | |\ \ parent: 1:6db2ef61d156 | | ~ : parent: 22:e0d9cccacb5d | | / | o : changeset: 22:e0d9cccacb5d |/:/ parent: 18:1aa84d96232a | : parent: 21:d42a756af44d | : | o changeset: 21:d42a756af44d | |\ parent: 19:31ddc2c1573b | | | parent: 20:d30ed6450e32 | | | +---o changeset: 20:d30ed6450e32 | | | parent: 0:e6eb3150255d | | ~ parent: 18:1aa84d96232a | | | o changeset: 19:31ddc2c1573b | |\ parent: 15:1dda3f72782d | ~ ~ parent: 17:44765d7c06e0 | o changeset: 18:1aa84d96232a parent: 1:6db2ef61d156 parent: 15:1dda3f72782d The default configuration leaves all 3 types set to |. This is part of the work towards moving smartlog upstream; currently smartlog injects extra nodes into the graph to indicate grandparent relationships (nodes elided).
mercurial/cmdutil.py
mercurial/graphmod.py
tests/test-glog.t
--- a/mercurial/cmdutil.py	Sat Mar 19 16:46:15 2016 -0700
+++ b/mercurial/cmdutil.py	Sat Mar 19 16:37:47 2016 -0700
@@ -2227,6 +2227,8 @@
     for name, key in edgetypes.items():
         # experimental config: ui.graphstyle.*
         styles[key] = ui.config('ui', 'graphstyle.%s' % name, styles[key])
+        if not styles[key]:
+            styles[key] = None
     for rev, type, ctx, parents in dag:
         char = formatnode(repo, ctx)
         copies = None
--- a/mercurial/graphmod.py	Sat Mar 19 16:46:15 2016 -0700
+++ b/mercurial/graphmod.py	Sat Mar 19 16:37:47 2016 -0700
@@ -31,6 +31,8 @@
 PARENT = 'P'
 GRANDPARENT = 'G'
 MISSINGPARENT = 'M'
+# Style of line to draw. None signals a line that ends and is removed at this
+# point.
 EDGES = {PARENT: '|', GRANDPARENT: '|', MISSINGPARENT: '|'}
 
 def groupbranchiter(revs, parentsfunc, firstbranch=()):
@@ -483,6 +485,56 @@
         line.extend(echars[-(remainder * 2):])
     return line
 
+def _drawendinglines(lines, extra, edgemap, seen):
+    """Draw ending lines for missing parent edges
+
+    None indicates an edge that ends at between this node and the next
+    Replace with a short line ending in ~ and add / lines to any edges to
+    the right.
+
+    """
+    if None not in edgemap.values():
+        return
+
+    # Check for more edges to the right of our ending edges.
+    # We need enough space to draw adjustment lines for these.
+    edgechars = extra[::2]
+    while edgechars and edgechars[-1] is None:
+        edgechars.pop()
+    shift_size = max((edgechars.count(None) * 2) - 1, 0)
+    while len(lines) < 3 + shift_size:
+        lines.append(extra[:])
+
+    if shift_size:
+        empties = []
+        toshift = []
+        first_empty = extra.index(None)
+        for i, c in enumerate(extra[first_empty::2], first_empty // 2):
+            if c is None:
+                empties.append(i * 2)
+            else:
+                toshift.append(i * 2)
+        targets = list(range(first_empty, first_empty + len(toshift) * 2, 2))
+        positions = toshift[:]
+        for line in lines[-shift_size:]:
+            line[first_empty:] = [' '] * (len(line) - first_empty)
+            for i in range(len(positions)):
+                pos = positions[i] - 1
+                positions[i] = max(pos, targets[i])
+                line[pos] = '/' if pos > targets[i] else extra[toshift[i]]
+
+    map = {1: '|', 2: '~'}
+    for i, line in enumerate(lines):
+        if None not in line:
+            continue
+        line[:] = [c or map.get(i, ' ') for c in line]
+
+    # remove edges that ended
+    remove = [p for p, c in edgemap.items() if c is None]
+    for parent in remove:
+        del edgemap[parent]
+        seen.remove(parent)
+
 def asciistate():
     """returns the initial value for the "state" argument to ascii()"""
     return {
@@ -582,12 +634,15 @@
 
     # make sure that there are as many graph lines as there are
     # log strings
+    extra_interline = echars[:(ncols + coldiff) * 2]
+    if len(lines) < len(text):
+        while len(lines) < len(text):
+            lines.append(extra_interline[:])
+
+    _drawendinglines(lines, extra_interline, edgemap, seen)
+
     while len(text) < len(lines):
         text.append("")
-    if len(lines) < len(text):
-        extra_interline = echars[:(ncols + coldiff) * 2]
-        while len(lines) < len(text):
-            lines.append(extra_interline)
 
     # print lines
     indentation_level = max(ncols, ncols + coldiff)
--- a/tests/test-glog.t	Sat Mar 19 16:46:15 2016 -0700
+++ b/tests/test-glog.t	Sat Mar 19 16:37:47 2016 -0700
@@ -2423,7 +2423,7 @@
   > [ui]
   > graphstyle.parent = |
   > graphstyle.grandparent = :
-  > graphstyle.missing = .
+  > graphstyle.missing =
   > EOF
   $ hg log -G -r 'file("a")' -m
   @  changeset:   36:08a19a744424
@@ -2451,178 +2451,178 @@
   | :
   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
-  . . . . .
+  | ~ :  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
+  
 
   $ cd ..