/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: Ian Clatworthy
  • Date: 2009-01-29 06:31:22 UTC
  • mfrom: (3947.1.10 bzr.log-merge-revisions)
  • mto: This revision was merged to the branch mainline in revision 3972.
  • Revision ID: ian.clatworthy@canonical.com-20090129063122-6yyql6ej6zwwfqzn
log -n/--levels (Ian Clatworthy)

Show diffs side-by-side

added added

removed removed

Lines of Context:
202
202
 
203
203
    if specific_fileid:
204
204
        trace.mutter('get log for file_id %r', specific_fileid)
205
 
    generate_merge_revisions = getattr(lf, 'supports_merge_revisions', False)
206
 
    allow_single_merge_revision = getattr(lf,
207
 
        'supports_single_merge_revision', False)
 
205
    levels_to_display = lf.get_levels()
 
206
    generate_merge_revisions = levels_to_display != 1
 
207
    allow_single_merge_revision = True
 
208
    if not getattr(lf, 'supports_merge_revisions', False):
 
209
        allow_single_merge_revision = getattr(lf,
 
210
            'supports_single_merge_revision', False)
208
211
    view_revisions = calculate_view_revisions(branch, start_revision,
209
212
                                              end_revision, direction,
210
213
                                              specific_fileid,
226
229
        generate_delta, search)
227
230
    for revs in revision_iterator:
228
231
        for (rev_id, revno, merge_depth), rev, delta in revs:
 
232
            # Note: 0 levels means show everything; merge_depth counts from 0
 
233
            if levels_to_display != 0 and merge_depth >= levels_to_display:
 
234
                continue
229
235
            if generate_diff:
230
236
                diff = _format_diff(repo, rev, rev_id, specific_fileid)
231
237
            else:
753
759
        also not True, then only mainline revisions will be passed to the 
754
760
        formatter.
755
761
 
 
762
    - preferred_levels is the number of levels this formatter defaults to.
 
763
        The default value is zero meaning display all levels.
 
764
        This value is only relevant if supports_merge_revisions is True.
 
765
 
756
766
    - supports_single_merge_revision must be True if this log formatter
757
767
        supports logging only a single merge revision.  This flag is
758
768
        only relevant if supports_merge_revisions is not True.
770
780
            # code that returns a dict {'name':'value'} of the properties 
771
781
            # to be shown
772
782
    """
 
783
    preferred_levels = 0
773
784
 
774
785
    def __init__(self, to_file, show_ids=False, show_timezone='original',
775
 
                 delta_format=None):
 
786
                 delta_format=None, levels=None):
 
787
        """Create a LogFormatter.
 
788
 
 
789
        :param to_file: the file to output to
 
790
        :param show_ids: if True, revision-ids are to be displayed
 
791
        :param show_timezone: the timezone to use
 
792
        :param delta_format: the level of delta information to display
 
793
          or None to leave it u to the formatter to decide
 
794
        :param levels: the number of levels to display; None or -1 to
 
795
          let the log formatter decide.
 
796
        """
776
797
        self.to_file = to_file
777
798
        self.show_ids = show_ids
778
799
        self.show_timezone = show_timezone
780
801
            # Ensures backward compatibility
781
802
            delta_format = 2 # long format
782
803
        self.delta_format = delta_format
783
 
 
784
 
# TODO: uncomment this block after show() has been removed.
785
 
# Until then defining log_revision would prevent _show_log calling show() 
786
 
# in legacy formatters.
787
 
#    def log_revision(self, revision):
788
 
#        """Log a revision.
789
 
#
790
 
#        :param  revision:   The LogRevision to be logged.
791
 
#        """
792
 
#        raise NotImplementedError('not implemented in abstract base')
 
804
        self.levels = levels
 
805
 
 
806
    def get_levels(self):
 
807
        """Get the number of levels to display or 0 for all."""
 
808
        if getattr(self, 'supports_merge_revisions', False):
 
809
            if self.levels is None or self.levels == -1:
 
810
                return self.preferred_levels
 
811
            else:
 
812
                return self.levels
 
813
        return 1
 
814
 
 
815
    def log_revision(self, revision):
 
816
        """Log a revision.
 
817
 
 
818
        :param  revision:   The LogRevision to be logged.
 
819
        """
 
820
        raise NotImplementedError('not implemented in abstract base')
793
821
 
794
822
    def short_committer(self, rev):
795
823
        name, address = config.parse_username(rev.committer)
874
902
 
875
903
class ShortLogFormatter(LogFormatter):
876
904
 
 
905
    supports_merge_revisions = True
 
906
    preferred_levels = 1
877
907
    supports_delta = True
878
908
    supports_tags = True
879
 
    supports_single_merge_revision = True
880
909
    supports_diff = True
881
910
 
 
911
    def __init__(self, *args, **kwargs):
 
