mercurial/graphmod.py
author Eric Sumner <ericsumner@fb.com>
Thu, 18 Dec 2014 12:33:17 -0800
changeset 23633 96c3cbec006f
parent 23570 3f86fe9bcef0
child 24180 d8e0c591781c
permissions -rw-r--r--
incoming: handle phases the same as pull Now that bundlerepo can move phases safely, 'hg incoming' can share its phase handling code with pull to better reflect what would actually show up.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     1
# Revision graph generator for Mercurial
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     2
#
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     3
# Copyright 2008 Dirkjan Ochtman <dirkjan@ochtman.nl>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     4
# Copyright 2007 Joel Rosdahl <joel@rosdahl.net>
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10084
diff changeset
     7
# GNU General Public License version 2 or any later version.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
     8
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
     9
"""supports walking the history as DAGs suitable for graphical output
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    10
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    11
The most basic format we use is that of::
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    12
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    13
  (id, type, data, [parentids])
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    14
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    15
The node and parent ids are arbitrary integers which identify a node in the
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    16
context of the graph returned. Type is a constant specifying the node type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    17
Data depends on type.
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    18
"""
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    19
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    20
from mercurial.node import nullrev
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
    21
import util
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    22
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    23
import heapq
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
    24
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
    25
CHANGESET = 'C'
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
    26
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    27
def groupbranchiter(revs, parentsfunc, firstbranch=()):
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    28
    """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
    29
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    30
    This function aims to be used by a graph generator that wishes to minimize
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    31
    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
    32
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    33
    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
    34
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    35
      o  4
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    36
      |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    37
      o  1
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    38
      |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    39
      | o  3
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    40
      | |
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    41
      | o  2
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    42
      |/
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    43
      o  0
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    44
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    45
    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
    46
    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
    47
    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
    48
    """
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    49
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    50
    ### 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
    51
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    52
    # 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
    53
    # 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
    54
    # "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
    55
    # 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
    56
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    57
    # 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
    58
    # A) revision already emitted
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    59
    # 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
    60
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    61
    # 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
    62
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    63
    #   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
    64
    #   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
    65
    #   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
    66
    #   group first.
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    67
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    68
    #   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
    69
    #   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
    70
    #   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
    71
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    72
    #   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
    73
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    74
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    75
    # 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
    76
    # 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
    77
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    78
    revs.sort(reverse=True)
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
    # 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
    81
    # 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
    82
    # 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
    83
    #
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    84
    # 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
    85
    # 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
    86
    # emitted.
