tests/drawdag.py
author Denis Laxalde <denis@laxalde.org>
Tue, 29 Aug 2017 11:25:22 +0200
changeset 34033 2d80e078724a
parent 33809 0531ffd59a98
child 34212 6c408bfa2dab
permissions -rw-r--r--
tag: use filtered repo when creating new tags (issue5539) When pruning a changeset that added a tag and then adding another tag, the "pruned" tag gets restored. This is because the tag creation step (tags._tag() call in tags.tag()) is currently done on the unfiltered repo. This behavior has been there from 7977d35df13b which backs out b08af8f0ac01 with no clear reason but caution on unthought situations at that time. In this changeset, we pass the filtered repo to tags._tag(), preventing "pruned" tags to reappear. This somehow restores b08af8f0ac01, though now we arguably have a valid use case for.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     1
# drawdag.py - convert ASCII revision DAG to actual changesets
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     2
#
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     3
# Copyright 2016 Facebook, Inc.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     4
#
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     7
"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     8
create changesets from an ASCII graph for testing purpose.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
     9
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    10
For example, given the following input::
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    11
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    12
    c d
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    13
    |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    14
    b
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    15
    |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    16
    a
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    17
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    18
4 changesets and 4 local tags will be created.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    19
`hg log -G -T "{rev} {desc} (tag: {tags})"` will output::
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    20
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    21
    o  3 d (tag: d tip)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    22
    |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    23
    | o  2 c (tag: c)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    24
    |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    25
    o  1 b (tag: b)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    26
    |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    27
    o  0 a (tag: a)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    28
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    29
For root nodes (nodes without parents) in the graph, they can be revsets
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    30
pointing to existing nodes.  The ASCII graph could also have disconnected
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    31
components with same names referring to the same changeset.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    32
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    33
Therefore, given the repo having the 4 changesets (and tags) above, with the
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    34
following ASCII graph as input::
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    35
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    36
    foo    bar       bar  foo
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    37
     |     /          |    |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    38
    ancestor(c,d)     a   baz
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    39
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    40
The result (`hg log -G -T "{desc}"`) will look like::
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    41
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    42
    o    foo
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    43
    |\
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    44
    +---o  bar
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    45
    | | |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    46
    | o |  baz
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    47
    |  /
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    48
    +---o  d
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    49
    | |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    50
    +---o  c
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    51
    | |
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    52
    o |  b
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    53
    |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    54
    o  a
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    55
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    56
Note that if you take the above `hg log` output directly as input. It will work
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    57
as expected - the result would be an isomorphic graph::
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    58
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    59
    o    foo
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    60
    |\
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    61
    | | o  d
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    62
    | |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    63
    | | o  c
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    64
    | |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    65
    | | o  bar
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    66
    | |/|
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    67
    | o |  b
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    68
    | |/
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    69
    o /  baz
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    70
     /
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    71
    o  a
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    72
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    73
This is because 'o' is specially handled in the input: instead of using 'o' as
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    74
the node name, the word to the right will be used.
33159
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    75
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    76
Some special comments could have side effects:
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    77
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    78
    - Create obsmarkers
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    79
      # replace: A -> B -> C -> D  # chained 1 to 1 replacements
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    80
      # split: A -> B, C           # 1 to many
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    81
      # prune: A, B, C             # many to nothing
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    82
"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    83
from __future__ import absolute_import, print_function
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    84
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    85
import collections
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    86
import itertools
33809
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
    87
import re
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    88
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    89
from mercurial.i18n import _
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    90
from mercurial import (
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    91
    context,
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    92
    error,
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    93
    node,
33159
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
    94
    obsolete,
32376
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32345
diff changeset
    95
    registrar,
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    96
    scmutil,
31676
d761ef24d6e1 drawdag: use 'tagsmod.tag' instead of 'repo.tag'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30458
diff changeset
    97
    tags as tagsmod,
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    98
)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
    99
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   100
cmdtable = {}
32376
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32345
diff changeset
   101
