mercurial/graphmod.py
author Anton Shestakov <av6@dwimlabs.net>
Fri, 11 Mar 2016 20:18:41 +0800
changeset 28467 bd37f0d53a49
parent 28376 fa2cd0c9a567
child 28600 0d6137891114
permissions -rw-r--r--
verify: specify unit for ui.progress when checking files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# Revision graph generator for Mercurial
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
#
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     4
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10084
diff changeset
     7
# GNU General Public License version 2 or any later version.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     8
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
     9
"""supports walking the history as DAGs suitable for graphical output
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    10
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    11
The most basic format we use is that of::
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    12
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    13
  (id, type, data, [parentids])
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    14
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    15
The node and parent ids are arbitrary integers which identify a node in the
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    16
context of the graph returned. Type is a constant specifying the node type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    17
Data depends on type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    18
"""
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    19
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    20
from __future__ import absolute_import
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    21
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    22
import heapq
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    23
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    24
from .node import nullrev
26003
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    25
from . import (
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    26
    revset,
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    27
    util,
62371c539c89 revset: remove grandparent by using reachableroots
Laurent Charignon <lcharignon@fb.com>
parents: 25951
diff changeset
    28
)
25951
69751804f2f5 graphmod: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 24180
diff changeset
    29
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    30
CHANGESET = 'C'
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    31
PARENT = 'P'
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    32
GRANDPARENT = 'G'
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
    33