23568
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
    87
    unblocked = set(firstbranch)
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    88
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
    89
    # 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
    90
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    91
    #   (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
    92
    #    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
    93
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
    94
    # 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
    95
    # 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
    96
    # 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
    97
    # 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
    98
    # 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
    99
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   100
    # 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
   101
    # 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
   102
    # 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
   103
    # 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
   104
    # 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
   105
    #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   106
    # 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
   107
    # 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
   108
    # '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
   109
    #
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   110
    # 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
   111
    # 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
   112
    groups = [([], unblocked)]
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   113
    pendingheap = []
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   114
    pendingset = set()
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   115
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   116
    heapq.heapify(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   117
    heappop = heapq.heappop
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   118
    heappush = heapq.heappush
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   119
    for currentrev in revs:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   120
        # 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
   121
        if currentrev not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   122
            heappush(pendingheap, -currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   123
            pendingset.add(currentrev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   124
        # iterates on pending rev until after the current rev have been
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   125
        # processeed.
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   126
        rev = None
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   127
        while rev != currentrev:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   128
            rev = -heappop(pendingheap)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   129
            pendingset.remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   130
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   131
            # 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
   132
            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
   133
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   134
            if matching:
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   135
                # 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
   136
                # on the same revision.
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   137
                #
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   138
                # 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
   139
                # 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
   140
                #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   141
                # revs [5, 4] waiting for 1
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   142
                # revs [3, 2] waiting for 1
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   143
                #
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   144
                # 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
   145
                # 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
   146
                # 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
   147
                # 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
   148
                # 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
   149
                #
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   150
                # 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
   151
                # 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
   152
                # 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
   153
                # 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
   154
                targetidx = matching.pop(0)
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   155
                trevs, tparents = groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   156
                for i in matching:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   157
                    gr = groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   158
                    trevs.extend(gr[0])
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   159
                    tparents |= gr[1]
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   160
                # 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
   161
                # (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
   162
                # sanity reasons)
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   163
                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
   164
                    del groups[i]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   165
            else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   166
                # 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
   167
                targetidx = len(groups)
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   168
                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
   169
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   170
            gr = groups[targetidx]
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   171
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   172
            # 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
   173
            # 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
   174
            # 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
   175
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   176
            # 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
   177
            # new nodes.
23567
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   178
            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
   179
                gr[0].append(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   180
            gr[1].remove(rev)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   181
            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
   182
            gr[1].update(parents)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   183
            for p in parents:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   184
                if p not in pendingset:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   185
                    pendingset.add(p)
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   186
                    heappush(pendingheap, -p)
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   187
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   188
            # 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
   189
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   190
            # 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
   191
            # 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
   192
            # 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
   193
            # 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
   194
            # 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
   195
            #
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   196
            # 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
   197
            # 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
   198
            # well.
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   199
            if not unblocked:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   200
                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
   201
                    targetidx = 1
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   202
                    gr = groups[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   203
            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
   204
                gr = None
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   205
23566
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   206
            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
   207
                # 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
   208
                # subgroup
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   209
                unblocked |= gr[1]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   210
                # 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
   211
                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
   212
                    yield r
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   213
                # 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
   214
                # 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
   215
                if targetidx:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   216
                    del groups[targetidx]
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   217
                else:
fee7a30cfdf5 groubranchhiter: indent most of the inner code
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23565
diff changeset
   218
                    gr[0][:] = []
23570
3f86fe9bcef0 graphmod: attempt to clarify documentation of groupbranchiter()
Augie Fackler <raf@durin42.com>
parents: 23569
diff changeset
   219
    # 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
   220
    # iterate over
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   221
    for g in groups:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   222
        for r in g[0]:
1f080c9c6a35 groupbranchiter: support for non-contiguous revsets
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23566
diff changeset
   223
            yield r
23564
f7ce0837eefd graphmod: add a function for topological iteration
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23006
diff changeset
   224
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   225
def dagwalker(repo, revs):
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   226
    """cset DAG generator yielding (id, CHANGESET, ctx, [parentids]) tuples
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   227
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   228
    This generator function walks through revisions (which should be ordered
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   229
    from bigger to lower). It returns a tuple for each node. The node and parent
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   230
    ids are arbitrary integers which identify a node in the context of the graph
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   231
    returned.
8836
11ff34956ee7 graphmod/graphlog: move log walks to graphmod
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8835
diff changeset
   232
    """
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   233
    if not revs:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   234
        return
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
    cl = repo.changelog
20762
e87bd3485a07 graphmod: changed code in dagwalker to use lazy implementations
Lucas Moscovicz <lmoscovicz@fb.com>
parents: 18467
diff changeset
   237
    lowestrev = revs.min()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   238
    gpcache = {}
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   239
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   240
    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
   241
        firstbranch = ()
23569
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   242
        firstbranchrevset = repo.ui.config(
3ecbcffdeb0c graphmod: rename graph-topological config to graph-group-branches
Augie Fackler <raf@durin42.com>
parents: 23568
diff changeset
   243
            '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
   244
        if firstbranchrevset:
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   245
            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
   246
        parentrevs = repo.changelog.parentrevs
740ae54573a3 groupbranchiter: allow callers to select the first branch
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23567
diff changeset
   247
        revs = list(groupbranchiter(revs, parentrevs, firstbranch))
23565
996c01bfbec4 graphlog: add a way to test the 'groupbranchiter' function
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 23564
diff changeset
   248
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   249
    for rev in revs:
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   250
        ctx = repo[rev]
14088
e83ced8b6464 graphlog: use a set for inclusion test
Patrick Mezard <pmezard@gmail.com>
parents: 14087
diff changeset
   251
        parents = sorted(set([p.rev() for p in ctx.parents()
23006
bb1bd9ee323d dagwalker: drop a useless intermediate variable
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 22878
diff changeset
   252
                              if p.rev() in revs]))
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   253
        mpars = [p.rev() for p in ctx.parents() if
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   254
                 p.rev() != nullrev and p.rev() not in parents]
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   255
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   256
        for mpar in mpars:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   257
            gp = gpcache.get(mpar)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   258
            if gp is None:
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   259
                gp = gpcache[mpar] = grandparent(cl, lowestrev, revs, mpar)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   260
            if not gp:
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   261
                parents.append(mpar)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   262
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   263
                parents.extend(g for g in gp if g not in parents)
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   264
14087
f3d585c9b042 graphmod: restore generator nature of dagwalker
Idan Kamara <idankk86@gmail.com>
parents: 14064
diff changeset
   265
        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
   266
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   267
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
   268
    """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
   269
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
   270
    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
   271
    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
   272
    """
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   273
    include = set(nodes)
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   274
    for node in nodes:
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   275
        ctx = repo[node]
12951
101366ad816c graphmod: safer code when a changeset has two identical parents
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 10602
diff changeset
   276
        parents = set([p.rev() for p in ctx.parents() if p.node() in include])
8840
d9acbe7b0049 graphmod/graphlog: make dag walks carry data as type, payload
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8837
diff changeset
   277
        yield (ctx.rev(), CHANGESET, ctx, sorted(parents))
8837
d8e3a98018cb graphmod/graphlog: extract nodelistwalk
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8836
diff changeset
   278
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   279
def colored(dag, repo):
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   280
    """annotates a DAG with colored edge information
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   281
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   282
    For each DAG node this function emits tuples::
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   283
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   284
      (id, type, data, (col, color), [(col, nextcol, color)])
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   285
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   286
    with the following new elements:
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   287
8835
ec5483efc31f graphmod: code cleanup and doc fix
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8225
diff changeset
   288
      - 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
   289
      - 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
   290
        parents.
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   291
    """
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   292
    seen = []
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   293
    colors = {}
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   294
    newcolor = 1
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   295
    config = {}
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   296
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   297
    for key, val in repo.ui.configitems('graph'):
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   298
        if '.' in key:
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   299
            branch, setting = key.rsplit('.', 1)
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   300
            # Validation
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   301
            if setting == "width" and val.isdigit():
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   302
                config.setdefault(branch, {})[setting] = int(val)
16131
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   303
            elif setting == "color" and val.isalnum():
6f236c8bdc01 graphmod: rewrite graph config validation
Matt Mackall <mpm@selenic.com>
parents: 16130
diff changeset
   304
                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
   305
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   306
    if config:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   307
        getconf = util.lrucachefunc(
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   308
            lambda rev: config.get(repo[rev].branch(), {}))
16132
41fc1e078d68 graphmod: add config cache
Matt Mackall <mpm@selenic.com>
parents: 16131
diff changeset
   309
    else:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   310
        getconf = lambda rev: {}
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   311
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   312
    for (cur, type, data, parents) in dag:
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
        # Compute seen and next
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   315
        if cur not in seen:
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   316
            seen.append(cur) # new head
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   317
            colors[cur] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   318
            newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   319
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   320
        col = seen.index(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   321
        color = colors.pop(cur)
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   322
        next = seen[:]
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   323
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   324
        # Add parents to next
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   325
        addparents = [p for p in parents if p not in next]
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   326
        next[col:col + 1] = addparents
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   327
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   328
        # Set colors for the parents
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   329
        for i, p in enumerate(addparents):
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   330
            if not i:
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   331
                colors[p] = color
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   332
            else:
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   333
                colors[p] = newcolor
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   334
                newcolor += 1
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   335
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   336
        # Add edges to the graph
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   337
        edges = []
8841
94ac080e7af9 graphmod: rename a bunch of vars in graph()
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8840
diff changeset
   338
        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
   339
            if eid in next:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   340
                bconf = getconf(eid)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   341
                edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   342
                    ecol, next.index(eid), colors[eid],
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   343
                    bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   344
                    bconf.get('color', '')))
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   345
            elif eid == cur:
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   346
                for p in parents:
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   347
                    bconf = getconf(p)
16129
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   348
                    edges.append((
5e50982c633c graph: in hgrc specify line width for main branch
Constantine Linnick <theaspect@gmail.com>
parents: 14131
diff changeset
   349
                        ecol, next.index(p), color,
16138
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   350
                        bconf.get('width', -1),
6e4de55a41a4 hgweb: refactor graph customization javascript
Patrick Mezard <patrick@mezard.eu>
parents: 16132
diff changeset
   351
                        bconf.get('color', '')))
6691
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   352
0dba955c2636 add graph page to hgweb
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents:
diff changeset
   353
        # Yield and move on
8842
acd03a6e2426 graphmod/webcommands: use generic DAG walks
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 8841
diff changeset
   354
        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
   355
        seen = next
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   356
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   357
def grandparent(cl, lowestrev, roots, head):
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   358
    """Return all ancestors of head in roots which revision is
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   359
    greater or equal to lowestrev.
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   360
    """
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   361
    pending = set([head])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   362
    seen = set()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   363
    kept = set()
14042
9966c95b8c4f graphmod: use revsets internally
Alexander Solovyov <alexander@solovyov.net>
parents: 12951
diff changeset
   364
    llowestrev = max(nullrev, lowestrev)
14131
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   365
    while pending:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   366
        r = pending.pop()
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   367
        if r >= llowestrev and r not in seen:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   368
            if r in roots:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   369
                kept.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   370
            else:
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   371
                pending.update([p for p in cl.parentrevs(r)])
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   372
            seen.add(r)
03e1c2d35c6a graphmod: correctly emit nodes with more than 2 predecessors
Patrick Mezard <pmezard@gmail.com>
parents: 14088
diff changeset
   373
    return sorted(kept)
17179
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   374
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   375
def asciiedges(type, char, lines, seen, rev, parents):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   376
    """adds edge info to changelog DAG walk suitable for ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   377
    if rev not in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   378
        seen.append(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   379
    nodeidx = seen.index(rev)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   380
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   381
    knownparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   382
    newparents = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   383
    for parent in parents:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   384
        if parent in seen:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   385
            knownparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   386
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   387
            newparents.append(parent)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   388
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   389
    ncols = len(seen)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   390
    nextseen = seen[:]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   391
    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
   392
    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
   393
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   394
    while len(newparents) > 2:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   395
        # 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
   396
        # 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
   397
        # 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
   398
        # slowly.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   399
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   400
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   401
        nmorecols = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   402
        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
   403
        char = '\\'
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   404
        lines = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   405
        nodeidx += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   406
        ncols += 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   407
        edges = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   408
        del newparents[0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   409
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   410
    if len(newparents) > 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   411
        edges.append((nodeidx, nodeidx))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   412
    if len(newparents) > 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   413
        edges.append((nodeidx, nodeidx + 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   414
    nmorecols = len(nextseen) - ncols
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   415
    seen[:] = nextseen
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   416
    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
   417
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   418
def _fixlongrightedges(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   419
    for (i, (start, end)) in enumerate(edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   420
        if end > start:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   421
            edges[i] = (start, end + 1)
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 _getnodelineedgestail(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   424
        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
   425
    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
   426
        # 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
   427
        if n_columns_diff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   428
            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
   429
            tail = ["|", " "] * (start - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   430
            tail.extend(["/", " "] * (n_columns - start))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   431
            return tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   432
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   433
            return ["\\", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   434
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   435
        return ["|", " "] * (n_columns - node_index - 1)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   436
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   437
def _drawedges(edges, nodeline, interline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   438
    for (start, end) in edges:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   439
        if start == end + 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   440
            interline[2 * end + 1] = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   441
        elif start == end - 1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   442
            interline[2 * start + 1] = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   443
        elif start == end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   444
            interline[2 * start] = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   445
        else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   446
            if 2 * end >= len(nodeline):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   447
                continue
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   448
            nodeline[2 * end] = "+"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   449
            if start > end:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   450
                (start, end) = (end, start)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   451
            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
   452
                if nodeline[i] != "+":
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   453
                    nodeline[i] = "-"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   454
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   455
def _getpaddingline(ni, n_columns, edges):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   456
    line = []
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   457
    line.extend(["|", " "] * ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   458
    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
   459
        # (ni, ni - 1)      (ni, ni)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   460
        # | | | |           | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   461
        # +---o |           | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   462
        # | | c |           | c | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   463
        # | |/ /            | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   464
        # | | |             | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   465
        c = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   466
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   467
        c = " "
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   468
    line.extend([c, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   469
    line.extend(["|", " "] * (n_columns - ni - 1))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   470
    return line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   471
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   472
def asciistate():
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   473
    """returns the initial value for the "state" argument to ascii()"""
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   474
    return [0, 0]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   475
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   476
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
   477
    """prints an ASCII graph of the DAG
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   478
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   479
    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
   480
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   481
      - ui to write to
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   482
      - 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
   483
      - 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
   484
      - 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
   485
      - Payload: (char, lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   486
        - Character to use as node's symbol.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   487
        - 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
   488
      - 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
   489
        the current node and its parents.
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   490
      - 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
   491
      - 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
   492
        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
   493
        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
   494
        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
   495
    """
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   496
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   497
    idx, edges, ncols, coldiff = coldata
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   498
    assert -2 < coldiff < 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   499
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   500
        # Transform
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
        #     | | |        | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   503
        #     o | |  into  o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   504
        #     |X /         |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   505
        #     | |          | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   506
        _fixlongrightedges(edges)
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
    # add_padding_line says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   509
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   510
    #     | | | |        | | | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   511
    #     | o---+  into  | o---+
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   512
    #     |  / /         |   | |  # <--- padding line
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   513
    #     o | |          |  / /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   514
    #                    o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   515
    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
   516
                        [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
   517
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   518
    # fix_nodeline_tail says whether to rewrite
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   519
    #
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   520
    #     | | o | |        | | o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   521
    #     | | |/ /         | | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   522
    #     | o | |    into  | o / /   # <--- fixed nodeline tail
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   523
    #     | |/ /           | |/ /
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   524
    #     o | |            o | |
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   525
    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
   526
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   527
    # 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
   528
    nodeline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   529
    nodeline.extend([char, " "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   530
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   531
    nodeline.extend(
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   532
        _getnodelineedgestail(idx, state[1], ncols, coldiff,
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   533
                              state[0], fix_nodeline_tail))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   534
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   535
    # 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
   536
    # edges between this entry and the next
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   537
    shift_interline = ["|", " "] * idx
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   538
    if coldiff == -1:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   539
        n_spaces = 1
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   540
        edge_ch = "/"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   541
    elif coldiff == 0:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   542
        n_spaces = 2
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   543
        edge_ch = "|"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   544
    else:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   545
        n_spaces = 3
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   546
        edge_ch = "\\"
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   547
    shift_interline.extend(n_spaces * [" "])
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   548
    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
   549
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   550
    # 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
   551
    _drawedges(edges, nodeline, shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   552
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   553
    # 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
   554
    lines = [nodeline]
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   555
    if add_padding_line:
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   556
        lines.append(_getpaddingline(idx, ncols, edges))
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   557
    lines.append(shift_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   558
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   559
    # 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
   560
    # log strings
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   561
    while len(text) < len(lines):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   562
        text.append("")
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   563
    if len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   564
        extra_interline = ["|", " "] * (ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   565
        while len(lines) < len(text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   566
            lines.append(extra_interline)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   567
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   568
    # print lines
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   569
    indentation_level = max(ncols, ncols + coldiff)
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   570
    for (line, logstr) in zip(lines, text):
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   571
        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
   572
        ui.write(ln.rstrip() + '\n')
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   573
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   574
    # ... and start over
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   575
    state[0] = coldiff
0849d725e2f9 graphlog: extract ascii drawing code into graphmod
Patrick Mezard <patrick@mezard.eu>
parents: 16138
diff changeset
   576
    state[1] = idx