/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/log.py

  • Committer: Jelmer Vernooij
  • Date: 2010-03-21 21:39:33 UTC
  • mfrom: (5102 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5143.
  • Revision ID: jelmer@samba.org-20100321213933-fexeh9zcoz8oaju2
merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006, 2007, 2009 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
88
88
    re_compile_checked,
89
89
    terminal_width,
90
90
    )
 
91
from bzrlib.symbol_versioning import (
 
92
    deprecated_function,
 
93
    deprecated_in,
 
94
    )
91
95
 
92
96
 
93
97
def find_touching_revisions(branch, file_id):
105
109
    last_path = None
106
110
    revno = 1
107
111
    for revision_id in branch.revision_history():
108
 
        this_inv = branch.repository.get_revision_inventory(revision_id)
 
112
        this_inv = branch.repository.get_inventory(revision_id)
109
113
        if file_id in this_inv:
110
114
            this_ie = this_inv[file_id]
111
115
            this_path = this_inv.id2path(file_id)
304
308
 
305
309
 
306
310
class Logger(object):
307
 
    """An object the generates, formats and displays a log."""
 
311
    """An object that generates, formats and displays a log."""
308
312
 
309
313
    def __init__(self, branch, rqst):
310
314
        """Create a Logger.
530
534
 
531
535
 
532
536
def _generate_all_revisions(branch, start_rev_id, end_rev_id, direction,
533
 
    delayed_graph_generation):
 
537
                            delayed_graph_generation):
534
538
    # On large trees, generating the merge graph can take 30-60 seconds
535
539
    # so we delay doing it until a merge is detected, incrementally
536
540
    # returning initial (non-merge) revisions while we can.
 
541
 
 
542
    # The above is only true for old formats (<= 0.92), for newer formats, a
 
543
    # couple of seconds only should be needed to load the whole graph and the
 
544
    # other graph operations needed are even faster than that -- vila 100201
537
545
    initial_revisions = []
538
546
    if delayed_graph_generation:
539
547
        try:
540
 
            for rev_id, revno, depth in \
541
 
                _linear_view_revisions(branch, start_rev_id, end_rev_id):
 
548
            for rev_id, revno, depth in  _linear_view_revisions(
 
549
                branch, start_rev_id, end_rev_id):
542
550
                if _has_merges(branch, rev_id):
 
551
                    # The end_rev_id can be nested down somewhere. We need an
 
552
                    # explicit ancestry check. There is an ambiguity here as we
 
553
                    # may not raise _StartNotLinearAncestor for a revision that
 
554
                    # is an ancestor but not a *linear* one. But since we have
 
555
                    # loaded the graph to do the check (or calculate a dotted
 
556
                    # revno), we may as well accept to show the log...  We need
 
557
                    # the check only if start_rev_id is not None as all
 
558
                    # revisions have _mod_revision.NULL_REVISION as an ancestor
 
559
                    # -- vila 20100319
 
560
                    graph = branch.repository.get_graph()
 
561
                    if (start_rev_id is not None
 
562
                        and not graph.is_ancestor(start_rev_id, end_rev_id)):
 
563
                        raise _StartNotLinearAncestor()
 
564
                    # Since we collected the revisions so far, we need to
 
565
                    # adjust end_rev_id.
543
566
                    end_rev_id = rev_id
544
567
                    break
545
568
                else:
558
581
            raise errors.BzrCommandError('Start revision not found in'
559
582
                ' history of end revision.')
560
583
 
 
584
    # We exit the loop above because we encounter a revision with merges, from
 
585
    # this revision, we need to switch to _graph_view_revisions.
 
586
 
561
587
    # A log including nested merges is required. If the direction is reverse,
562
588
    # we rebase the initial merge depths so that the development line is
563
589
    # shown naturally, i.e. just like it is for linear logging. We can easily
565
591
    # indented at the end seems slightly nicer in that case.
566
592
    view_revisions = chain(iter(initial_revisions),
567
593
        _graph_view_revisions(branch, start_rev_id, end_rev_id,
568
 
        rebase_initial_depths=direction == 'reverse'))
 
594
                              rebase_initial_depths=(direction == 'reverse')))
569
595
    if direction == 'reverse':
570
596
        return view_revisions
571
597
    elif direction == 'forward':
597
623
        else:
598
624
            # not obvious
599
625
            return False
 
626
    # if either start or end is not specified then we use either the first or
 
627
    # the last revision and *they* are obvious ancestors.
600
628
    return True
601
629
 
602
630
 
635
663
 
636
664
 
637
665
def _graph_view_revisions(branch, start_rev_id, end_rev_id,
638
 
    rebase_initial_depths=True):
 
666
                          rebase_initial_depths=True):
639
667
    """Calculate revisions to view including merges, newest to oldest.
640
668
 
641
669
    :param branch: the branch
664
692
                depth_adjustment = merge_depth
