18
18
import bzrlib.errors
19
from bzrlib.graph import farthest_nodes, node_distances, all_descendants
19
from bzrlib.graph import node_distances, select_farthest, all_descendants
21
23
class RevisionReference(object):
230
233
while len(lines) > 0:
231
234
new_lines = set()
232
235
for line in lines:
234
rev = revision_source.get_revision(line)
235
parents = [p.revision_id for p in rev.parents]
236
if len(parents) == 0:
238
except bzrlib.errors.NoSuchRevision:
236
if line == NULL_REVISION:
241
rev = revision_source.get_revision(line)
242
parents = [p.revision_id for p in rev.parents]
243
if len(parents) == 0:
244
parents = [NULL_REVISION]
245
except bzrlib.errors.NoSuchRevision:
242
249
if parents is not None:
243
250
for parent in parents:
244
251
if parent not in ancestors:
253
260
assert root not in ancestors[root]
254
261
return root, ancestors, descendants
256
264
def combined_graph(revision_a, revision_b, revision_source):
257
265
"""Produce a combined ancestry graph.
258
266
Return graph root, ancestors map, descendants map, set of common nodes"""
259
267
root, ancestors, descendants = revision_graph(revision_a, revision_source)
260
268
root_b, ancestors_b, descendants_b = revision_graph(revision_b,
262
assert root == root_b
271
raise bzrlib.errors.NoCommonRoot(revision_a, revision_b)
264
273
for node, node_anc in ancestors_b.iteritems():
265
274
if node in ancestors:
269
278
ancestors[node].update(node_anc)
270
279
for node, node_dec in descendants_b.iteritems():
271
280
if node not in descendants:
272
descendants[node] = set()
281
descendants[node] = {}
273
282
descendants[node].update(node_dec)
274
283
return root, ancestors, descendants, common
276
286
def common_ancestor(revision_a, revision_b, revision_source):
277
root, ancestors, descendants, common = \
278
combined_graph(revision_a, revision_b, revision_source)
279
nodes = farthest_nodes(descendants, ancestors, root)
288
root, ancestors, descendants, common = \
289
combined_graph(revision_a, revision_b, revision_source)
290
except bzrlib.errors.NoCommonRoot:
291
raise bzrlib.errors.NoCommonAncestor(revision_a, revision_b)
293
distances = node_distances (descendants, ancestors, root)
294
farthest = select_farthest(distances, common)
295
if farthest is None or farthest == NULL_REVISION:
296
raise bzrlib.errors.NoCommonAncestor(revision_a, revision_b)
284
300
class MultipleRevisionSources(object):
285
301
"""Proxy that looks in multiple branches for revisions."""