/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: Andrew Bennetts
  • Date: 2008-04-02 00:14:00 UTC
  • mfrom: (3324 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3756.
  • Revision ID: andrew.bennetts@canonical.com-20080402001400-r1pqse38i03dl97w
Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
71
71
 
72
72
from bzrlib import (
73
73
    config,
74
 
    lazy_regex,
75
74
    registry,
76
 
    symbol_versioning,
77
75
    )
78
76
from bzrlib.osutils import (
79
77
    format_date,
80
78
    get_terminal_encoding,
81
79
    terminal_width,
82
80
    )
83
 
from bzrlib.symbol_versioning import (
84
 
    deprecated_method,
85
 
    zero_seventeen,
86
 
    )
 
81
from bzrlib.repository import _strip_NULL_ghosts
87
82
from bzrlib.trace import mutter
88
83
 
89
84
 
190
185
    finally:
191
186
        branch.unlock()
192
187
 
 
188
 
193
189
def _show_log(branch,
194
190
             lf,
195
191
             specific_fileid=None,
205
201
 
206
202
    if specific_fileid:
207
203
        mutter('get log for file_id %r', specific_fileid)
208
 
 
 
204
    generate_merge_revisions = getattr(lf, 'supports_merge_revisions', False)
 
205
    allow_single_merge_revision = getattr(lf,
 
206
        'supports_single_merge_revision', False)
 
207
    view_revisions = calculate_view_revisions(branch, start_revision,
 
208
                                              end_revision, direction,
 
209
                                              specific_fileid,
 
210
                                              generate_merge_revisions,
 
211
                                              allow_single_merge_revision)
209
212
    if search is not None:
210
213
        searchRE = re.compile(search, re.IGNORECASE)
211
214
    else:
212
215
        searchRE = None
213
216
 
 
217
    rev_tag_dict = {}
 
218
    generate_tags = getattr(lf, 'supports_tags', False)
 
219
    if generate_tags:
 
220
        if branch.supports_tags():
 
221
            rev_tag_dict = branch.tags.get_reverse_tag_dict()
 
222
 
 
223
    generate_delta = verbose and getattr(lf, 'supports_delta', False)
 
224
 
 
225
    # now we just print all the revisions
 
226
    log_count = 0
 
227
    for (rev_id, revno, merge_depth), rev, delta in _iter_revisions(
 
228
        branch.repository, view_revisions, generate_delta):
 
229
        if searchRE:
 
230
            if not searchRE.search(rev.message):
 
231
                continue
 
232
 
 
233
        lr = LogRevision(rev, revno, merge_depth, delta,
 
234
                         rev_tag_dict.get(rev_id))
 
235
        lf.log_revision(lr)
 
236
        if limit:
 
237
            log_count += 1
 
238
            if log_count >= limit:
 
239
                break
 
240
 
 
241
 
 
242
def calculate_view_revisions(branch, start_revision, end_revision, direction,
 
243
                             specific_fileid, generate_merge_revisions,
 
244
                             allow_single_merge_revision):
 
245
    if (not generate_merge_revisions and start_revision is end_revision is
 
246
        None and direction == 'reverse' and specific_fileid is None):
 
247
        return _linear_view_revisions(branch)
 
248
 
214
249
    mainline_revs, rev_nos, start_rev_id, end_rev_id = \
215
250
        _get_mainline_revs(branch, start_revision, end_revision)
216
251
    if not mainline_revs:
217
 
        return
 
252
        return []
218
253
 
219
254
    if direction == 'reverse':
220
255
        start_rev_id, end_rev_id = end_rev_id, start_rev_id
221
 
        
222
 
    legacy_lf = getattr(lf, 'log_revision', None) is None
223
 
    if legacy_lf:
224
 
        # pre-0.17 formatters use show for mainline revisions.
225
 
        # how should we show merged revisions ?
226
 
        #   pre-0.11 api: show_merge
227
 
        #   0.11-0.16 api: show_merge_revno
228
 
        show_merge_revno = getattr(lf, 'show_merge_revno', None)
229
 
        show_merge = getattr(lf, 'show_merge', None)
230
 
        if show_merge is None and show_merge_revno is None:
231
 
            # no merged-revno support
232
 
            generate_merge_revisions = False
233
 
        else:
234
 
            generate_merge_revisions = True
235
 
        # tell developers to update their code
236
 
        symbol_versioning.warn('LogFormatters should provide log_revision '
237
 
            'instead of show and show_merge_revno since bzr 0.17.',
238
 
            DeprecationWarning, stacklevel=3)
239
 
    else:
240
 
        generate_merge_revisions = getattr(lf, 'supports_merge_revisions', 
241
 
                                           False)
 
256
 
242
257
    generate_single_revision = False
243
258
    if ((not generate_merge_revisions)
244
259
        and ((start_rev_id and (start_rev_id not in rev_nos))
245
260
            or (end_rev_id and (end_rev_id not in rev_nos)))):
246
261
        generate_single_revision = ((start_rev_id == end_rev_id)
247
 
            and getattr(lf, 'supports_single_merge_revision', False))
 
262
            and allow_single_merge_revision)
248
263
        if not generate_single_revision:
249
264
            raise errors.BzrCommandError('Selected log formatter only supports '
250
265
                'mainline revisions.')
268
283
        min_depth = min([d for r,n,d in view_revisions])
269
284
        if min_depth != 0:
270
285
            view_revisions = [(r,n,d-min_depth) for r,n,d in view_revisions]
271
 
        
272
 
    rev_tag_dict = {}
273
 
    generate_tags = getattr(lf, 'supports_tags', False)
274
 
    if generate_tags:
275
 
        if branch.supports_tags():
276
 
            rev_tag_dict = branch.tags.get_reverse_tag_dict()
277
 
 
278
 
    generate_delta = verbose and getattr(lf, 'supports_delta', False)
279
 
 
280
 
    def iter_revisions():
 
286
    return view_revisions
 
287
 
 
288
 
 
289
def _linear_view_revisions(branch):
 
290
    start_revno, start_revision_id = branch.last_revision_info()
 
291
    repo = branch.repository
 
292
    revision_ids = repo.iter_reverse_revision_history(start_revision_id)
 
293
    for num, revision_id in enumerate(revision_ids):
 
294
        yield revision_id, str(start_revno - num), 0
 
295
 
 
296
 
 
297
def _iter_revisions(repository, view_revisions, generate_delta):
 
298
    num = 9
 
299
    view_revisions = iter(view_revisions)
 
300
    while True:
 
301
        cur_view_revisions = [d for x, d in zip(range(num), view_revisions)]
 
302
        if len(cur_view_revisions) == 0:
 
303
            break
 
304
        cur_deltas = {}
281
305
        # r = revision, n = revno, d = merge depth
282
 
        revision_ids = [r for r, n, d in view_revisions]
283
 
        num = 9
284
 
        repository = branch.repository
285
 
        while revision_ids:
286
 
            cur_deltas = {}
287
 
            revisions = repository.get_revisions(revision_ids[:num])
288
 
            if generate_delta:
289
 
                deltas = repository.get_deltas_for_revisions(revisions)
290
 
                cur_deltas = dict(izip((r.revision_id for r in revisions),
291
 
                                       deltas))
292
 
            for revision in revisions:
293
 
                yield revision, cur_deltas.get(revision.revision_id)
294
 
            revision_ids  = revision_ids[num:]
295
 
            num = min(int(num * 1.5), 200)
296
 
 
297
 
    # now we just print all the revisions
298
 
    log_count = 0
299
 
    for ((rev_id, revno, merge_depth), (rev, delta)) in \
300
 
         izip(view_revisions, iter_revisions()):
301
 
 
302
 
        if searchRE:
303
 
            if not searchRE.search(rev.message):
304
 
                continue
305
 
 
306
 
        if not legacy_lf:
307
 
            lr = LogRevision(rev, revno, merge_depth, delta,
308
 
                             rev_tag_dict.get(rev_id))
309
 
            lf.log_revision(lr)
310
 
        else:
311
 
            # support for legacy (pre-0.17) LogFormatters
312
 
            if merge_depth == 0:
313
 
                if generate_tags:
314
 
                    lf.show(revno, rev, delta, rev_tag_dict.get(rev_id))
315
 
                else:
316
 
                    lf.show(revno, rev, delta)
317
 
            else:
318
 
                if show_merge_revno is None:
319
 
                    lf.show_merge(rev, merge_depth)
320
 
                else:
321
 
                    if generate_tags:
322
 
                        lf.show_merge_revno(rev, merge_depth, revno,
323
 
                                            rev_tag_dict.get(rev_id))
324
 
                    else:
325
 
                        lf.show_merge_revno(rev, merge_depth, revno)
326
 
        if limit:
327
 
            log_count += 1
328
 
            if log_count >= limit:
329
 
                break
 
306
        revision_ids = [r for (r, n, d) in cur_view_revisions]
 
307
        revisions = repository.get_revisions(revision_ids)
 
308
        if generate_delta:
 
309
            deltas = repository.get_deltas_for_revisions(revisions)
 
310
            cur_deltas = dict(izip((r.revision_id for r in revisions),
 
311
                                   deltas))
 
312
        for view_data, revision in izip(cur_view_revisions, revisions):
 
313
            yield view_data, revision, cur_deltas.get(revision.revision_id)
 
314
        num = min(int(num * 1.5), 200)
330
315
 
331
316
 
332
317
def _get_mainline_revs(branch, start_revision, end_revision):
471
456
    weave_modifed_revisions = set(file_weave.versions())
472
457
    # build the ancestry of each revision in the graph
473
458
    # - only listing the ancestors that change the specific file.
474
 
    rev_graph = branch.repository.get_revision_graph(mainline_revisions[-1])
475
 
    sorted_rev_list = tsort.topo_sort(rev_graph)
 
459
    graph = branch.repository.get_graph()
 
460
    # This asks for all mainline revisions, which means we only have to spider
 
461
    # sideways, rather than depth history. That said, its still size-of-history
 
462
    # and should be addressed.
 
463
    parent_map = dict(((key, value) for key, value in
 
464
        graph.iter_ancestry(mainline_revisions) if value is not None))
 
465
    sorted_rev_list = tsort.topo_sort(parent_map.items())
476
466
    ancestry = {}
477
467
    for rev in sorted_rev_list:
478
 
        parents = rev_graph[rev]
 
468
        parents = parent_map[rev]
479
469
        if rev not in weave_modifed_revisions and len(parents) == 1:
480
470
            # We will not be adding anything new, so just use a reference to
481
471
            # the parent ancestry.
489
479
        ancestry[rev] = rev_ancestry
490
480
 
491
481
    def is_merging_rev(r):
492
 
        parents = rev_graph[r]
 
482
        parents = parent_map[r]
493
483
        if len(parents) > 1:
494
484
            leftparent = parents[0]
495
485
            for rightparent in parents[1:]:
517
507
        for revision_id in revision_ids:
518
508
            yield revision_id, str(rev_nos[revision_id]), 0
519
509
        return
 
510
    graph = branch.repository.get_graph()
 
511
    # This asks for all mainline revisions, which means we only have to spider
 
512
    # sideways, rather than depth history. That said, its still size-of-history
 
513
    # and should be addressed.
 
514
    parent_map = dict(((key, value) for key, value in
 
515
        graph.iter_ancestry(mainline_revs) if value is not None))
 
516
    # filter out ghosts; merge_sort errors on ghosts.
 
517
    rev_graph = _strip_NULL_ghosts(parent_map)
520
518
    merge_sorted_revisions = tsort.merge_sort(
521
 
        branch.repository.get_revision_graph(mainline_revs[-1]),
 
519
        rev_graph,
522
520
        mainline_revs[-1],
523
521
        mainline_revs,
524
522
        generate_revno=True)
613
611
#        """
614
612
#        raise NotImplementedError('not implemented in abstract base')
615
613
 
616
 
    @deprecated_method(zero_seventeen)
617
 
    def show(self, revno, rev, delta):
618
 
        raise NotImplementedError('not implemented in abstract base')
619
 
 
620
614
    def short_committer(self, rev):
621
615
        name, address = config.parse_username(rev.committer)
622
616
        if name:
636
630
    supports_delta = True
637
631
    supports_tags = True
638
632
 
639
 
    @deprecated_method(zero_seventeen)
640
 
    def show(self, revno, rev, delta, tags=None):
641
 
        lr = LogRevision(rev, revno, 0, delta, tags)
642
 
        return self.log_revision(lr)
643
 
 
644
 
    @deprecated_method(zero_seventeen)
645
 
    def show_merge_revno(self, rev, merge_depth, revno, tags=None):
646
 
        """Show a merged revision rev, with merge_depth and a revno."""
647
 
        lr = LogRevision(rev, revno, merge_depth, tags=tags)
648
 
        return self.log_revision(lr)
649
 
 
650
633
    def log_revision(self, revision):
651
634
        """Log a revision, either merged or not."""
652
635
        indent = '    ' * revision.merge_depth
692
675
    supports_delta = True
693
676
    supports_single_merge_revision = True
694
677
 
695
 
    @deprecated_method(zero_seventeen)
696
 
    def show(self, revno, rev, delta):
697
 
        lr = LogRevision(rev, revno, 0, delta)
698
 
        return self.log_revision(lr)
699
 
 
700
678
    def log_revision(self, revision):
701
679
        to_file = self.to_file
702
680
        date_str = format_date(revision.rev.timestamp,
752
730
        else:
753
731
            return rev.message
754
732
 
755
 
    @deprecated_method(zero_seventeen)
756
 
    def show(self, revno, rev, delta):
757
 
        self.to_file.write(self.log_string(revno, rev, terminal_width()-1))
758
 
        self.to_file.write('\n')
759
 
 
760
733
    def log_revision(self, revision):
761
734
        self.to_file.write(self.log_string(revision.revno, revision.rev,
762
735
                                              self._max_chars))