665
693
            if depth_adjustment:
666
694
                if merge_depth < depth_adjustment:
 
695
                    # From now on we reduce the depth adjustement, this can be
 
696
                    # surprising for users. The alternative requires two passes
 
697
                    # which breaks the fast display of the first revision
 
698
                    # though.
667
699
                    depth_adjustment = merge_depth
668
700
                merge_depth -= depth_adjustment
669
701
            yield rev_id, '.'.join(map(str, revno)), merge_depth
670
702
 
671
703
 
 
704
@deprecated_function(deprecated_in((2, 2, 0)))
672
705
def calculate_view_revisions(branch, start_revision, end_revision, direction,
673
706
        specific_fileid, generate_merge_revisions):
674
707
    """Calculate the revisions to view.
676
709
    :return: An iterator of (revision_id, dotted_revno, merge_depth) tuples OR
677
710
             a list of the same tuples.
678
711
    """
679
 
    # This method is no longer called by the main code path.
680
 
    # It is retained for API compatibility and may be deprecated
681
 
    # soon. IGC 20090116
682
712
    start_rev_id, end_rev_id = _get_revision_limits(branch, start_revision,
683
713
        end_revision)
684
714
    view_revisions = list(_calc_view_revisions(branch, start_rev_id, end_rev_id,
1034
1064
    return mainline_revs, rev_nos, start_rev_id, end_rev_id
1035
1065
 
1036
1066
 
 
1067
@deprecated_function(deprecated_in((2, 2, 0)))
1037
1068
def _filter_revision_range(view_revisions, start_rev_id, end_rev_id):
1038
1069
    """Filter view_revisions based on revision ranges.
1039
1070
 
1048
1079
 
1049
1080
    :return: The filtered view_revisions.
1050
1081
    """
1051
 
    # This method is no longer called by the main code path.
1052
 
    # It may be removed soon. IGC 20090127
1053
1082
    if start_rev_id or end_rev_id:
1054
1083
        revision_ids = [r for r, n, d in view_revisions]
1055
1084
        if start_rev_id:
1161
1190
    return result
1162
1191
 
1163
1192
 
 
1193
@deprecated_function(deprecated_in((2, 2, 0)))
1164
1194
def get_view_revisions(mainline_revs, rev_nos, branch, direction,
1165
1195
                       include_merges=True):
1166
1196
    """Produce an iterator of revisions to show
1167
1197
    :return: an iterator of (revision_id, revno, merge_depth)
1168
1198
    (if there is no revno for a revision, None is supplied)
1169
1199
    """
1170
 
    # This method is no longer called by the main code path.
1171
 
    # It is retained for API compatibility and may be deprecated
1172
 
    # soon. IGC 20090127
1173
1200
    if not include_merges:
1174
1201
        revision_ids = mainline_revs[1:]
1175
1202
        if direction == 'reverse':
1293
1320
    preferred_levels = 0
1294
1321
 
1295
1322
    def __init__(self, to_file, show_ids=False, show_timezone='original',
1296
 
            delta_format=None, levels=None, show_advice=False,
1297
 
            to_exact_file=None):
 
1323
                 delta_format=None, levels=None, show_advice=False,
 
1324
                 to_exact_file=None):
1298
1325
        """Create a LogFormatter.
1299
1326
 
1300
1327
        :param to_file: the file to output to
1405
1432
        """
1406
1433
        # Revision comes directly from a foreign repository
1407
1434
        if isinstance(rev, foreign.ForeignRevision):
1408
 
            return rev.mapping.vcs.show_foreign_revid(rev.foreign_revid)
 
1435
            return self._format_properties(
 
1436
                rev.mapping.vcs.show_foreign_revid(rev.foreign_revid))
1409
1437
 
1410
1438
        # Imported foreign revision revision ids always contain :
1411
1439
        if not ":" in rev.revision_id:
1980
2008
 
1981
2009
properties_handler_registry = registry.Registry()
1982
2010
 
 
2011
# Use the properties handlers to print out bug information if available
 
2012
def _bugs_properties_handler(revision):
 
2013
    if revision.properties.has_key('bugs'):
 
2014
        bug_lines = revision.properties['bugs'].split('\n')
 
2015
        bug_rows = [line.split(' ', 1) for line in bug_lines]
 
2016
        fixed_bug_urls = [row[0] for row in bug_rows if
 
2017
                          len(row) > 1 and row[1] == 'fixed']
 
2018
 
 
2019
        if fixed_bug_urls:
 
2020
            return {'fixes bug(s)': ' '.join(fixed_bug_urls)}
 
2021
    return {}
 
2022
 
 
2023
properties_handler_registry.register('bugs_properties_handler',
 
2024
                                     _bugs_properties_handler)
 
2025
 
1983
2026
 
1984
2027
# adapters which revision ids to log are filtered. When log is called, the
1985
2028
# log_rev_iterator is adapted through each of these factory methods.