MISSINGPARENT = 'M'
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    34
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    35
def groupbranchiter(revs, parentsfunc, firstbranch=()):
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    36
    """Yield revisions from heads to roots one (topo) branch at a time.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    37
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    38
    This function aims to be used by a graph generator that wishes to minimize
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    39
    the number of parallel branches and their interleaving.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    40
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    41
    Example iteration order (numbers show the "true" order in a changelog):
23564
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  4
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
      o  1
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    46
      |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    47
      | o  3
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
      | o  2
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
      o  0
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    52
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    53
    Note that the ancestors of merges are understood by the current
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    54
    algorithm to be on the same branch. This means no reordering will
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    55
    occur behind a merge.
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    56
    """
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    57
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    58
    ### 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
    59
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    60
    # 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
    61
    # in memory until we are ready to emit a whole branch that immediately
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    62
    # "merges" into an existing one. This reduces the number of parallel
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    63
    # branches with interleaved revisions.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    64
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    65
    # 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
    66
    # A) revision already emitted
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    67
    # 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
    68
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    69
    # for each REV, we do the following logic:
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    70
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    71
    #   1) if REV is a parent of (A), we will emit it. If there is a
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    72
    #   retention group ((B) above) that is blocked on REV being
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    73
    #   available, we emit all the revisions out of that retention
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    74
    #   group first.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    75
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    76
    #   2) else, we'll search for a subgroup in (B) awaiting for REV to be
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    77
    #   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
    78
    #   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
    79
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    80
    #   3) finally if no such group existed in (B), we create a new subgroup.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    81
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    82
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    83
    # To bootstrap the algorithm, we emit the tipmost revision (which
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    84
    # puts it in group (A) from above).
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    85
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    86
    revs.sort(reverse=True)
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    87
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    88
    # Set of parents of revision that have been emitted. They can be considered
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    89
    # unblocked as the graph generator is already aware of them so there is no
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    90
    # need to delay the revisions 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
    91
    #
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    92
    # 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
    93
    # set will force all other branches to wait until this branch is ready to be
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    94
    # emitted.
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    95
    unblocked = set(firstbranch)
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    96
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    97
    # list of groups waiting to be displayed, each group is defined by:
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    98
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    99
    #   (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
   100
    #    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
   101
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   102
    # 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
   103
    # 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
   104
    # 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
   105
    # revision.  This means waiting for the moment we are about to display
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   106
    # these parents to display the revs in a group.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   107
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   108
    # This first implementation is smart until it encounters a merge: it will
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   109
    # emit revs as soon as any parent is about to be emitted and can grow an
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   110
    # arbitrary number of revs in 'blocked'. In practice this mean we properly
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   111
    # retains new branches but gives up on any special ordering for ancestors
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   112
    # of merges. The implementation can be improved to handle this better.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   113
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   114
    # The first subgroup is special. It corresponds to all the revision that
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   115
    # 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
   116
    # '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
   117
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   118
    # 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
   119
    # 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
   120
    groups = [([], unblocked)]
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   121
    pendingheap = []
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   122
    pendingset = set()
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   123
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   124
    heapq.heapify(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   125
    heappop = heapq.heappop
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   126
    heappush = heapq.heappush
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   127
    for currentrev in revs:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   128
        # 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
   129
        if currentrev not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   130
            heappush(pendingheap, -currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   131
            pendingset.add(currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   132
        # iterates on pending rev until after the current rev have been
24180
d8e0c591781c spelling: fixes from proofreading of spell checker issues
Mads Kiilerich <madski@unity3d.com>
parents: 23570
diff changeset
   133
        # processed.
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   134
        rev = None
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   135
        while rev != currentrev:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   136
            rev = -heappop(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   137
            pendingset.remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   138
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   139
            # 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
   140
            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
   141
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   142
            if matching:
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   143
                # The main idea is to gather together all sets that are blocked
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   144
                # on the same revision.
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   145
                #
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   146
                # Groups are merged when a common blocking ancestor is
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   147
                # observed. For example, given two groups:
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   148
                #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   149
                # revs [5, 4] waiting for 1
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   150
                # revs [3, 2] waiting for 1
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   151
                #
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   152
                # These two groups will be merged when we process
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   153
                # 1. In theory, we could have merged the groups when
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   154
                # we added 2 to the group it is now in (we could have
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   155
                # noticed the groups were both blocked on 1 then), but
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   156
                # the way it works now makes the algorithm simpler.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   157
                #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   158
                # We also always keep the oldest subgroup first. We can
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   159
                # probably improve the behavior by having the longest set
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   160
                # first. That way, graph algorithms could minimise the length
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   161
                # of parallel lines their drawing. This is currently not done.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   162
                targetidx = matching.pop(0)
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   163
                trevs, tparents = groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   164
                for i in matching:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   165
                    gr = groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   166
                    trevs.extend(gr[0])
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   167
                    tparents |= gr[1]
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   168
                # delete all merged subgroups (except the one we kept)
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   169
                # (starting from the last subgroup for performance and
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   170
                # sanity reasons)
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   171
                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
   172
                    del groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   173
            else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   174
                # 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
   175
                targetidx = len(groups)
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   176
                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
   177
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   178
            gr = groups[targetidx]
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   179
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   180
            # We now add the current nodes to this subgroups. This is done
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   181
            # after the subgroup merging because all elements from a subgroup
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   182
            # that relied on this rev must precede it.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   183
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   184
            # we also update the <parents> set to include the parents of the
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   185
            # new nodes.
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   186
            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
   187
                gr[0].append(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   188
            gr[1].remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   189
            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
   190
            gr[1].update(parents)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   191
            for p in parents:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   192
                if p not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   193
                    pendingset.add(p)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   194
                    heappush(pendingheap, -p)
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
            # 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
   197
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   198
            # When unblocked is empty (if clause), we were not waiting for any
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   199
            # revisions during the first iteration (if no priority was given) or
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   200
            # if we emitted a whole disconnected set of the graph (reached a
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   201
            # root).  In that case we arbitrarily take the oldest known
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   202
            # subgroup. The heuristic could probably be better.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   203
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   204
            # Otherwise (elif clause) if the subgroup is blocked on
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   205
            # a revision we just emitted, we can safely emit it as
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   206
            # well.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   207
            if not unblocked:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   208
                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
   209
                    targetidx = 1
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   210
                    gr = groups[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   211
            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
   212
                gr = None
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   213
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   214
            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
   215
                # 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
   216
                # subgroup
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   217
                unblocked |= gr[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   218
                # 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
   219
                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
   220
                    yield r
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   221
                # 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
   222
                # 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
   223
                if targetidx:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   224
                    del groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   225
                else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   226
                    gr[0][:] = []
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   227
    # Check if we have some subgroup waiting for revisions we are not going to
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   228
    # iterate over
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   229
    for g in groups:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   230
        for r in g[0]:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   231
            yield r
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   232
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   233
def dagwalker(repo, revs):
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   234
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentinfo]) tuples
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   235
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   236
    This generator function walks through revisions (which should be ordered
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   237
    from bigger to lower). It returns a tuple for each node.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   238
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   239
    Each parentinfo entry is a tuple with (edgetype, parentid), where edgetype
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   240
    is one of PARENT, GRANDPARENT or MISSINGPARENT. The node and parent ids
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   241
    are arbitrary integers which identify a node in the context of the graph
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   242
    returned.
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   243
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
   244
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   245
    if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   246
        return
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   247
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   248
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   249
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   250
    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
   251
        firstbranch = ()
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   252
        firstbranchrevset = repo.ui.config(
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   253
            '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
   254
        if firstbranchrevset:
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   255
            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
   256
        parentrevs = repo.changelog.parentrevs
26092
014044dbd4e8 graphmod: stop building a list out of branchgroupiter
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26003
diff changeset
   257
        revs = groupbranchiter(revs, parentrevs, firstbranch)
014044dbd4e8 graphmod: stop building a list out of branchgroupiter
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26003
diff changeset
   258
        revs = revset.baseset(revs)
23565
996c01bfbec4 graphlog: add a way to test the 'groupbranchiter' function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23564
diff changeset
   259
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   260
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   261
        ctx = repo[rev]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   262
        # partition into parents in the rev set and missing parents, then
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   263
        # augment the lists with markers, to inform graph drawing code about
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   264
        # what kind of edge to draw between nodes.
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   265
        pset = set(p.rev() for p in ctx.parents() if p.rev() in revs)
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   266
        mpars = [p.rev() for p in ctx.parents()
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   267
                 if p.rev() != nullrev and p.rev() not in pset]
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   268
        parents = [(PARENT, p) for p in sorted(pset)]
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   269
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   270
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   271
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   272
            if gp is None:
26187
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
   273
                # precompute slow query as we know reachableroots() goes
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
   274
                # through all revs (issue4782)
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
   275
                if not isinstance(revs, revset.baseset):
9cf65f43b49b graphmod: compute slow revset query once prior to reachableroots (issue4782)
Yuya Nishihara <yuya@tcha.org>
parents: 26092
diff changeset
   276
                    revs = revset.baseset(revs)
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   277
                gp = gpcache[mpar] = sorted(set(revset.reachableroots(
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   278
                    repo, revs, [mpar])))
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   279
            if not gp:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   280
                parents.append((MISSINGPARENT, mpar))
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   281
                pset.add(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   282
            else:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   283
                parents.extend((GRANDPARENT, g) for g in gp if g not in pset)
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   284
                pset.update(gp)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   285
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   286
        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
   287
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   288
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
   289
    """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
   290
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
   291
    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
   292
    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
   293
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   294
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   295
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   296
        ctx = repo[node]
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   297
        parents = set((PARENT, p.rev()) for p in ctx.parents()
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   298
                      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
   299
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   300
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   301
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   302
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   303
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   304
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   305
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   306
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   307
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   308
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   309
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   310
      - 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
   311
      - 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
   312
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   313
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   314
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   315
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   316
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   317
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   318
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   319
    for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   320
        if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   321
            branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   322
            # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   323
            if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   324
                config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   325
            elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   326
                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
   327
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   328
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   329
        getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   330
            lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   331
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   332
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   333
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   334
    for (cur, type, data, parents) in dag:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   335
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   336
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   337
        if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   338
            seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   339
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   340
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   341
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   342
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   343
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   344
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   345
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   346
        # Add parents to next
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   347
        addparents = [p for pt, 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
   348
        next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   349
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   350
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   351
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   352
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   353
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   354
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   355
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   356
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   357
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   358
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   359
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   360
        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
   361
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   362
                bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   363
                edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   364
                    ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   365
                    bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   366
                    bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   367
            elif eid == cur:
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   368
                for ptype, p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   369
                    bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   370
                    edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   371
                        ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   372
                        bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   373
                        bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   374
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   375
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   376
        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
   377
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   378
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   379
def asciiedges(type, char, lines, state, rev, parents):
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   380
    """adds edge info to changelog DAG walk suitable for ascii()"""
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   381
    seen = state['seen']
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   382
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   383
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   384
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   385
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   386
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   387
    newparents = []
28376
fa2cd0c9a567 graphmod: augment the graph to include more information about the edges
Martijn Pieters <mjpieters@fb.com>
parents: 28375
diff changeset
   388
    for ptype, parent in parents:
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   389
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   392
            newparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   393
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
    ncols = len(seen)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   395
    nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   396
    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
   397
    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
   398
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   400
        # 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
   401
        # 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
   402
        # 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
   403
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   404
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   405
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   406
        nmorecols = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   407
        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
   408
        char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   409
        lines = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   410
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   411
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   412
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   413
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   414
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   415
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   416
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   417
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   418
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   419
    nmorecols = len(nextseen) - ncols
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   420
    seen[:] = nextseen
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   421
    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
   422
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   423
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   425
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   426
            edges[i] = (start, end + 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   427
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   428
def _getnodelineedgestail(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   429
        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
   430
    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
   431
        # 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
   432
        if n_columns_diff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   433
            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
   434
            tail = ["|", " "] * (start - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   435
            tail.extend(["/", " "] * (n_columns - start))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   436
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   437
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   438
            return ["\\", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   439
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   440
        return ["|", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   441
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   442
def _drawedges(edges, nodeline, interline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   443
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
        if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   445
            interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
        elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   447
            interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   448
        elif start == end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   449
            interline[2 * start] = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   450
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   451
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   452
                continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   453
            nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   454
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   455
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   456
            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
   457
                if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   458
                    nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   459
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   460
def _getpaddingline(ni, n_columns, edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   461
    line = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   462
    line.extend(["|", " "] * ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   463
    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
   464
        # (ni, ni - 1)      (ni, ni)
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
        # +---o |           | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   467
        # | | c |           | c | |
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
        # | | |             | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   470
        c = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   471
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   472
        c = " "
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   473
    line.extend([c, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   474
    line.extend(["|", " "] * (n_columns - ni - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   475
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   476
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   477
def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   478
    """returns the initial value for the "state" argument to ascii()"""
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   479
    return {'seen': [], 'lastcoldiff': 0, 'lastindex': 0}
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   480
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   481
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
   482
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   483
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   484
    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
   485
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   486
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   487
      - 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
   488
      - 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
   489
      - 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
   490
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   491
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   492
        - 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
   493
      - 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
   494
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   495
      - 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
   496
      - 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
   497
        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
   498
        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
   499
        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
   500
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   501
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   502
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   503
    assert -2 < coldiff < 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   504
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   505
        # Transform
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   506
        #
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
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   509
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   510
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   511
        _fixlongrightedges(edges)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   512
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   513
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   514
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   515
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   516
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   517
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   518
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   519
    #                    o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   520
    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
   521
                        [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
   522
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   523
    # fix_nodeline_tail says whether to rewrite
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
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   526
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   527
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   528
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   529
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   530
    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
   531
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   532
    # 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
   533
    nodeline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   534
    nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   535
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   536
    nodeline.extend(
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   537
        _getnodelineedgestail(idx, state['lastindex'], ncols, coldiff,
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   538
                              state['lastcoldiff'], fix_nodeline_tail))
17179
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
    # 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
   541
    # edges between this entry and the next
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   542
    shift_interline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   543
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   544
        n_spaces = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   545
        edge_ch = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   546
    elif coldiff == 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   547
        n_spaces = 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   548
        edge_ch = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   549
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   550
        n_spaces = 3
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   551
        edge_ch = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   552
    shift_interline.extend(n_spaces * [" "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   553
    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
   554
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   555
    # 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
   556
    _drawedges(edges, nodeline, shift_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
    # 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
   559
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   560
    if add_padding_line:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   561
        lines.append(_getpaddingline(idx, ncols, edges))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   562
    lines.append(shift_interline)
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
    # 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
   565
    # log strings
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   566
    while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   567
        text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   568
    if len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   569
        extra_interline = ["|", " "] * (ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   570
        while len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   571
            lines.append(extra_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   572
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   573
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   574
    indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   575
    for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   576
        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
   577
        ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   578
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   579
    # ... and start over
28375
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   580
    state['lastcoldiff'] = coldiff
97cb1aeaca78 graphmod: refactor state handling
Martijn Pieters <mjpieters@fb.com>
parents: 26187
diff changeset
   581
    state['lastindex'] = idx