command = registrar.command(cmdtable)
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   102
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   103
_pipechars = '\\/+-|'
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   104
_nonpipechars = ''.join(chr(i) for i in xrange(33, 127)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   105
                        if chr(i) not in _pipechars)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   106
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   107
def _isname(ch):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   108
    """char -> bool. return True if ch looks like part of a name, False
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   109
    otherwise"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   110
    return ch in _nonpipechars
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   111
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   112
def _parseasciigraph(text):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   113
    """str -> {str : [str]}. convert the ASCII graph to edges"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   114
    lines = text.splitlines()
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   115
    edges = collections.defaultdict(list)  # {node: []}
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   116
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   117
    def get(y, x):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   118
        """(int, int) -> char. give a coordinate, return the char. return a
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   119
        space for anything out of range"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   120
        if x < 0 or y < 0:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   121
            return ' '
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   122
        try:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   123
            return lines[y][x]
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   124
        except IndexError:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   125
            return ' '
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   126
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   127
    def getname(y, x):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   128
        """(int, int) -> str. like get(y, x) but concatenate left and right
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   129
        parts. if name is an 'o', try to replace it to the right"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   130
        result = ''
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   131
        for i in itertools.count(0):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   132
            ch = get(y, x - i)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   133
            if not _isname(ch):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   134
                break
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   135
            result = ch + result
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   136
        for i in itertools.count(1):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   137
            ch = get(y, x + i)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   138
            if not _isname(ch):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   139
                break
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   140
            result += ch
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   141
        if result == 'o':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   142
            # special handling, find the name to the right
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   143
            result = ''
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   144
            for i in itertools.count(2):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   145
                ch = get(y, x + i)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   146
                if ch == ' ' or ch in _pipechars:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   147
                    if result or x + i >= len(lines[y]):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   148
                        break
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   149
                else:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   150
                    result += ch
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   151
            return result or 'o'
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   152
        return result
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   153
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   154
    def parents(y, x):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   155
        """(int, int) -> [str]. follow the ASCII edges at given position,
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   156
        return a list of parents"""
32331
bd872f64a8ba cleanup: use set literals
Martin von Zweigbergk <martinvonz@google.com>
parents: 31676
diff changeset
   157
        visited = {(y, x)}
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   158
        visit = []
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   159
        result = []
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   160
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   161
        def follow(y, x, expected):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   162
            """conditionally append (y, x) to visit array, if it's a char
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   163
            in excepted. 'o' in expected means an '_isname' test.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   164
            if '-' (or '+') is not in excepted, and get(y, x) is '-' (or '+'),
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   165
            the next line (y + 1, x) will be checked instead."""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   166
            ch = get(y, x)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   167
            if any(ch == c and c not in expected for c in '-+'):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   168
                y += 1
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   169
                return follow(y + 1, x, expected)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   170
            if ch in expected or ('o' in expected and _isname(ch)):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   171
                visit.append((y, x))
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   172
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   173
        #  -o-  # starting point:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   174
        #  /|\ # follow '-' (horizontally), and '/|\' (to the bottom)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   175
        follow(y + 1, x, '|')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   176
        follow(y + 1, x - 1, '/')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   177
        follow(y + 1, x + 1, '\\')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   178
        follow(y, x - 1, '-')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   179
        follow(y, x + 1, '-')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   180
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   181
        while visit:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   182
            y, x = visit.pop()
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   183
            if (y, x) in visited:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   184
                continue
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   185
            visited.add((y, x))
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   186
            ch = get(y, x)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   187
            if _isname(ch):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   188
                result.append(getname(y, x))
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   189
                continue
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   190
            elif ch == '|':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   191
                follow(y + 1, x, '/|o')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   192
                follow(y + 1, x - 1, '/')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   193
                follow(y + 1, x + 1, '\\')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   194
            elif ch == '+':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   195
                follow(y, x - 1, '-')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   196
                follow(y, x + 1, '-')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   197
                follow(y + 1, x - 1, '/')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   198
                follow(y + 1, x + 1, '\\')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   199
                follow(y + 1, x, '|')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   200
            elif ch == '\\':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   201
                follow(y + 1, x + 1, '\\|o')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   202
            elif ch == '/':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   203
                follow(y + 1, x - 1, '/|o')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   204
            elif ch == '-':
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   205
                follow(y, x - 1, '-+o')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   206
                follow(y, x + 1, '-+o')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   207
        return result
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   208
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   209
    for y, line in enumerate(lines):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   210
        for x, ch in enumerate(line):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   211
            if ch == '#':  # comment
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   212
                break
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   213
            if _isname(ch):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   214
                edges[getname(y, x)] += parents(y, x)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   215
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   216
    return dict(edges)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   217
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   218
class simplefilectx(object):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   219
    def __init__(self, path, data):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   220
        self._data = data
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   221
        self._path = path
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   222
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   223
    def data(self):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   224
        return self._data
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   225
32345
911057981ba4 drawdag: provide filenode for its dummy filectx
Jun Wu <quark@fb.com>
parents: 32331
diff changeset
   226
    def filenode(self):
