1
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Canonical Ltd
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
31
from bzrlib.lazy_import import lazy_import
32
lazy_import(globals(), """
33
31
from bzrlib import (
42
37
from bzrlib.config import extract_email_address
43
38
from bzrlib.repository import _strip_NULL_ghosts
44
39
from bzrlib.revision import CURRENT_REVISION, Revision
194
189
last_revision = current_rev.revision_id
195
190
# XXX: Partially Cloned from branch, uses the old_get_graph, eep.
196
# XXX: The main difficulty is that we need to inject a single new node
197
# (current_rev) into the graph before it gets numbered, etc.
198
# Once KnownGraph gets an 'add_node()' function, we can use
199
# VF.get_known_graph_ancestry().
200
191
graph = repository.get_graph()
201
192
revision_graph = dict(((key, value) for key, value in
202
193
graph.iter_ancestry(current_rev.parent_ids) if value is not None))
319
310
def _get_matching_blocks(old, new):
320
matcher = patiencediff.PatienceSequenceMatcher(None, old, new)
311
matcher = patiencediff.PatienceSequenceMatcher(None,
321
313
return matcher.get_matching_blocks()
324
_break_annotation_tie = None
326
def _old_break_annotation_tie(annotated_lines):
327
"""Chose an attribution between several possible ones.
329
:param annotated_lines: A list of tuples ((file_id, rev_id), line) where
330
the lines are identical but the revids different while no parent
331
relation exist between them
333
:return : The "winning" line. This must be one with a revid that
334
guarantees that further criss-cross merges will converge. Failing to
335
do so have performance implications.
337
# sort lexicographically so that we always get a stable result.
339
# TODO: while 'sort' is the easiest (and nearly the only possible solution)
340
# with the current implementation, chosing the oldest revision is known to
341
# provide better results (as in matching user expectations). The most
342
# common use case being manual cherry-pick from an already existing
344
return sorted(annotated_lines)[0]
347
316
def _find_matching_unannotated_lines(output_lines, plain_child_lines,
348
317
child_lines, start_child, end_child,
349
318
right_lines, start_right, end_right,
354
323
:param plain_child_lines: The unannotated new lines for the child text
355
324
:param child_lines: Lines for the child text which have been annotated
356
325
for the left parent
358
:param start_child: Position in plain_child_lines and child_lines to start
360
:param end_child: Last position in plain_child_lines and child_lines to
326
:param start_child: Position in plain_child_lines and child_lines to start the
328
:param end_child: Last position in plain_child_lines and child_lines to search
362
330
:param right_lines: The annotated lines for the whole text for the right
364
332
:param start_right: Position in right_lines to start the match
400
368
if len(heads) == 1:
401
369
output_append((iter(heads).next(), left[1]))
403
# Both claim different origins, get a stable result.
404
# If the result is not stable, there is a risk a
405
# performance degradation as criss-cross merges will
406
# flip-flop the attribution.
407
if _break_annotation_tie is None:
409
_old_break_annotation_tie([left, right]))
411
output_append(_break_annotation_tie([left, right]))
371
# Both claim different origins, sort lexicographically
372
# so that we always get a stable result.
373
output_append(sorted([left, right])[0])
412
374
last_child_idx = child_idx + match_len
438
400
matching_left_and_right = _get_matching_blocks(right_parent_lines,
440
402
for right_idx, left_idx, match_len in matching_left_and_right:
441
# annotated lines from last_left_idx to left_idx did not match the
442
# lines from last_right_idx to right_idx, the raw lines should be
443
# compared to determine what annotations need to be updated
403
# annotated lines from last_left_idx to left_idx did not match the lines from
405
# to right_idx, the raw lines should be compared to determine what annotations
444
407
if last_right_idx == right_idx or last_left_idx == left_idx:
445
408
# One of the sides is empty, so this is a pure insertion
446
409
lines_extend(annotated_lines[last_left_idx:left_idx])
458
421
# If left and right agree on a range, just push that into the output
459
422
lines_extend(annotated_lines[left_idx:left_idx + match_len])
464
from bzrlib._annotator_pyx import Annotator
465
except ImportError, e:
466
osutils.failed_to_load_extension(e)
467
from bzrlib._annotator_py import Annotator