18
18
# perhaps show them in log -v and allow them as options to the commit command.
25
from bzrlib.deprecated_graph import (
21
import bzrlib.errors as errors
22
from bzrlib.graph import node_distances, select_farthest, all_descendants, Graph
31
23
from bzrlib.osutils import contains_whitespace
32
24
from bzrlib.progress import DummyProgress
33
25
from bzrlib.symbol_versioning import (deprecated_function,
36
29
NULL_REVISION="null:"
37
CURRENT_REVISION="current:"
40
32
class Revision(object):
114
106
def get_summary(self):
115
107
"""Get the first line of the log message for this revision.
117
return self.message.lstrip().split('\n', 1)[0]
119
def get_apparent_author(self):
120
"""Return the apparent author of this revision.
122
If the revision properties contain the author name,
123
return it. Otherwise return the committer name.
125
return self.properties.get('author', self.committer)
109
return self.message.split('\n', 1)[0]
128
112
def is_ancestor(revision_id, candidate_id, branch):
269
250
pb.update('Picking ancestor', 1, 3)
270
251
graph = revision_source.get_revision_graph_with_ghosts(
271
252
[revision_a, revision_b])
272
# Shortcut the case where one of the tips is already included in
273
# the other graphs ancestry.
274
ancestry_a = graph.get_ancestry(revision_a, topo_sorted=False)
275
if revision_b in ancestry_a:
277
ancestry_b = graph.get_ancestry(revision_b, topo_sorted=False)
278
if revision_a in ancestry_b:
280
253
# convert to a NULL_REVISION based graph.
281
254
ancestors = graph.get_ancestors()
282
255
descendants = graph.get_descendants()
283
common = set(ancestry_a)
284
common.intersection_update(ancestry_b)
256
common = set(graph.get_ancestry(revision_a)).intersection(
257
set(graph.get_ancestry(revision_b)))
285
258
descendants[NULL_REVISION] = {}
286
259
ancestors[NULL_REVISION] = []
287
260
for root in graph.roots:
440
def is_reserved_id(revision_id):
441
"""Determine whether a revision id is reserved
413
@deprecated_function(zero_eight)
414
def get_intervening_revisions(ancestor_id, rev_id, rev_source,
415
revision_history=None):
416
"""Find the longest line of descent from maybe_ancestor to revision.
417
Revision history is followed where possible.
443
:return: True if the revision is is reserved, False otherwise
419
If ancestor_id == rev_id, list will be empty.
420
Otherwise, rev_id will be the last entry. ancestor_id will never appear.
421
If ancestor_id is not an ancestor, NotAncestor will be thrown
445
return isinstance(revision_id, basestring) and revision_id.endswith(':')
448
def check_not_reserved_id(revision_id):
449
"""Raise ReservedId if the supplied revision_id is reserved"""
450
if is_reserved_id(revision_id):
451
raise errors.ReservedId(revision_id)
454
def ensure_null(revision_id):
455
"""Ensure only NULL_REVISION is used to represent the null revisionn"""
456
if revision_id is None:
457
symbol_versioning.warn('NULL_REVISION should be used for the null'
458
' revision instead of None, as of bzr 0.91.',
459
DeprecationWarning, stacklevel=2)
465
def is_null(revision_id):
466
if revision_id is None:
467
symbol_versioning.warn('NULL_REVISION should be used for the null'
468
' revision instead of None, as of bzr 0.90.',
469
DeprecationWarning, stacklevel=2)
470
return revision_id in (None, NULL_REVISION)
423
root, ancestors, descendants = revision_graph(rev_id, rev_source)
424
if len(descendants) == 0:
425
raise errors.NoSuchRevision(rev_source, rev_id)
426
if ancestor_id not in descendants:
427
rev_source.get_revision(ancestor_id)
428
raise errors.NotAncestor(rev_id, ancestor_id)
429
root_descendants = all_descendants(descendants, ancestor_id)
430
root_descendants.add(ancestor_id)
431
if rev_id not in root_descendants:
432
raise errors.NotAncestor(rev_id, ancestor_id)
433
distances = node_distances(descendants, ancestors, ancestor_id,
434
root_descendants=root_descendants)
436
def best_ancestor(rev_id):
438
for anc_id in ancestors[rev_id]:
440
distance = distances[anc_id]
443
if revision_history is not None and anc_id in revision_history:
445
elif best is None or distance > best[1]:
446
best = (anc_id, distance)
451
while next != ancestor_id:
453
next = best_ancestor(next)