911057981ba4 drawdag: provide filenode for its dummy filectx
Jun Wu <quark@fb.com>
parents: 32331
diff changeset
   227
        return None
911057981ba4 drawdag: provide filenode for its dummy filectx
Jun Wu <quark@fb.com>
parents: 32331
diff changeset
   228
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   229
    def path(self):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   230
        return self._path
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   231
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   232
    def renamed(self):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   233
        return None
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   234
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   235
    def flags(self):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   236
        return ''
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   237
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   238
class simplecommitctx(context.committablectx):
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   239
    def __init__(self, repo, name, parentctxs, added):
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   240
        opts = {
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   241
            'changes': scmutil.status([], list(added), [], [], [], [], []),
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   242
            'date': '0 0',
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   243
            'extra': {'branch': 'default'},
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   244
        }
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   245
        super(simplecommitctx, self).__init__(self, name, **opts)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   246
        self._repo = repo
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   247
        self._added = added
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   248
        self._parents = parentctxs
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   249
        while len(self._parents) < 2:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   250
            self._parents.append(repo[node.nullid])
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   251
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   252
    def filectx(self, key):
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   253
        return simplefilectx(key, self._added[key])
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   254
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   255
    def commit(self):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   256
        return self._repo.commitctx(self)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   257
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   258
def _walkgraph(edges):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   259
    """yield node, parents in topologically order"""
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   260
    visible = set(edges.keys())
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   261
    remaining = {}  # {str: [str]}
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   262
    for k, vs in edges.iteritems():
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   263
        for v in vs:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   264
            if v not in remaining:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   265
                remaining[v] = []
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   266
        remaining[k] = vs[:]
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   267
    while remaining:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   268
        leafs = [k for k, v in remaining.items() if not v]
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   269
        if not leafs:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   270
            raise error.Abort(_('the graph has cycles'))
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   271
        for leaf in sorted(leafs):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   272
            if leaf in visible:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   273
                yield leaf, edges[leaf]
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   274
            del remaining[leaf]
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   275
            for k, v in remaining.iteritems():
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   276
                if leaf in v:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   277
                    v.remove(leaf)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   278
