mercurial/graphmod.py
author Pierre-Yves David <pierre-yves.david@octobus.net>
Tue, 26 Mar 2024 08:43:20 +0000
changeset 51546 f376c4d5c4b6
parent 49284 d44e3c45f0e4
child 51690 493034cc3265
permissions -rw-r--r--
perf-stream-locked-section: advertise the right version key in the help As the v3 format is still experimental, its key is "v3-exp". The help text was not pointing that out. (we also fix `perf::stream-generate` in the process)
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
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    20
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    21
from .node import nullrev
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
    22
from .thirdparty import attr
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    23
from . import (
32903
27932a76a88d dagop: split module hosting DAG-related algorithms from revset
Yuya Nishihara <yuya@tcha.org>
parents: 32160
diff changeset
    24
    dagop,
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    25
    smartset,
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    26
    util,
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    27
)
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    28
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    29
CHANGESET = b'C'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    30
PARENT = b'P'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    31
GRANDPARENT = b'G'
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    32
MISSINGPARENT = b'M'
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
    33
# 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
    34
# 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
    35
# 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
    36
# (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
    37
EDGES = {PARENT: b'|', GRANDPARENT: b':', MISSINGPARENT: None}
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    38
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    39
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    40
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
    41
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    42
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    43
    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
    44
    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
    45
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    46
    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
    47
    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
    48
    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
    49
    returned.
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    50
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    51
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    52
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    53
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    54
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    55
        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
    56
        # 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
    57
        # 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
    58
        # what kind of edge to draw between nodes.
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43776
diff changeset
    59
        pset = {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
    60
        mpars = [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    61
            p.rev()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    62
            for p in ctx.parents()
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    63
            if p.rev() != nullrev and p.rev() not in pset
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    64
        ]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    65
        parents = [(PARENT, p) for p in sorted(pset)]
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    66
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    67
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    68
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    69
            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
    70
                # 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
    71
                # through all revs (issue4782)
31023
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    72
                if not isinstance(revs, smartset.baseset):
aea06029919e revset: import set classes directly from smartset module
Yuya Nishihara <yuya@tcha.org>
parents: 29348
diff changeset
    73
                    revs = smartset.baseset(revs)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    74
                gp = gpcache[mpar] = sorted(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    75
                    set(dagop.reachableroots(repo, revs, [mpar]))
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    76
                )
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    77
            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
    78
                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
    79
                pset.add(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    80
            else:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    81
                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
    82
                pset.update(gp)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    83
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    84
        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
    85
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    86
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    87
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
    88
    """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
    89
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    90
    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
    91
    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
    92
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    93
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    94
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    95
        ctx = repo[node]
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43776
diff changeset
    96
        parents = {
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
    97
            (PARENT, p.rev()) for p in ctx.parents() if p.node() in include
44452
9d2b2df2c2ba cleanup: run pyupgrade on our source tree to clean up varying things
Augie Fackler <augie@google.com>
parents: 43776
diff changeset
    98
        }
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    99
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   100
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   101
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   102
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   103
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   104
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   105
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   106
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   107
      (id, type, data, (col, color), [(col, nextcol, color)])
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
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   110
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   111
      - 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
   112
      - 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
   113
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   114
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   115
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   116
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   117
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   118
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   119
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   120
    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
   121
        if b'.' in key:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   122
            branch, setting = key.rsplit(b'.', 1)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   123
            # Validation
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   124
            if setting == b"width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   125
                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
   126
            elif setting == b"color" and val.isalnum():
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   127
                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
   128
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   129
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   130
        getconf = util.lrucachefunc(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   131
            lambda rev: config.get(repo[rev].branch(), {})
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   132
        )
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   133
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   134
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   135
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   136
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   137
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   138
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   139
        if cur not in seen:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   140
            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
   141
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   142
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   143
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   144
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   145
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   146
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   147
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   148
        # 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
   149
        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
   150
        next[col : col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   151
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   152
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   153
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   154
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   155
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   156
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   157
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   158
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   159
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   160
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   161
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   162
        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
   163
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   164
                bconf = getconf(eid)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   165
                edges.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   166
                    (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   167
                        ecol,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   168
                        next.index(eid),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   169
                        colors[eid],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   170
                        bconf.get(b'width', -1),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   171
                        bconf.get(b'color', b''),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   172
                    )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   173
                )
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   174
            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
   175
                for ptype, p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   176
                    bconf = getconf(p)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   177
                    edges.append(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   178
                        (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   179
                            ecol,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   180
                            next.index(p),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   181
                            color,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   182
                            bconf.get(b'width', -1),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   183
                            bconf.get(b'color', b''),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   184
                        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   185
                    )
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   186
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   187
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   188
        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
   189
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   190
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   191
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   192
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
   193
    """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
   194
    seen = state.seen
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   195
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   196
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   197
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   198
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   199
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   200
    newparents = []
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   201
    for ptype, parent in parents:
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   202
        if parent == rev:
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   203
            # 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
   204
            continue
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   205
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   206
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   207
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   208
            newparents.append(parent)
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   209
            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
   210
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   211
    ncols = len(seen)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   212
    width = 1 + ncols * 2
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   213
    nextseen = seen[:]
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   214
    nextseen[nodeidx : nodeidx + 1] = newparents
31552
d0b9e9803caf graphlog: draw multiple edges towards null node (issue5440)
Yuya Nishihara <yuya@tcha.org>
parents: 31023
diff changeset
   215
    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
   216
28998
f303b569134c graphmod: fix seen state handling for > 2 parents (issue5174)
Martijn Pieters <mjpieters@fb.com>
parents: 28891
diff changeset
   217
    seen[:] = nextseen
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   218
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   219
        # 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
   220
        # 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
   221
        # 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
   222
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   223
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   224
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   225
        nmorecols = 1
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   226
        width += 2
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   227
        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
   228
        char = b'\\'
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   229
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   230
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   231
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   232
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   233
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   234
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   235
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   236
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   237
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   238
    nmorecols = len(nextseen) - ncols
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   239
    if nmorecols > 0:
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   240
        width += 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   241
    # 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
   242
    state.edges.pop(rev, None)
33858
6f6c87888b22 log: add a "graphwidth" template variable
Danny Hooper <hooper@google.com>
parents: 32903
diff changeset
   243
    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
   244
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   245
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   246
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   247
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   248
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   249
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   250
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   251
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   252
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
   253
    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
   254
        # 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
   255
        if coldiff == -1:
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   256
            start = max(idx + 1, pidx)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   257
            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
   258
            tail.extend([b"/", b" "] * (ncols - start))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   259
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   260
        else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   261
            return [b"\\", b" "] * (ncols - idx - 1)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   262
    else:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   263
        remainder = ncols - idx - 1
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   264
        return echars[-(remainder * 2) :] if remainder > 0 else []
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   265
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   266
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   267
def _drawedges(echars, edges, nodeline, interline):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   268
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   269
        if start == end + 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   270
            interline[2 * end + 1] = b"/"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   271
        elif 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 * start + 1] = b"\\"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   273
        elif start == end:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   274
            interline[2 * start] = echars[2 * start]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   275
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   276
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   277
                continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   278
            nodeline[2 * end] = b"+"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   279
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   280
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   281
            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
   282
                if nodeline[i] != b"+":
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   283
                    nodeline[i] = b"-"
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   284
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   285
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   286
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
   287
    # all edges up to the current node
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   288
    line = echars[: idx * 2]
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   289
    # 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
   290
    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
   291
        # (idx, idx - 1)      (idx, idx)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   292
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   293
        # +---o |           | o---+
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   294
        # | | X |           | X | |
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   295
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   296
        # | | |             | | |
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   297
        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
   298
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   299
        line.extend([b' ', b' '])
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   300
    # 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
   301
    remainder = ncols - idx - 1
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   302
    if remainder > 0:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   303
        line.extend(echars[-(remainder * 2) :])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   304
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   305
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   306
39286
3c4b2e880273 log: respect graphshorten on terminal nodes (collapsing o-~ to just o~)
Kyle Lippincott <spectral@google.com>
parents: 38783
diff changeset
   307
def _drawendinglines(lines, extra, edgemap, seen, state):
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   308
    """Draw ending lines for missing parent edges
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   309
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   310
    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
   311
    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
   312
    the right.
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   313
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   314
    """
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   315
    if None not in edgemap.values():
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   316
        return
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   317
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   318
    # 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
   319
    # 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
   320
    edgechars = extra[::2]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   321
    while edgechars and edgechars[-1] is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   322
        edgechars.pop()
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   323
    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
   324
    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
   325
    while len(lines) < minlines + shift_size:
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   326
        lines.append(extra[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   327
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   328
    if shift_size:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   329
        empties = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   330
        toshift = []
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   331
        first_empty = extra.index(None)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   332
        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
   333
            if c is None:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   334
                empties.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   335
            else:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   336
                toshift.append(i * 2)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   337
        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
   338
        positions = toshift[:]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   339
        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
   340
            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
   341
            for i in range(len(positions)):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   342
                pos = positions[i] - 1
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   343
                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
   344
                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
   345
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   346
    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
   347
    for i, line in enumerate(lines):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   348
        if None not in line:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   349
            continue
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   350
        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
   351
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   352
    # remove edges that ended
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   353
    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
   354
    for parent in remove:
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   355
        del edgemap[parent]
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   356
        seen.remove(parent)
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   357
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   358
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   359
@attr.s
48946
642e31cb55f0 py3: use class X: instead of class X(object):
Gregory Szorc <gregory.szorc@gmail.com>
parents: 48875
diff changeset
   360
class asciistate:
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   361
    """State of ascii() graph rendering"""
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   362
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   363
    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
   364
    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
   365
    lastcoldiff = attr.ib(init=False, default=0)
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   366
    lastindex = attr.ib(init=False, default=0)
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   367
    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
   368
    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
   369
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   370
38150
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   371
def outputgraph(ui, graph):
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   372
    """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
   373
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   374
    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
   375
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   376
    takes the following arguments:
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
    - ui to write to
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   379
    - 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
   380
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   381
    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
   382
    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
   383
    """
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   384
    for (ln, logstr) in graph:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   385
        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
   386
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   387
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   388
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
   389
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
    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
   392
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   393
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
      - 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
   395
      - 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
   396
      - 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
   397
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   398
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
        - 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
   400
      - 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
   401
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   402
      - 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
   403
      - 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
   404
        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
   405
        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
   406
        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
   407
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   408
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   409
    assert -2 < coldiff < 2
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   410
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   411
    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
   412
    # 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
   413
    # 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
   414
    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
   415
    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
   416
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   417
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   418
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   419
        #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   420
        #     | | |        | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   421
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   422
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   423
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
        _fixlongrightedges(edges)
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
    # add_padding_line says whether to rewrite
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
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   429
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   430
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   431
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   432
    #                    o | |
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   433
    add_padding_line = (
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   434
        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
   435
    )
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   436
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   437
    # fix_nodeline_tail says whether to rewrite
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
    #     | | o | |        | | o | |
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 | |    into  | o / /   # <--- fixed nodeline tail
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 | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
    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
   445
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
    # 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
   447
    nodeline = echars[: idx * 2]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   448
    nodeline.extend([char, b" "])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   449
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   450
    nodeline.extend(
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   451
        _getnodelineedgestail(
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   452
            echars,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   453
            idx,
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   454
            state.lastindex,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   455
            ncols,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   456
            coldiff,
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   457
            state.lastcoldiff,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   458
            fix_nodeline_tail,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   459
        )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   460
    )
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   461
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   462
    # 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
   463
    # edges between this entry and the next
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   464
    shift_interline = echars[: idx * 2]
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   465
    for i in range(2 + coldiff):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   466
        shift_interline.append(b' ')
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   467
    count = ncols - idx - 1
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   468
    if coldiff == -1:
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   469
        for i in range(count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   470
            shift_interline.extend([b'/', b' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   471
    elif coldiff == 0:
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   472
        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
   473
    else:
49284
d44e3c45f0e4 py3: replace `pycompat.xrange` by `range`
Manuel Jacob <me@manueljacob.de>
parents: 48946
diff changeset
   474
        for i in range(count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   475
            shift_interline.extend([b'\\', b' '])
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   476
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   477
    # 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
   478
    _drawedges(echars, edges, nodeline, shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   479
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   480
    # 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
   481
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   482
    if add_padding_line:
28600
0d6137891114 graphmod: allow for different styles for different edge types
Martijn Pieters <mjpieters@fb.com>
parents: 28376
diff changeset
   483
        lines.append(_getpaddingline(echars, idx, ncols, edges))
28891
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   484
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   485
    # If 'graphshorten' config, only draw shift_interline
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   486
    # 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
   487
    if state.graphshorten:
41536
fb9e11fdcbba graphmod: use raw string
Gregory Szorc <gregory.szorc@gmail.com>
parents: 39286
diff changeset
   488
        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
   489
            lines.append(shift_interline)
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   490
    # Else, no 'graphshorten' config so draw shift_interline.
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   491
    else:
ac30adb260ea graphmod: shorten graph
santiagopim <santiagopim@gmail.com>
parents: 28627
diff changeset
   492
        lines.append(shift_interline)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   493
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   494
    # 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
   495
    # log strings
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42307
diff changeset
   496
    extra_interline = echars[: (ncols + coldiff) * 2]
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   497
    if len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   498
        while len(lines) < len(text):
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   499
            lines.append(extra_interline[:])
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   500
39286
3c4b2e880273 log: respect graphshorten on terminal nodes (collapsing o-~ to just o~)
Kyle Lippincott <spectral@google.com>
parents: 38783
diff changeset
   501
    _drawendinglines(lines, extra_interline, edgemap, seen, state)
28601
cd10171d6c71 graphmod: allow edges to end early
Martijn Pieters <mjpieters@fb.com>
parents: 28600
diff changeset
   502
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   503
    while len(text) < len(lines):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   504
        text.append(b"")
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   505
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   506
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   507
    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
   508
    lines = [
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   509
        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
   510
    ]
38150
24e517600b29 graph: add outputgraph() function, called by ascii() to print
John Stiles <johnstiles@gmail.com>
parents: 36180
diff changeset
   511
    outputgraph(ui, zip(lines, text))
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   512
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   513
    # ... and start over
43776
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   514
    state.lastcoldiff = coldiff
faa8a59f4a06 graphlog: change state dict to attr struct
Yuya Nishihara <yuya@tcha.org>
parents: 43077
diff changeset
   515
    state.lastindex = idx