[PATCH 2 of 2 V4] graphmod: end edges to missing parents early

Martijn Pieters mj at zopatista.com
Sat Mar 19 20:45:50 EDT 2016


# HG changeset patch
# User Martijn Pieters <mjpieters at fb.com>
# Date 1458430667 25200
#      Sat Mar 19 16:37:47 2016 -0700
# Node ID c05fd6aeedf050eb3e94e0b0c77121b45b5cdc89
# Parent  f09345b5fceef0f716018745747b0b49aaae7a5a
graphmod: end edges to missing parents 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).

diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -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
diff --git a/mercurial/graphmod.py b/mercurial/graphmod.py
--- a/mercurial/graphmod.py
+++ b/mercurial/graphmod.py
@@ -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)
diff --git a/tests/test-glog.t b/tests/test-glog.t
--- a/tests/test-glog.t
+++ b/tests/test-glog.t
@@ -1188,6 +1188,7 @@
      date:        Thu Jan 01 00:00:00 1970 +0000
      summary:     one
   
+
 Issue2395: glog --style header and footer
   $ hg log -G --style=xml one
   <?xml version="1.0"?>
@@ -2423,7 +2424,7 @@
   > [ui]
   > graphstyle.parent = |
   > graphstyle.grandparent = :
-  > graphstyle.missing = .
+  > graphstyle.missing =
   > EOF
   $ hg log -G -r 'file("a")' -m
   @  changeset:   36:08a19a744424
@@ -2451,178 +2452,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 ..


More information about the Mercurial-devel mailing list