106
106
return committer, message, nick, date
108
108
class Grapher(object):
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()
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)
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)
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,
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,
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:
139
self.new_base = new_graph.find_unique_lca(revision_a,
141
self.lcas = new_graph.find_lca(revision_a, revision_b)
136
144
self.new_base = None
137
145
self.lcas = set()
138
146
self.m_history = []
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)
153
self.descendants = {}
155
for revision, parents in self.ancestors.iteritems():
156
self.descendants.setdefault(revision, [])
159
parents = [NULL_REVISION]
160
for parent in parents:
161
self.descendants.setdefault(parent, []).append(revision)
163
self.ancestors[ghost] = [NULL_REVISION]
166
def _get_revno_str(prefix, revno_map, revision_id):
168
revno = revno_map[revision_id]
171
return '%s%s' % (prefix, '.'.join(str(n) for n in revno))
173
148
def dot_node(self, node, num):