mercurial/graphmod.py
author Manuel Jacob <me@manueljacob.de>
Fri, 06 Mar 2020 10:52:44 +0100
changeset 44449 ff72bd52d56a
parent 43776 faa8a59f4a06
child 44452 9d2b2df2c2ba
permissions -rw-r--r--
tests: avoid implicit conversion of str to unicode On Python 2, str.encode('utf-8') implicitly converts the string to unicode and then back to str. Using _sys2bytes() ensures that opt is only encoded on Python 3, where opt is unicode. Although contrived, before this change, a UnicodeDecodeError could be triggered on Python 2 when passing non-ascii values to --extra-config-opt.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# Revision graph generator for Mercurial
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
#
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     4
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10084
diff changeset
     7
# GNU General Public License version 2 or any later version.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     8
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
     9
"""supports walking the history as DAGs suitable for graphical output
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    10
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    11
The most basic format we use is that of::
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    12
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    13
  (id, type, data, [parentids])
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    14
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    15
The node and parent ids are arbitrary integers which identify a node in the
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    16
context of the graph returned. Type is a constant specifying the node type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    17
Data depends on type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    18
"""
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    19
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    20
from __future__ import absolute_import
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    21
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    22
from .node import nullrev
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
    23
from .thirdparty import attr
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    24
from . import (
32903
27932a76a88d dagop: split module hosting DAG-related algorithms from revset
Yuya Nishihara <yuya@tcha.org>
parents: 32160
diff changeset
    25
    dagop,
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38150
diff changeset
    26
    pycompat,
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    27
    smartset,
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    28
    util,
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    29
)
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    30
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    31
CHANGESET = b'C'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    32
PARENT = b'P'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    33
GRANDPARENT = b'G'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    34
MISSINGPARENT = b'M'
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
    35
# Style of line to draw. None signals a line that ends and is removed at this
29134
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    36
# point. A number prefix means only the last N characters of the current block
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    37
# will use that style, the rest will use the PARENT style. Add a - sign
8d5584d8345b graphmod: partial edge styling
Martijn Pieters <mjpieters@fb.com>
parents: 28998
diff changeset
    38
# (so making N negative) and all but the first N characters use that style.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    39
EDGES = {PARENT: b'|', GRANDPARENT: b':', MISSINGPARENT: None}
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    40
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    41
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    42
def dagwalker(repo, revs):
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    43
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    44
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    45
    This generator function walks through revisions (which should be ordered
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    46
    from bigger to lower). It returns a tuple for each node.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    47
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    48
    Each parentinfo entry is a tuple with (edgetype, parentid), where edgetype
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    49
    is one of PARENT, GRANDPARENT or MISSINGPARENT. The node and parent ids
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    50
    are arbitrary integers which identify a node in the context of the graph
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    51
    returned.
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    52
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    53
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    54
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    55
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    56
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    57
        ctx = repo[rev]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    58
        # partition into parents in the rev set and missing parents, then
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    59
        # augment the lists with markers, to inform graph drawing code about
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    60
        # what kind of edge to draw between nodes.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    61
        pset = set(p.rev() for p in ctx.parents() if p.rev() in revs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    62
        mpars = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    63
            p.rev()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    64
            for p in ctx.parents()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    65
            if p.rev() != nullrev and p.rev() not in pset
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    66
        ]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    67
        parents = [(PARENT, p) for p in sorted(pset)]
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    68
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    69
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    70
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    71
            if gp is None:
