mercurial/graphmod.py
author Augie Fackler <raf@durin42.com>
Mon, 08 Dec 2014 15:20:28 -0500
changeset 23569 3ecbcffdeb0c
parent 23568 740ae54573a3
child 23570 3f86fe9bcef0
permissions -rw-r--r--
graphmod: rename graph-topological config to graph-group-branches The latter suggests what the change is slightly better.
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
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    23
import heapq
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    24
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    25
CHANGESET = 'C'
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    26
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    27
def groupbranchiter(revs, parentsfunc, firstbranch=()):
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    28
    """yield revision from heads to roots one (topo) branch after the other.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    29
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    30
    This function aims to be used by a graph generator that wishes to minimize
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    31
    the amount of parallel branches and their interleaving.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    32
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    33
    Example iteration order:
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    34
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    35
      o  4
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    36
      |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    37
      o  1
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    38
      |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    39
      | o  3
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    40
      | |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    41
      | o  2
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    42
      |/
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    43
      o  0
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    44
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    45
    Currently consider every changeset under a merge to be on the same branch
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    46
    using revision number to sort them.
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    47
    """
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    48
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    49
    ### Quick summary of the algorithm
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    50
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    51
    # This function is based around a "retention" principle. We keep revisions
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    52
    # in memory until we are ready to emit a whole branch that immediately
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    53
    # "merge" into an existing one. This reduce the number of branch "ongoing"
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    54
    # at the same time.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    55
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    56
    # During iteration revs are split into two groups:
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    57
    # A) revision already emitted
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    58
    # B) revision in "retention". They are stored as different subgroups.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    59
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    60
    # for each REV, we do the follow logic:
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    61
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    62
    #   a) if REV is a parent of (A), we will emit it. But before emitting it,
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    63
    #   we'll "free" all the revs from subgroup in (B) that were waiting for
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    64
    #   REV to be available. So we emit all revision of such subgroup before
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    65
    #   emitting REV
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    66
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    67
    #   b) else, we'll search for a subgroup in (B) awaiting for REV to be
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    68
    #   available, if such subgroup exist, we add REV to it and the subgroup is
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    69
    #   now awaiting for REV.parents() to be available.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    70
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    71
    #   c) finally if no such group existed in (B), we create a new subgroup.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    72
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    73
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    74
    # To bootstrap the algorithm, we emit the tipmost revision.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    75
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    76
    revs.sort(reverse=True)
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    77
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    78
    # Set of parents of revision that have been yield. They can be considered
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    79
    # unblocked as the graph generator is already aware of them so there is no
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    80
    # need to delay the one that reference them.
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    81
    #
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    82
    # If someone wants to prioritize a branch over the others, pre-filling this
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    83
    # set will force all other branches to wait until this branch is ready to be
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    84
    # outputed.
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    85
    unblocked = set(firstbranch)
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    86
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    87
    # list of group waiting to be displayed, each group is defined by:
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    88
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    89
    #   (revs:    lists of revs waiting to be displayed,
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    90
    #    blocked: set of that cannot be displayed before those in 'revs')
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    91
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    92
    # The second value ('blocked') correspond to parents of any revision in the
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    93
    # group ('revs') that is not itself contained in the group. The main idea
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    94
    # of this algorithm is to delay as much as possible the emission of any
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    95
    # revision.  This means waiting for the moment we are about to display
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    96
    # theses parents to display the revs in a group.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    97
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    98
    # This first implementation is smart until it meet a merge: it will emit
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    99
    # revs as soon as any parents is about to be emitted and can grow an
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   100
    # arbitrary number of revs in 'blocked'. In practice this mean we properly
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   101
    # retains new branches but give up on any special ordering for ancestors of
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   102
    # merges. The implementation can be improved to handle this better.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   103
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   104
    # The first subgroup is special. It correspond to all the revision that
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   105
    # were already emitted. The 'revs' lists is expected to be empty and the
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   106
    # 'blocked' set contains the parents revisions of already emitted revision.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   107
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   108
    # You could pre-seed the <parents> set of groups[0] to a specific
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   109
    # changesets to select what the first emitted branch should be.
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   110
    groups = [([], unblocked)]
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   111
    pendingheap = []
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   112
    pendingset = set()
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   113
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   114
    heapq.heapify(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   115
    heappop = heapq.heappop
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   116
    heappush = heapq.heappush
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   117
    for currentrev in revs:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   118
        # Heap works with smallest element, we want highest so we invert
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   119
        if currentrev not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   120
            heappush(pendingheap, -currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   121
            pendingset.add(currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   122
        # iterates on pending rev until after the current rev have been
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   123
        # processeed.
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   124
        rev = None
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   125
        while rev != currentrev:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   126
            rev = -heappop(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   127
            pendingset.remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   128
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   129
            # Seek for a subgroup blocked, waiting for the current revision.
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   130
            matching = [i for i, g in enumerate(groups) if rev in g[1]]
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   131
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   132
            if matching:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   133
                # The main idea is to gather together all sets that await on
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   134
                # the same revision.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   135
                #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   136
                # This merging is done at the time we are about to add this
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   137
                # common awaited to the subgroup for simplicity purpose. Such
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   138
                # merge could happen sooner when we update the "blocked" set of
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   139
                # revision.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   140
                #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   141
                # We also always keep the oldest subgroup first. We can
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   142
                # probably improve the behavior by having the longuest set
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   143
                # first. That way, graph algorythms could minimise the length
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   144
                # of parallele lines their draw. This is currently not done.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   145
                targetidx = matching.pop(0)
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   146
                trevs, tparents = groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   147
                for i in matching:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   148
                    gr = groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   149
                    trevs.extend(gr[0])
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   150
                    tparents |= gr[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   151
                # delete all merged subgroups (but the one we keep) (starting
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   152
                # from the last subgroup for performance and sanity reason)
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   153
                for i in reversed(matching):
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   154
                    del groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   155
            else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   156
                # This is a new head. We create a new subgroup for it.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   157
                targetidx = len(groups)
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   158
                groups.append(([], set([rev])))
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   159
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   160
            gr = groups[targetidx]
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   161
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   162
            # We now adds the current nodes to this subgroups. This is done
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   163
            # after the subgroup merging because all elements from a subgroup
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   164
            # that relied on this rev must preceed it.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   165
            #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   166
            # we also update the <parents> set to includes the parents on the
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   167
            # new nodes.
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   168
            if rev == currentrev: # only display stuff in rev
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   169
                gr[0].append(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   170
            gr[1].remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   171
            parents = [p for p in parentsfunc(rev) if p > nullrev]
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   172
            gr[1].update(parents)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   173
            for p in parents:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   174
                if p not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   175
                    pendingset.add(p)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   176
                    heappush(pendingheap, -p)
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   177
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   178
            # Look for a subgroup to display
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   179
            #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   180
            # When unblocked is empty (if clause), We are not waiting over any
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   181
            # revision during the first iteration (if no priority was given) or
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   182
            # if we outputed a whole disconnected sets of the graph (reached a
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   183
            # root).  In that case we arbitrarily takes the oldest known
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   184
            # subgroup. The heuristique could probably be better.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   185
            #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   186
            # Otherwise (elif clause) this mean we have some emitted revision.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   187
            # if the subgroup awaits on the same revision that the outputed
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   188
            # ones, we can safely output it.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   189
            if not unblocked:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   190
                if len(groups) > 1:  # display other subset
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   191
                    targetidx = 1
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   192
                    gr = groups[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   193
            elif not gr[1] & unblocked:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   194
                gr = None
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   195
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   196
            if gr is not None:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   197
                # update the set of awaited revisions with the one from the
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   198
                # subgroup
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   199
                unblocked |= gr[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   200
                # output all revisions in the subgroup
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   201
                for r in gr[0]:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   202
                    yield r
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   203
                # delete the subgroup that you just output
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   204
                # unless it is groups[0] in which case you just empty it.
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   205
                if targetidx:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   206
                    del groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   207
                else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   208
                    gr[0][:] = []
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   209
    # Check if we have some subgroup waiting for revision we are not going to
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   210
    # iterate over
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   211
    for g in groups:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   212
        for r in g[0]:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   213
            yield r
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   214
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   215
def dagwalker(repo, revs):
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   216
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   217
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   218
    This generator function walks through revisions (which should be ordered
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   219
    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
   220
    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
   221
    returned.
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
   222
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   223
    if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   224
        return
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   225
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   226
    cl = repo.changelog
20762
e87bd3485a07 graphmod: changed code in dagwalker to use lazy implementations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 18467
diff changeset
   227
    lowestrev = revs.min()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   228
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   229
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   230
    if repo.ui.configbool('experimental', 'graph-group-branches', False):
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   231
        firstbranch = ()
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   232
        firstbranchrevset = repo.ui.config(
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   233
            'experimental', 'graph-group-branches.firstbranch', '')
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   234
        if firstbranchrevset:
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   235
            firstbranch = repo.revs(firstbranchrevset)
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   236
        parentrevs = repo.changelog.parentrevs
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   237
        revs = list(groupbranchiter(revs, parentrevs, firstbranch))
23565
996c01bfbec4 graphlog: add a way to test the 'groupbranchiter' function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23564
diff changeset
   238
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   239
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   240
        ctx = repo[rev]
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
   241
        parents = sorted(set([p.rev() for p in ctx.parents()
23006
bb1bd9ee323d dagwalker: drop a useless intermediate variable
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22878
diff changeset
   242
                              if p.rev() in revs]))
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   243
        mpars = [p.rev() for p in ctx.parents() if
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   244
                 p.rev() != nullrev and p.rev() not in parents]
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   245
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   246
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   247
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   248
            if gp is None:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   249
                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
   250
            if not gp:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   251
                parents.append(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   252
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   253
                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
   254
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   255
        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
   256
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   257
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
   258
    """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
   259
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
   260
    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
   261
    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
   262
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   263
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   264
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   265
        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
   266
        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
   267
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   268
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   269
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   270
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   271
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   272
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   273
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   274
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   275
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   276
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   277
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   278
      - 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
   279
      - 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
   280
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   281
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   282
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   283
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   284
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   285
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   286
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   287
    for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   288
        if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   289
            branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   290
            # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   291
            if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   292
                config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   293
            elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   294
                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
   295
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   296
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   297
        getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   298
            lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   299
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   300
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   301
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   302
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   303
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   304
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   305
        if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   306
            seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   307
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   308
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   309
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   310
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   311
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   312
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   313
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   314
        # Add parents to next
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   315
        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
   316
        next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   317
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   318
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   319
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   320
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   321
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   322
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   323
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   324
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   325
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   326
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   327
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   328
        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
   329
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   330
                bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   331
                edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   332
                    ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   333
                    bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   334
                    bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   335
            elif eid == cur:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   336
                for p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   337
                    bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   338
                    edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   339
                        ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   340
                        bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   341
                        bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   342
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   343
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   344
        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
   345
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   346
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   347
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
   348
    """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
   349
    greater or equal to lowestrev.
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   350
    """
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   351
    pending = set([head])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   352
    seen = set()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   353
    kept = set()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   354
    llowestrev = max(nullrev, lowestrev)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   355
    while pending:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   356
        r = pending.pop()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   357
        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
   358
            if r in roots:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   359
                kept.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   360
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   361
                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
   362
            seen.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   363
    return sorted(kept)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   364
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   365
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
   366
    """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
   367
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   368
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   369
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   370
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   371
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   372
    newparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   373
    for parent in parents:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   374
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   375
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   376
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   377
            newparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   378
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   379
    ncols = len(seen)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   380
    nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   381
    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
   382
    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
   383
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   384
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   385
        # 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
   386
        # 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
   387
        # 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
   388
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   389
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
        nmorecols = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   392
        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
   393
        char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
        lines = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   395
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   396
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   397
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   398
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   400
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   401
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   402
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   403
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   404
    nmorecols = len(nextseen) - ncols
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   405
    seen[:] = nextseen
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   406
    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
   407
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   408
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   409
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   410
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   411
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   412
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   413
def _getnodelineedgestail(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   414
        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
   415
    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
   416
        # 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
   417
        if n_columns_diff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   418
            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
   419
            tail = ["|", " "] * (start - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   420
            tail.extend(["/", " "] * (n_columns - start))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   421
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   422
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   423
            return ["\\", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   425
        return ["|", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   426
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   427
def _drawedges(edges, nodeline, interline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   428
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   429
        if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   430
            interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   431
        elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   432
            interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   433
        elif start == end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   434
            interline[2 * start] = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   435
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   436
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   437
                continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   438
            nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   439
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   440
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   441
            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
   442
                if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   443
                    nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   445
def _getpaddingline(ni, n_columns, edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
    line = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   447
    line.extend(["|", " "] * ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   448
    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
   449
        # (ni, ni - 1)      (ni, ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   450
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   451
        # +---o |           | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   452
        # | | c |           | c | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   453
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   454
        # | | |             | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   455
        c = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   456
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   457
        c = " "
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   458
    line.extend([c, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   459
    line.extend(["|", " "] * (n_columns - ni - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   460
    return line
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
def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   463
    """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
   464
    return [0, 0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   465
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   466
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
   467
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   468
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   469
    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
   470
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   471
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   472
      - 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
   473
      - 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
   474
      - 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
   475
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   476
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   477
        - 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
   478
      - 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
   479
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   480
      - 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
   481
      - 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
   482
        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
   483
        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
   484
        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
   485
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   486
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   487
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   488
    assert -2 < coldiff < 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   489
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   490
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   491
        #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   492
        #     | | |        | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   493
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   494
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   495
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   496
        _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   497
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   498
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   499
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   500
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   501
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   502
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   503
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   504
    #                    o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   505
    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
   506
                        [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
   507
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   508
    # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   509
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   510
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   511
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   512
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   513
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   514
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   515
    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
   516
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   517
    # 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
   518
    nodeline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   519
    nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   520
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   521
    nodeline.extend(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   522
        _getnodelineedgestail(idx, state[1], ncols, coldiff,
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   523
                              state[0], fix_nodeline_tail))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   524
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   525
    # 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
   526
    # edges between this entry and the next
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   527
    shift_interline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   528
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   529
        n_spaces = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   530
        edge_ch = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   531
    elif coldiff == 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   532
        n_spaces = 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   533
        edge_ch = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   534
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   535
        n_spaces = 3
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   536
        edge_ch = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   537
    shift_interline.extend(n_spaces * [" "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   538
    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
   539
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   540
    # 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
   541
    _drawedges(edges, nodeline, shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   542
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   543
    # 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
   544
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   545
    if add_padding_line:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   546
        lines.append(_getpaddingline(idx, ncols, edges))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   547
    lines.append(shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   548
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   549
    # 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
   550
    # log strings
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   551
    while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   552
        text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   553
    if len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   554
        extra_interline = ["|", " "] * (ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   555
        while len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   556
            lines.append(extra_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   557
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   558
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   559
    indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   560
    for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   561
        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
   562
        ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   563
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   564
    # ... and start over
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   565
    state[0] = coldiff
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   566
    state[1] = idx