912
        super(ShortLogFormatter, self).__init__(*args, **kwargs)
 
913
        self.revno_width_by_depth = {}
 
914
 
882
915
    def log_revision(self, revision):
 
916
        # We need two indents: one per depth and one for the information
 
917
        # relative to that indent. Most mainline revnos are 5 chars or
 
918
        # less while dotted revnos are typically 11 chars or less. Once
 
919
        # calculated, we need to remember the offset for a given depth
 
920
        # as we might be starting from a dotted revno in the first column
 
921
        # and we want subsequent mainline revisions to line up.
 
922
        depth = revision.merge_depth
 
923
        indent = '    ' * depth
 
924
        revno_width = self.revno_width_by_depth.get(depth)
 
925
        if revno_width is None:
 
926
            if revision.revno.find('.') == -1:
 
927
                # mainline revno, e.g. 12345
 
928
                revno_width = 5
 
929
            else:
 
930
                # dotted revno, e.g. 12345.10.55
 
931
                revno_width = 11
 
932
            self.revno_width_by_depth[depth] = revno_width
 
933
        offset = ' ' * (revno_width + 1)
 
934
 
883
935
        to_file = self.to_file
884
936
        is_merge = ''
885
937
        if len(revision.rev.parent_ids) > 1:
887
939
        tags = ''
888
940
        if revision.tags:
889
941
            tags = ' {%s}' % (', '.join(revision.tags))
890
 
 
891
 
        to_file.write("%5s %s\t%s%s%s\n" % (revision.revno,
892
 
                self.short_author(revision.rev),
 
942
        to_file.write(indent + "%*s %s\t%s%s%s\n" % (revno_width,
 
943
                revision.revno, self.short_author(revision.rev),
893
944
                format_date(revision.rev.timestamp,
894
945
                            revision.rev.timezone or 0,
895
946
                            self.show_timezone, date_fmt="%Y-%m-%d",
896
947
                            show_offset=False),
897
948
                tags, is_merge))
898
949
        if self.show_ids:
899
 
            to_file.write('      revision-id:%s\n'
 
950
            to_file.write(indent + offset + 'revision-id:%s\n'
900
951
                          % (revision.rev.revision_id,))
901
952
        if not revision.rev.message:
902
 
            to_file.write('      (no message)\n')
 
953
            to_file.write(indent + offset + '(no message)\n')
903
954
        else:
904
955
            message = revision.rev.message.rstrip('\r\n')
905
956
            for l in message.split('\n'):
906
 
                to_file.write('      %s\n' % (l,))
 
957
                to_file.write(indent + offset + '%s\n' % (l,))
907
958
 
908
959
        if revision.delta is not None:
909
 
            revision.delta.show(to_file, self.show_ids,
 
960
            revision.delta.show(to_file, self.show_ids, indent=indent + offset,
910
961
                                short_status=self.delta_format==1)
911
962
        if revision.diff is not None:
912
963
            self.show_diff(to_file, revision.diff, '      ')
915
966
 
916
967
class LineLogFormatter(LogFormatter):
917
968
 
 
969
    supports_merge_revisions = True
 
970
    preferred_levels = 1
918
971
    supports_tags = True
919
 
    supports_single_merge_revision = True
920
972
 
921
973
    def __init__(self, *args, **kwargs):
922
974
        super(LineLogFormatter, self).__init__(*args, **kwargs)
939
991
            return rev.message
940
992
 
941
993
    def log_revision(self, revision):
 
994
        indent = '  ' * revision.merge_depth
942
995
        self.to_file.write(self.log_string(revision.revno, revision.rev,
943
 
            self._max_chars, revision.tags))
 
996
            self._max_chars, revision.tags, indent))
944
997
        self.to_file.write('\n')
945
998
 
946
 
    def log_string(self, revno, rev, max_chars, tags=None):
 
999
    def log_string(self, revno, rev, max_chars, tags=None, prefix=''):
947
1000
        """Format log info into one string. Truncate tail of string
948
1001
        :param  revno:      revision number or None.
949
1002
                            Revision numbers counts from 1.
950
1003
        :param  rev:        revision object
951
1004
        :param  max_chars:  maximum length of resulting string
952
1005
        :param  tags:       list of tags or None
 
1006
        :param  prefix:     string to prefix each line
953
1007
        :return:            formatted truncated string
954
1008
        """
955
1009
        out = []
962
1016
            tag_str = '{%s}' % (', '.join(tags))
963
1017
            out.append(tag_str)
964
1018
        out.append(rev.get_summary())
965
 
        return self.truncate(" ".join(out).rstrip('\n'), max_chars)
 
1019
        return self.truncate(prefix + " ".join(out).rstrip('\n'), max_chars)
966
1020
 
967
1021
 
968
1022
def line_log(rev, max_chars):