33809
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   279
def _getcomments(text):
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   280
    for line in text.splitlines():
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   281
        if ' # ' not in line:
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   282
            continue
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   283
        yield line.split(' # ', 1)[1].split(' # ')[0].strip()
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   284
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   285
@command('debugdrawdag', [])
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   286
def debugdrawdag(ui, repo, **opts):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   287
    """read an ASCII graph from stdin and create changesets
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   288
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   289
    The ASCII graph is like what :hg:`log -G` outputs, with each `o` replaced
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   290
    to the name of the node. The command will create dummy changesets and local
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   291
    tags with those names to make the dummy changesets easier to be referred
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   292
    to.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   293
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   294
    If the name of a node is a single character 'o', It will be replaced by the
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   295
    word to the right. This makes it easier to reuse
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   296
    :hg:`log -G -T '{desc}'` outputs.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   297
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   298
    For root (no parents) nodes, revset can be used to query existing repo.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   299
    Note that the revset cannot have confusing characters which can be seen as
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   300
    the part of the graph edges, like `|/+-\`.
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   301
    """
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   302
    text = ui.fin.read()
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   303
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   304
    # parse the graph and make sure len(parents) <= 2 for each node
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   305
    edges = _parseasciigraph(text)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   306
    for k, v in edges.iteritems():
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   307
        if len(v) > 2:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   308
            raise error.Abort(_('%s: too many parents: %s')
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   309
                              % (k, ' '.join(v)))
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   310
33809
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   311
    # parse comments to get extra file content instructions
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   312
    files = collections.defaultdict(dict) # {(name, path): content}
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   313
    comments = list(_getcomments(text))
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   314
    filere = re.compile(r'^(\w+)/([\w/]+)\s*=\s*(.*)$', re.M)
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   315
    for name, path, content in filere.findall('\n'.join(comments)):
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   316
        files[name][path] = content.replace(r'\n', '\n')
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   317
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   318
    committed = {None: node.nullid}  # {name: node}
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   319
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   320
    # for leaf nodes, try to find existing nodes in repo
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   321
    for name, parents in edges.iteritems():
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   322
        if len(parents) == 0:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   323
            try:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   324
                committed[name] = scmutil.revsingle(repo, name)
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   325
            except error.RepoLookupError:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   326
                pass
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   327
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   328
    # commit in topological order
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   329
    for name, parents in _walkgraph(edges):
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   330
        if name in committed:
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   331
            continue
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   332
        pctxs = [repo[committed[n]] for n in parents]
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   333
        pctxs.sort(key=lambda c: c.node())
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   334
        added = {}
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   335
        if len(parents) > 1:
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   336
            # If it's a merge, take the files and contents from the parents
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   337
            for f in pctxs[1].manifest():
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   338
                if f not in pctxs[0].manifest():
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   339
                    added[f] = pctxs[1][f].data()
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   340
        else:
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   341
            # If it's not a merge, add a single file
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   342
            added[name] = name
33809
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   343
        # add extra file contents in comments
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   344
        for path, content in files.get(name, {}).items():
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   345
            added[path] = content
33558
0103e7187237 drawdag: include files from both parents in merge commits
Martin von Zweigbergk <martinvonz@google.com>
parents: 33174
diff changeset
   346
        ctx = simplecommitctx(repo, name, pctxs, added)
30458
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   347
        n = ctx.commit()
a31634336471 drawdag: update test repos by drawing the changelog DAG in ASCII
Jun Wu <quark@fb.com>
parents:
diff changeset
   348
        committed[name] = n
31676
d761ef24d6e1 drawdag: use 'tagsmod.tag' instead of 'repo.tag'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30458
diff changeset
   349
        tagsmod.tag(repo, name, n, message=None, user=None, date=None,
d761ef24d6e1 drawdag: use 'tagsmod.tag' instead of 'repo.tag'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 30458
diff changeset
   350
                    local=True)
33159
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   351
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   352
    # handle special comments
33174
0830c841fc7f drawdag: inline transaction() function
Martin von Zweigbergk <martinvonz@google.com>
parents: 33159
diff changeset
   353
    with repo.wlock(), repo.lock(), repo.transaction('drawdag'):
33159
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   354
        getctx = lambda x: repo.unfiltered()[committed[x.strip()]]
33809
0531ffd59a98 drawdag: allow override file contents via comments
Jun Wu <quark@fb.com>
parents: 33558
diff changeset
   355
        for comment in comments:
33159
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   356
            rels = [] # obsolete relationships
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   357
            args = comment.split(':', 1)
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   358
            if len(args) <= 1:
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   359
                continue
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   360
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   361
            cmd = args[0].strip()
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   362
            arg = args[1].strip()
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   363
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   364
            if cmd in ('replace', 'rebase', 'amend'):
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   365
                nodes = [getctx(m) for m in arg.split('->')]
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   366
                for i in range(len(nodes) - 1):
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   367
                    rels.append((nodes[i], (nodes[i + 1],)))
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   368
            elif cmd in ('split',):
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   369
                pre, succs = arg.split('->')
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   370
                succs = succs.split(',')
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   371
                rels.append((getctx(pre), (getctx(s) for s in succs)))
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   372
            elif cmd in ('prune',):
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   373
                for n in arg.split(','):
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   374
                    rels.append((getctx(n), ()))
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   375
            if rels:
4d780d510b44 drawdag: support obsmarker creation in comments
Jun Wu <quark@fb.com>
parents: 32376
diff changeset
   376
                obsolete.createmarkers(repo, rels, date=(0, 0), operation=cmd)