/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/annotate.py

  • Committer: John Arbash Meinel
  • Date: 2009-04-08 16:33:19 UTC
  • mfrom: (3735.2.187 brisbane-core)
  • mto: This revision was merged to the branch mainline in revision 4280.
  • Revision ID: john@arbash-meinel.com-20090408163319-jzin98xnzklj8vun
Merge the a couple rev older brisbane-core into bzr.dev, most things are resolve in favor of bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Canonical Ltd
 
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
2
2
#
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
28
28
import sys
29
29
import time
30
30
 
31
 
from bzrlib.lazy_import import lazy_import
32
 
lazy_import(globals(), """
33
31
from bzrlib import (
 
32
    errors,
 
33
    osutils,
34
34
    patiencediff,
35
35
    tsort,
36
36
    )
37
 
""")
38
 
from bzrlib import (
39
 
    errors,
40
 
    osutils,
41
 
    )
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
193
188
        # or something.
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))
317
308
 
318
309
 
319
310
def _get_matching_blocks(old, new):
320
 
    matcher = patiencediff.PatienceSequenceMatcher(None, old, new)
 
311
    matcher = patiencediff.PatienceSequenceMatcher(None,
 
312
        old, new)
321
313
    return matcher.get_matching_blocks()
322
314
 
323
315
 
324
 
_break_annotation_tie = None
325
 
 
326
 
def _old_break_annotation_tie(annotated_lines):
327
 
    """Chose an attribution between several possible ones.
328
 
 
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
332
 
 
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.
336
 
    """
337
 
    # sort lexicographically so that we always get a stable result.
338
 
 
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
343
 
    # revision.
344
 
    return sorted(annotated_lines)[0]
345
 
 
346
 
 
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
357
 
 
358
 
    :param start_child: Position in plain_child_lines and child_lines to start
359
 
        the match searching
360
 
    :param end_child: Last position in plain_child_lines and child_lines to
361
 
        search for a match
 
326
    :param start_child: Position in plain_child_lines and child_lines to start the
 
327
        match searching
 
328
    :param end_child: Last position in plain_child_lines and child_lines to search
 
329
        for a match
362
330
    :param right_lines: The annotated lines for the whole text for the right
363
331
        parent
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]))
402
370
                    else:
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:
408
 
                            output_append(
409
 
                                _old_break_annotation_tie([left, right]))
410
 
                        else:
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
413
375
 
414
376
 
438
400
    matching_left_and_right = _get_matching_blocks(right_parent_lines,
439
401
                                                   annotated_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
 
404
        # last_right_idx
 
405
        # to right_idx, the raw lines should be compared to determine what annotations
 
406
        # need to be updated
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])
460
423
    return lines
461
 
 
462
 
 
463
 
try:
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