mercurial/graphmod.py
author Alexander Plavin <alexander@plav.in>
Fri, 06 Sep 2013 13:30:56 +0400
changeset 19722 bf15935b68a3
parent 18467 e441657b372b
child 20762 e87bd3485a07
permissions -rw-r--r--
hgweb: add revset syntax support to search This mode is used when all the conditions are met: - 'reverse(%s)' % query string can be parsed to a revset tree - this tree has depth more than two, i.e. the query has some part of revset syntax used - the repo can be actually matched against this tree, i.e. it has only existent function/operators and revisions/tags/bookmarks specified are correct - no revset regexes are used in the query (strings which start with 're:') - only functions explicitly marked as safe in revset.py are used in the query Add several new tests for different parsing conditions and exception handling.
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
from mercurial.node import nullrev
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
    21
import util
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    22
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    23
CHANGESET = 'C'
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    24
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    25
def dagwalker(repo, revs):
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    26
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    27
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    28
    This generator function walks through revisions (which should be ordered
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    29
    from bigger to lower). It returns a tuple for each node. The node and parent
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    30
    ids are arbitrary integers which identify a node in the context of the graph
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    31
    returned.
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
    32
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    33
    if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    34
        return
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    35
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    36
    cl = repo.changelog
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    37
    lowestrev = min(revs)
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    38
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    39
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
    40
    knownrevs = set(revs)
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    41
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    42
        ctx = repo[rev]
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
    43
        parents = sorted(set([p.rev() for p in ctx.parents()
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
    44
                              if p.rev() in knownrevs]))
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    45
        mpars = [p.rev() for p in ctx.parents() if
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    46
                 p.rev() != nullrev and p.rev() not in parents]
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    47
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    48
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    49
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    50
            if gp is None:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    51
                gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    52
            if not gp:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    53
                parents.append(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    54
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
    55
                parents.extend(g for g in gp if g not in parents)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
    56
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
    57
        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
    58
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    59
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
    60
    """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
    61
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    62
    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
    63
    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
    64
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    65
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    66
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    67
        ctx = repo[node]
12951
101366ad816c graphmod: safer code when a changeset has two identical parents
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10602
diff changeset
    68
        parents = set([p.rev() for p in ctx.parents() if p.node() in include])
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    69
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
    70
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
    71
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    72
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    73
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    74
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    75
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    76
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    77
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    78
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
    79
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
    80
      - 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
    81
      - 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
    82
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    83
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
    84
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    85
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
    86
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
    87
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
    88
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
    89
    for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    90
        if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    91
            branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    92
            # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    93
            if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
    94
                config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    95
            elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
    96
                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
    97
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
    98
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
    99
        getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   100
            lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   101
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   102
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   103
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   104
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   105
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   106
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   107
        if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   108
            seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   109
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   110
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   111
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   112
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   113
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   114
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   115
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   116
        # Add parents to next
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   117
        addparents = [p for p in parents if p not in next]
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   118
        next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   119
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   120
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   121
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   122
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   123
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   124
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   125
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   126
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   127
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   128
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   129
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   130
        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
   131
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   132
                bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   133
                edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   134
                    ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   135
                    bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   136
                    bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   137
            elif eid == cur:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   138
                for p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   139
                    bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   140
                    edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   141
                        ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   142
                        bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   143
                        bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   144
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   145
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   146
        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
   147
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   148
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   149
def grandparent(cl, lowestrev, roots, head):
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   150
    """Return all ancestors of head in roots which revision is
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   151
    greater or equal to lowestrev.
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   152
    """
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   153
    pending = set([head])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   154
    seen = set()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   155
    kept = set()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   156
    llowestrev = max(nullrev, lowestrev)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   157
    while pending:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   158
        r = pending.pop()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   159
        if r >= llowestrev and r not in seen:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   160
            if r in roots:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   161
                kept.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   162
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   163
                pending.update([p for p in cl.parentrevs(r)])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   164
            seen.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   165
    return sorted(kept)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   166
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   167
def asciiedges(type, char, lines, seen, rev, parents):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   168
    """adds edge info to changelog DAG walk suitable for ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   169
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   170
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   171
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   172
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   173
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   174
    newparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   175
    for parent in parents:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   176
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   177
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   178
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   179
            newparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   180
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   181
    ncols = len(seen)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   182
    nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   183
    nextseen[nodeidx:nodeidx + 1] = newparents
18467
e441657b372b graphmod: don't try to visit nullrev (issue3772)
Bryan O'Sullivan <bryano@fb.com>
parents: 17179
diff changeset
   184
    edges = [(nodeidx, nextseen.index(p)) for p in knownparents if p != nullrev]
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   185
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   186
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   187
        # 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
   188
        # 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
   189
        # 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
   190
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   191
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   192
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   193
        nmorecols = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   194
        yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   195
        char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   196
        lines = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   197
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   198
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   199
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   200
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   201
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   202
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   203
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   204
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   205
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   206
    nmorecols = len(nextseen) - ncols
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   207
    seen[:] = nextseen
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   208
    yield (type, char, lines, (nodeidx, edges, ncols, nmorecols))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   209
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   210
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   211
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   212
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   213
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   214
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   215
def _getnodelineedgestail(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   216
        node_index, p_node_index, n_columns, n_columns_diff, p_diff, fix_tail):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   217
    if fix_tail and n_columns_diff == p_diff and n_columns_diff != 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   218
        # Still going in the same non-vertical direction.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   219
        if n_columns_diff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   220
            start = max(node_index + 1, p_node_index)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   221
            tail = ["|", " "] * (start - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   222
            tail.extend(["/", " "] * (n_columns - start))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   223
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   224
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   225
            return ["\\", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   226
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   227
        return ["|", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   228
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   229
def _drawedges(edges, nodeline, interline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   230
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   231
        if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   232
            interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   233
        elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   234
            interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   235
        elif start == end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   236
            interline[2 * start] = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   237
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   238
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   239
                continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   240
            nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   241
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   242
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   243
            for i in range(2 * start + 1, 2 * end):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   244
                if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   245
                    nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   246
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   247
def _getpaddingline(ni, n_columns, edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   248
    line = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   249
    line.extend(["|", " "] * ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   250
    if (ni, ni - 1) in edges or (ni, ni) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   251
        # (ni, ni - 1)      (ni, ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   252
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   253
        # +---o |           | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   254
        # | | c |           | c | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   255
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   256
        # | | |             | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   257
        c = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   258
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   259
        c = " "
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   260
    line.extend([c, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   261
    line.extend(["|", " "] * (n_columns - ni - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   262
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   263
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   264
def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   265
    """returns the initial value for the "state" argument to ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   266
    return [0, 0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   267
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   268
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
   269
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   270
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   271
    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
   272
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   273
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   274
      - 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
   275
      - 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
   276
      - 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
   277
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   278
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   279
        - 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
   280
      - 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
   281
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   282
      - 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
   283
      - 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
   284
        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
   285
        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
   286
        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
   287
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   288
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   289
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   290
    assert -2 < coldiff < 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   291
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   292
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   293
        #
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 | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   296
        #     |X /         |/ /
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
        _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   299
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   300
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   301
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   302
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   303
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   304
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   305
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   306
    #                    o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   307
    add_padding_line = (len(text) > 2 and coldiff == -1 and
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   308
                        [x for (x, y) in edges if x + 1 < y])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   309
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   310
    # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   311
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   312
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   313
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   314
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   315
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   316
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   317
    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
   318
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   319
    # nodeline is the line containing the node character (typically o)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   320
    nodeline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   321
    nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   322
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   323
    nodeline.extend(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   324
        _getnodelineedgestail(idx, state[1], ncols, coldiff,
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   325
                              state[0], fix_nodeline_tail))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   326
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   327
    # 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
   328
    # edges between this entry and the next
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   329
    shift_interline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   330
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   331
        n_spaces = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   332
        edge_ch = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   333
    elif coldiff == 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   334
        n_spaces = 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   335
        edge_ch = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   336
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   337
        n_spaces = 3
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   338
        edge_ch = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   339
    shift_interline.extend(n_spaces * [" "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   340
    shift_interline.extend([edge_ch, " "] * (ncols - idx - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   341
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   342
    # draw edges from the current node to its parents
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   343
    _drawedges(edges, nodeline, shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   344
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   345
    # 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
   346
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   347
    if add_padding_line:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   348
        lines.append(_getpaddingline(idx, ncols, edges))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   349
    lines.append(shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   350
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   351
    # 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
   352
    # log strings
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   353
    while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   354
        text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   355
    if len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   356
        extra_interline = ["|", " "] * (ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   357
        while len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   358
            lines.append(extra_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   359
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   360
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   361
    indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   362
    for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   363
        ln = "%-*s %s" % (2 * indentation_level, "".join(line), logstr)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   364
        ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   365
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   366
    # ... and start over
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   367
    state[0] = coldiff
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   368
    state[1] = idx