26187
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
    72
                # precompute slow query as we know reachableroots() goes
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
    73
                # through all revs (issue4782)
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    74
                if not isinstance(revs, smartset.baseset):
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    75
                    revs = smartset.baseset(revs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    76
                gp = gpcache[mpar] = sorted(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    77
                    set(dagop.reachableroots(repo, revs, [mpar]))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    78
                )
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    79
            if not gp:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    80
                parents.append((MISSINGPARENT, mpar))
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    81
                pset.add(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    82
            else:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    83
                parents.extend((GRANDPARENT, g) for g in gp if g not in pset)
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    84
                pset.update(gp)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    85
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    86
        yield (ctx.rev(), CHANGESET, ctx, parents)
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    87
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    88
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    89
def nodes(repo, nodes):
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    90
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    91
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    92
    This generator function walks the given nodes. It only returns parents
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    93
    that are in nodes, too.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    94
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    95
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    96
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    97
        ctx = repo[node]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    98
        parents = set(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    99
            (PARENT, p.rev()) for p in ctx.parents() if p.node() in include
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   100
        )
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
   101
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   102
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   103
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   104
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   105
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   106
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   107
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   108
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   109
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   110
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   111
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   112
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   113
      - Tuple (col, color) with column and color index for the current node
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   114
      - A list of tuples indicating the edges between the current node and its
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   115
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   116
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   117
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   118
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   119
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   120
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   121
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   122
    for key, val in repo.ui.configitems(b'graph'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   123
        if b'.' in key:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   124
            branch, setting = key.rsplit(b'.', 1)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   125
            # Validation
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   126
            if setting == b"width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   127
                config.setdefault(branch, {})[setting] = int(val)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   128
            elif setting == b"color" and val.isalnum():
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   129
                config.setdefault(branch, {})[setting] = val
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   130
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   131
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   132
        getconf = util.lrucachefunc(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   133
            lambda rev: config.get(repo[rev].branch(), {})
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   134
        )
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   135
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   136
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   137
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   138
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   139
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   140
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   141
        if cur not in seen:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   142
            seen.append(cur)  # new head
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   143
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   144
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   145
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   146
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   147
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   148
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   149
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   150
        # Add parents to next
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   151
        addparents = [p for pt, p in parents if p not in next]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   152
        next[col : col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   153
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   154
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   155
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   156
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   157
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   158
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   159
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   160
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   161
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   162
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   163
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   164
        for ecol, eid in enumerate(seen):
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   165
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   166
                bconf = getconf(eid)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   167
                edges.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   168
                    (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   169
                        ecol,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   170
                        next.index(eid),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   171
                        colors[eid],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   172
                        bconf.get(b'width', -1),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   173
                        bconf.get(b'color', b''),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   174
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   175
                )
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   176
            elif eid == cur:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   177
                for ptype, p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   178
                    bconf = getconf(p)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   179
                    edges.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   180
                        (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   181
                            ecol,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   182
                            next.index(p),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   183
                            color,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   184
                            bconf.get(b'width', -1),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   185
                            bconf.get(b'color', b''),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   186
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   187
                    )
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   188
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   189
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   190
        yield (cur, type, data, (col, color), edges)
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   191
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   192
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   193
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   194
def asciiedges(type, char, state, rev, parents):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   195
    """adds edge info to changelog DAG walk suitable for ascii()"""
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   196
    seen = state.seen
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   197
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   198
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   199
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   200
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   201
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   202
    newparents = []
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   203
    for ptype, parent in parents:
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   204
        if parent == rev:
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   205
            # self reference (should only be seen in null rev)
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   206
            continue
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   207
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   208
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   209
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   210
            newparents.append(parent)
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   211
            state.edges[parent] = state.styles.get(ptype, b'|')
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   212
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   213
    ncols = len(seen)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   214
    width = 1 + ncols * 2
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   215
    nextseen = seen[:]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   216
    nextseen[nodeidx : nodeidx + 1] = newparents
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   217
    edges = [(nodeidx, nextseen.index(p)) for p in knownparents]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   218
28998
f303b569134c graphmod: fix seen state handling for > 2 parents (issue5174)
Martijn Pieters <mjpieters@fb.com>
parents: 28891
diff changeset
   219
    seen[:] = nextseen
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   220
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   221
        # ascii() only knows how to add or remove a single column between two
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   222
        # calls. Nodes with more than two parents break this constraint so we
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   223
        # introduce intermediate expansion lines to grow the active node list
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   224
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   225
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   226
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   227
        nmorecols = 1
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   228
        width += 2
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   229
        yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   230
        char = b'\\'
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   231
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   232
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   233
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   234
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   235
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   236
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   237
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   238
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   239
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   240
    nmorecols = len(nextseen) - ncols
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   241
    if nmorecols > 0:
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   242
        width += 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   243
    # remove current node from edge characters, no longer needed
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   244
    state.edges.pop(rev, None)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   245
    yield (type, char, width, (nodeidx, edges, ncols, nmorecols))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   246
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   247
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   248
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   249
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   250
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   251
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   252
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   253
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   254
def _getnodelineedgestail(echars, idx, pidx, ncols, coldiff, pdiff, fix_tail):
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   255
    if fix_tail and coldiff == pdiff and coldiff != 0:
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   256
        # Still going in the same non-vertical direction.
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   257
        if coldiff == -1:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   258
            start = max(idx + 1, pidx)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   259
            tail = echars[idx * 2 : (start - 1) * 2]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   260
            tail.extend([b"/", b" "] * (ncols - start))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   261
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   262
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   263
            return [b"\\", b" "] * (ncols - idx - 1)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   264
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   265
        remainder = ncols - idx - 1
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   266
        return echars[-(remainder * 2) :] if remainder > 0 else []
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   267
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   268
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   269
def _drawedges(echars, edges, nodeline, interline):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   270
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   271
        if start == end + 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   272
            interline[2 * end + 1] = b"/"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   273
        elif start == end - 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   274
            interline[2 * start + 1] = b"\\"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   275
        elif start == end:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   276
            interline[2 * start] = echars[2 * start]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   277
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   278
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   279
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   280
            nodeline[2 * end] = b"+"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   281
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   282
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   283
            for i in range(2 * start + 1, 2 * end):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   284
                if nodeline[i] != b"+":
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   285
                    nodeline[i] = b"-"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   286
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   287
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   288
def _getpaddingline(echars, idx, ncols, edges):
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   289
    # all edges up to the current node
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   290
    line = echars[: idx * 2]
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   291
    # an edge for the current node, if there is one
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   292
    if (idx, idx - 1) in edges or (idx, idx) in edges:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   293
        # (idx, idx - 1)      (idx, idx)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   294
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   295
        # +---o |           | o---+
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   296
        # | | X |           | X | |
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   297
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   298
        # | | |             | | |
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   299
        line.extend(echars[idx * 2 : (idx + 1) * 2])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   300
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   301
        line.extend([b' ', b' '])
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   302
    # all edges to the right of the current node
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   303
    remainder = ncols - idx - 1
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   304
    if remainder > 0:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   305
        line.extend(echars[-(remainder * 2) :])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   306
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   307
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   308
39286
3c4b2e880273 log: respect graphshorten on terminal nodes (collapsing o-~ to just o~)
Kyle Lippincott <spectral@google.com>
parents: 38783
diff changeset
   309
def _drawendinglines(lines, extra, edgemap, seen, state):
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   310
    """Draw ending lines for missing parent edges
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   311
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   312
    None indicates an edge that ends at between this node and the next
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   313
    Replace with a short line ending in ~ and add / lines to any edges to
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   314
    the right.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   315
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   316
    """
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   317
    if None not in edgemap.values():
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   318
        return
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   319
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   320
    # Check for more edges to the right of our ending edges.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   321
    # We need enough space to draw adjustment lines for these.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   322
    edgechars = extra[::2]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   323
    while edgechars and edgechars[-1] is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   324
        edgechars.pop()
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   325
    shift_size = max((edgechars.count(None) * 2) - 1, 0)
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   326
    minlines = 3 if not state.graphshorten else 2
39286
3c4b2e880273 log: respect graphshorten on terminal nodes (collapsing o-~ to just o~)
Kyle Lippincott <spectral@google.com>
parents: 38783
diff changeset
   327
    while len(lines) < minlines + shift_size:
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   328
        lines.append(extra[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   329
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   330
    if shift_size:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   331
        empties = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   332
        toshift = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   333
        first_empty = extra.index(None)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   334
        for i, c in enumerate(extra[first_empty::2], first_empty // 2):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   335
            if c is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   336
                empties.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   337
            else:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   338
                toshift.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   339
        targets = list(range(first_empty, first_empty + len(toshift) * 2, 2))
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   340
        positions = toshift[:]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   341
        for line in lines[-shift_size:]:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   342
            line[first_empty:] = [b' '] * (len(line) - first_empty)
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   343
            for i in range(len(positions)):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   344
                pos = positions[i] - 1
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   345
                positions[i] = max(pos, targets[i])
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   346
                line[pos] = b'/' if pos > targets[i] else extra[toshift[i]]
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   347
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   348
    map = {1: b'|', 2: b'~'} if not state.graphshorten else {1: b'~'}
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   349
    for i, line in enumerate(lines):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   350
        if None not in line:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   351
            continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   352
        line[:] = [c or map.get(i, b' ') for c in line]
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   353
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   354
    # remove edges that ended
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   355
    remove = [p for p, c in edgemap.items() if c is None]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   356
    for parent in remove:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   357
        del edgemap[parent]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   358
        seen.remove(parent)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   359
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   360
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   361
@attr.s
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   362
class asciistate(object):
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   363
    """State of ascii() graph rendering"""
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   364
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   365
    seen = attr.ib(init=False, default=attr.Factory(list))
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   366
    edges = attr.ib(init=False, default=attr.Factory(dict))
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   367
    lastcoldiff = attr.ib(init=False, default=0)
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   368
    lastindex = attr.ib(init=False, default=0)
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   369
    styles = attr.ib(init=False, default=attr.Factory(EDGES.copy))
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   370
    graphshorten = attr.ib(init=False, default=False)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   371
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   372
38150
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   373
def outputgraph(ui, graph):
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   374
    """outputs an ASCII graph of a DAG
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   375
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   376
    this is a helper function for 'ascii' below.
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   377
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   378
    takes the following arguments:
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   379
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   380
    - ui to write to
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   381
    - graph data: list of { graph nodes/edges, text }
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   382
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   383
    this function can be monkey-patched by extensions to alter graph display
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   384
    without needing to mimic all of the edge-fixup logic in ascii()
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   385
    """
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   386
    for (ln, logstr) in graph:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   387
        ui.write((ln + logstr).rstrip() + b"\n")
38150
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   388
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   389
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
def ascii(ui, state, type, char, text, coldata):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   392
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   393
    takes the following arguments (one call per node in the graph):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   395
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   396
      - Somewhere to keep the needed state in (init to asciistate())
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   397
      - Column of the current node in the set of ongoing edges.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   398
      - Type indicator of node data, usually 'C' for changesets.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   400
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   401
        - List of lines to display as the node's text.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   402
      - Edges; a list of (col, next_col) indicating the edges between
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   403
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   404
      - Number of columns (ongoing edges) in the current revision.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   405
      - The difference between the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   406
        in the next revision and the number of columns (ongoing edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   407
        in the current revision. That is: -1 means one column removed;
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   408
        0 means no columns added or removed; 1 means one column added.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   409
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   410
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   411
    assert -2 < coldiff < 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   412
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   413
    edgemap, seen = state.edges, state.seen
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   414
    # Be tolerant of history issues; make sure we have at least ncols + coldiff
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   415
    # elements to work with. See test-glog.t for broken history test cases.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   416
    echars = [c for p in seen for c in (edgemap.get(p, b'|'), b' ')]
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   417
    echars.extend((b'|', b' ') * max(ncols + coldiff - len(seen), 0))
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   418
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   419
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   420
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   421
        #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   422
        #     | | |        | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   423
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   425
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   426
        _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   427
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   428
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   429
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   430
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   431
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   432
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   433
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   434
    #                    o | |
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   435
    add_padding_line = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   436
        len(text) > 2 and coldiff == -1 and [x for (x, y) in edges if x + 1 < y]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   437
    )
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   438
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   439
    # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   440
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   441
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   442
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   443
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   445
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
    fix_nodeline_tail = len(text) <= 2 and not add_padding_line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   447
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   448
    # nodeline is the line containing the node character (typically o)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   449
    nodeline = echars[: idx * 2]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   450
    nodeline.extend([char, b" "])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   451
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   452
    nodeline.extend(
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   453
        _getnodelineedgestail(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   454
            echars,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   455
            idx,
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   456
            state.lastindex,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   457
            ncols,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   458
            coldiff,
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   459
            state.lastcoldiff,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   460
            fix_nodeline_tail,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   461
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   462
    )
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   463
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   464
    # shift_interline is the line containing the non-vertical
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   465
    # edges between this entry and the next
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   466
    shift_interline = echars[: idx * 2]
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38150
diff changeset
   467
    for i in pycompat.xrange(2 + coldiff):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   468
        shift_interline.append(b' ')
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   469
    count = ncols - idx - 1
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   470
    if coldiff == -1:
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38150
diff changeset
   471
        for i in pycompat.xrange(count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   472
            shift_interline.extend([b'/', b' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   473
    elif coldiff == 0:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   474
        shift_interline.extend(echars[(idx + 1) * 2 : ncols * 2])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   475
    else:
38783
e7aa113b14f7 global: use pycompat.xrange()
Gregory Szorc <gregory.szorc@gmail.com>
parents: 38150
diff changeset
   476
        for i in pycompat.xrange(count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   477
            shift_interline.extend([b'\\', b' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   478
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   479
    # draw edges from the current node to its parents
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   480
    _drawedges(echars, edges, nodeline, shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   481
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   482
    # lines is the list of all graph lines to print
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   483
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   484
    if add_padding_line:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   485
        lines.append(_getpaddingline(echars, idx, ncols, edges))
28891
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   486
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   487
    # If 'graphshorten' config, only draw shift_interline
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   488
    # when there is any non vertical flow in graph.
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   489
    if state.graphshorten:
41536
fb9e11fdcbba graphmod: use raw string
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39286
diff changeset
   490
        if any(c in br'\/' for c in shift_interline if c):
28891
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   491
            lines.append(shift_interline)
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   492
    # Else, no 'graphshorten' config so draw shift_interline.
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   493
    else:
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   494
        lines.append(shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   495
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   496
    # make sure that there are as many graph lines as there are
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   497
    # log strings
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   498
    extra_interline = echars[: (ncols + coldiff) * 2]
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   499
    if len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   500
        while len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   501
            lines.append(extra_interline[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   502
39286
3c4b2e880273 log: respect graphshorten on terminal nodes (collapsing o-~ to just o~)
Kyle Lippincott <spectral@google.com>
parents: 38783
diff changeset
   503
    _drawendinglines(lines, extra_interline, edgemap, seen, state)
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   504
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   505
    while len(text) < len(lines):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   506
        text.append(b"")
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   507
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   508
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   509
    indentation_level = max(ncols, ncols + coldiff)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   510
    lines = [
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   511
        b"%-*s " % (2 * indentation_level, b"".join(line)) for line in lines
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   512
    ]
38150
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   513
    outputgraph(ui, zip(lines, text))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   514
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   515
    # ... and start over
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   516
    state.lastcoldiff = coldiff
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   517
    state.lastindex = idx