~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to graph.py

  • Committer: Aaron Bentley
  • Date: 2007-06-18 23:52:33 UTC
  • Revision ID: abentley@panoramicfeedback.com-20070618235233-7ick9errjikvy4di
Fix no-collapse behavior

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005 Aaron Bentley
2
 
# <aaron@aaronbentley.com>
 
2
# <aaron.bentley@utoronto.ca>
3
3
#
4
4
#    This program is free software; you can redistribute it and/or modify
5
5
#    it under the terms of the GNU General Public License as published by
20
20
from bzrlib.branch import Branch
21
21
from bzrlib.errors import BzrCommandError, NoCommonRoot, NoSuchRevision
22
22
from bzrlib.graph import node_distances, select_farthest
23
 
from bzrlib.revision import combined_graph, revision_graph, NULL_REVISION
 
23
from bzrlib.revision import combined_graph, revision_graph
24
24
from bzrlib.revision import MultipleRevisionSources
25
25
import bzrlib.errors
26
26
import re
106
106
    return committer, message, nick, date
107
107
 
108
108
class Grapher(object):
109
 
 
110
109
    def __init__(self, branch, other_branch=None):
111
110
        object.__init__(self)
112
111
        self.branch = branch
113
112
        self.other_branch = other_branch
 
113
        revision_a = self.branch.last_revision()
114
114
        if other_branch is not None:
115
 
            other_repo = other_branch.repository
 
115
            branch.fetch(other_branch)
116
116
            revision_b = self.other_branch.last_revision()
 
117
            try:
 
118
                self.root, self.ancestors, self.descendants, self.common = \
 
119
                    combined_graph(revision_a, revision_b,
 
120
                                   self.branch.repository)
 
121
            except bzrlib.errors.NoCommonRoot:
 
122
                raise bzrlib.errors.NoCommonAncestor(revision_a, revision_b)
117
123
        else:
118
 
            other_repo = None
119
 
            revision_b = None
120
 
        self.graph = self.branch.repository.get_graph(other_repo)
121
 
        revision_a = self.branch.last_revision()
122
 
        self.scan_graph(revision_a, revision_b)
 
124
            self.root, self.ancestors, self.descendants = \
 
125
                revision_graph(revision_a, branch.repository)
 
126
            self.common = []
 
127
 
123
128
        self.n_history = branch.revision_history()
124
 
        self.n_revnos = branch.get_revision_id_to_revno_map()
125
129
        self.distances = node_distances(self.descendants, self.ancestors,
126
130
                                        self.root)
127
131
        if other_branch is not None:
128
132
            self.base = select_farthest(self.distances, self.common)
129
133
            self.m_history = other_branch.revision_history()
130
 
            self.m_revnos = other_branch.get_revision_id_to_revno_map()
131
 
            self.new_base = self.graph.find_unique_lca(revision_a,
132
 
                                                       revision_b)
133
 
            self.lcas = self.graph.find_lca(revision_a, revision_b)
 
134
            new_graph = getattr(branch.repository, 'get_graph', lambda: None)()
 
135
            if new_graph is None:
 
136
                self.new_base = None
 
137
                self.lcas = set()
 
138
            else:
 
139
                self.new_base = new_graph.find_unique_lca(revision_a,
 
140
                                                          revision_b)
 
141
                self.lcas = new_graph.find_lca(revision_a, revision_b)
134
142
        else:
135
143
            self.base = None
136
144
            self.new_base = None
137
145
            self.lcas = set()
138
146
            self.m_history = []
139
 
            self.m_revnos = {}
140
 
 
141
 
    def scan_graph(self, revision_a, revision_b):
142
 
        a_ancestors = dict(self.graph.iter_ancestry([revision_a]))
143
 
        self.ancestors = a_ancestors
144
 
        self.root = NULL_REVISION
145
 
        if revision_b is not None:
146
 
            b_ancestors = dict(self.graph.iter_ancestry([revision_b]))
147
 
            self.common = set(a_ancestors.keys())
148
 
            self.common.intersection_update(b_ancestors)
149
 
            self.ancestors.update(b_ancestors)
150
 
        else:
151
 
            self.common = []
152
 
            revision_b = None
153
 
        self.descendants = {}
154
 
        ghosts = set()
155
 
        for revision, parents in self.ancestors.iteritems():
156
 
            self.descendants.setdefault(revision, [])
157
 
            if parents is None:
158
 
                ghosts.add(revision)
159
 
                parents = [NULL_REVISION]
160
 
            for parent in parents:
161
 
                self.descendants.setdefault(parent, []).append(revision)
162
 
        for ghost in ghosts:
163
 
            self.ancestors[ghost] = [NULL_REVISION]
164
 
 
165
 
    @staticmethod
166
 
    def _get_revno_str(prefix, revno_map, revision_id):
167
 
        try:
168
 
            revno = revno_map[revision_id]
169
 
        except KeyError:
170
 
            return None
171
 
        return '%s%s' % (prefix, '.'.join(str(n) for n in revno))
172
147
 
173
148
    def dot_node(self, node, num):
174
149
        try:
180
155
        except ValueError:
181
156
            m_rev = None
182
157
        if (n_rev, m_rev) == (None, None):
183
 
            name = self._get_revno_str('r', self.n_revnos, node)
184
 
            if name is None:
185
 
                name = self._get_revno_str('R', self.m_revnos, node)
186
 
            if name is None:
187
 
                name = node[-5:]
 
158
            name = node[-5:]
188
159
            cluster = None
189
160
        elif n_rev == m_rev:
190
161
            name = "rR%d" % n_rev
323
294
            done = True
324
295
        except NoDot, e:
325
296
            raise BzrCommandError("Can't find 'dot'.  Please ensure Graphviz"\
326
 
                " is installed correctly.")
 
297
                " is installed correctly, or use --noantialias")
327
298
    elif ext == 'dot' and not done:
328
299
        my_file = file(filename, 'wb')
329
300
        for fragment in output:
333
304
            invoke_dot_html(output, filename)
334
305
        except NoDot, e:
335
306
            raise BzrCommandError("Can't find 'dot'.  Please ensure Graphviz"\
336
 
                " is installed correctly.")
 
307
                " is installed correctly, or use --noantialias")
337
308
    elif not done:
338
309
        print "Unknown file extension: %s" % ext
 
310