1
1
# Copyright (C) 2005 Aaron Bentley
2
# <aaron@aaronbentley.com>
2
# <aaron.bentley@utoronto.ca>
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
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
129
self.n_revnos = branch.get_revision_id_to_revno_map()
125
130
self.distances = node_distances(self.descendants, self.ancestors,
128
133
self.base = select_farthest(self.distances, self.common)
129
134
self.m_history = other_branch.revision_history()
130
135
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)
136
new_graph = getattr(branch.repository, 'get_graph', lambda: None)()
137
if new_graph is None:
141
self.new_base = new_graph.find_unique_lca(revision_a,
143
self.lcas = new_graph.find_lca(revision_a, revision_b)
136
146
self.new_base = None
138
148
self.m_history = []
139
149
self.m_revnos = {}
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
152
def _get_revno_str(prefix, revno_map, revision_id):