/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

merge bzr.dev r4221

Show diffs side-by-side

added added

removed removed

Lines of Context:
279
279
        'diff_type': diff_type,
280
280
        # Add 'private' attributes for features that may be deprecated
281
281
        '_match_using_deltas': _match_using_deltas,
282
 
        '_allow_single_merge_revision': True,
283
282
    }
284
283
 
285
284
 
348
347
            rqst['delta_type'] = None
349
348
        if not getattr(lf, 'supports_diff', False):
350
349
            rqst['diff_type'] = None
351
 
        if not getattr(lf, 'supports_merge_revisions', False):
352
 
            rqst['_allow_single_merge_revision'] = getattr(lf,
353
 
                'supports_single_merge_revision', False)
354
350
 
355
351
        # Find and print the interesting revisions
356
352
        generator = self._generator_factory(self.branch, rqst)
357
353
        for lr in generator.iter_log_revisions():
358
354
            lf.log_revision(lr)
 
355
        lf.show_advice()
359
356
 
360
357
    def _generator_factory(self, branch, rqst):
361
358
        """Make the LogGenerator object to use.
453
450
                rqst.get('limit') or self.start_rev_id or self.end_rev_id)
454
451
        view_revisions = _calc_view_revisions(self.branch, self.start_rev_id,
455
452
            self.end_rev_id, rqst.get('direction'), generate_merge_revisions,
456
 
            rqst.get('_allow_single_merge_revision'),
457
453
            delayed_graph_generation=delayed_graph_generation)
458
454
 
459
455
        # Apply the other filters
468
464
        # filter_revisions_touching_file_id() requires them ...
469
465
        rqst = self.rqst
470
466
        view_revisions = _calc_view_revisions(self.branch, self.start_rev_id,
471
 
            self.end_rev_id, rqst.get('direction'), True,
472
 
            rqst.get('_allow_single_merge_revision'))
 
467
            self.end_rev_id, rqst.get('direction'), True)
473
468
        if not isinstance(view_revisions, list):
474
469
            view_revisions = list(view_revisions)
475
470
        view_revisions = _filter_revisions_touching_file_id(self.branch,
480
475
 
481
476
 
482
477
def _calc_view_revisions(branch, start_rev_id, end_rev_id, direction,
483
 
    generate_merge_revisions, allow_single_merge_revision,
484
 
    delayed_graph_generation=False):
 
478
    generate_merge_revisions, delayed_graph_generation=False):
485
479
    """Calculate the revisions to view.
486
480
 
487
481
    :return: An iterator of (revision_id, dotted_revno, merge_depth) tuples OR
495
489
    generate_single_revision = (end_rev_id and start_rev_id == end_rev_id and
496
490
        (not generate_merge_revisions or not _has_merges(branch, end_rev_id)))
497
491
    if generate_single_revision:
498
 
        return _generate_one_revision(branch, end_rev_id, br_rev_id, br_revno,
499
 
            allow_single_merge_revision)
 
492
        return _generate_one_revision(branch, end_rev_id, br_rev_id, br_revno)
500
493
 
501
494
    # If we only want to see linear revisions, we can iterate ...
502
495
    if not generate_merge_revisions:
507
500
            direction, delayed_graph_generation)
508
501
 
509
502
 
510
 
def _generate_one_revision(branch, rev_id, br_rev_id, br_revno,
511
 
    allow_single_merge_revision):
 
503
def _generate_one_revision(branch, rev_id, br_rev_id, br_revno):
512
504
    if rev_id == br_rev_id:
513
505
        # It's the tip
514
506
        return [(br_rev_id, br_revno, 0)]
515
507
    else:
516
508
        revno = branch.revision_id_to_dotted_revno(rev_id)
517
 
        if len(revno) > 1 and not allow_single_merge_revision:
518
 
            # It's a merge revision and the log formatter is
519
 
            # completely brain dead. This "feature" of allowing
520
 
            # log formatters incapable of displaying dotted revnos
521
 
            # ought to be deprecated IMNSHO. IGC 20091022
522
 
            raise errors.BzrCommandError('Selected log formatter only'
523
 
                ' supports mainline revisions.')
524
509
        revno_str = '.'.join(str(n) for n in revno)
525
510
        return [(rev_id, revno_str, 0)]
526
511
 
682
667
 
683
668
 
684
669
def calculate_view_revisions(branch, start_revision, end_revision, direction,
685
 
        specific_fileid, generate_merge_revisions, allow_single_merge_revision):
 
670
        specific_fileid, generate_merge_revisions):
686
671
    """Calculate the revisions to view.
687
672
 
688
673
    :return: An iterator of (revision_id, dotted_revno, merge_depth) tuples OR
694
679
    start_rev_id, end_rev_id = _get_revision_limits(branch, start_revision,
695
680
        end_revision)
696
681
    view_revisions = list(_calc_view_revisions(branch, start_rev_id, end_rev_id,
697
 
        direction, generate_merge_revisions or specific_fileid,
698
 
        allow_single_merge_revision))
 
682
        direction, generate_merge_revisions or specific_fileid))
699
683
    if specific_fileid:
700
684
        view_revisions = _filter_revisions_touching_file_id(branch,
701
685
            specific_fileid, view_revisions,
1283
1267
        one (2) should be used.
1284
1268
 
1285
1269
    - supports_merge_revisions must be True if this log formatter supports
1286
 
        merge revisions.  If not, and if supports_single_merge_revision is
1287
 
        also not True, then only mainline revisions will be passed to the
1288
 
        formatter.
 
1270
        merge revisions.  If not, then only mainline revisions will be passed
 
1271
        to the formatter.
1289
1272
 
1290
1273
    - preferred_levels is the number of levels this formatter defaults to.
1291
1274
        The default value is zero meaning display all levels.
1292
1275
        This value is only relevant if supports_merge_revisions is True.
1293
1276
 
1294
 
    - supports_single_merge_revision must be True if this log formatter
1295
 
        supports logging only a single merge revision.  This flag is
1296
 
        only relevant if supports_merge_revisions is not True.
1297
 
 
1298
1277
    - supports_tags must be True if this log formatter supports tags.
1299
1278
        Otherwise the tags attribute may not be populated.
1300
1279
 
1333
1312
            delta_format = 2 # long format
1334
1313
        self.delta_format = delta_format
1335
1314
        self.levels = levels
 
1315
        self._merge_count = 0
1336
1316
 
1337
1317
    def get_levels(self):
1338
1318
        """Get the number of levels to display or 0 for all."""
1339
1319
        if getattr(self, 'supports_merge_revisions', False):
1340
1320
            if self.levels is None or self.levels == -1:
1341
 
                return self.preferred_levels
1342
 
            else:
1343
 
                return self.levels
1344
 
        return 1
 
1321
                self.levels = self.preferred_levels
 
1322
        else:
 
1323
            self.levels = 1
 
1324
        return self.levels
1345
1325
 
1346
1326
    def log_revision(self, revision):
1347
1327
        """Log a revision.
1350
1330
        """
1351
1331
        raise NotImplementedError('not implemented in abstract base')
1352
1332
 
 
1333
    def show_advice(self):
 
1334
        """Output user advice, if any, when the log is completed."""
 
1335
        if self.levels == 1 and self._merge_count > 0:
 
1336
            advice_sep = self.get_advice_separator()
 
1337
            if advice_sep:
 
1338
                self.to_file.write(advice_sep)
 
1339
            self.to_file.write(
 
1340
                "Use --levels 0 (or -n0) to see merged revisions.\n")
 
1341
 
 
1342
    def get_advice_separator(self):
 
1343
        """Get the text separating the log from the closing advice."""
 
1344
        return ''
 
1345
 
1353
1346
    def short_committer(self, rev):
1354
1347
        name, address = config.parse_username(rev.committer)
1355
1348
        if name:
1362
1355
            return name
1363
1356
        return address
1364
1357
 
 
1358
    def merge_marker(self, revision):
 
1359
        """Get the merge marker to include in the output or '' if none."""
 
1360
        if len(revision.rev.parent_ids) > 1:
 
1361
            self._merge_count += 1
 
1362
            return ' [merge]'
 
1363
        else:
 
1364
            return ''
 
1365
 
1365
1366
    def show_properties(self, revision, indent):
1366
1367
        """Displays the custom properties returned by each registered handler.
1367
1368
 
1379
1380
class LongLogFormatter(LogFormatter):
1380
1381
 
1381
1382
    supports_merge_revisions = True
 
1383
    preferred_levels = 1
1382
1384
    supports_delta = True
1383
1385
    supports_tags = True
1384
1386
    supports_diff = True
1389
1391
        to_file = self.to_file
1390
1392
        to_file.write(indent + '-' * 60 + '\n')
1391
1393
        if revision.revno is not None:
1392
 
            to_file.write(indent + 'revno: %s\n' % (revision.revno,))
 
1394
            to_file.write(indent + 'revno: %s%s\n' % (revision.revno,
 
1395
                self.merge_marker(revision)))
1393
1396
        if revision.tags:
1394
1397
            to_file.write(indent + 'tags: %s\n' % (', '.join(revision.tags)))
1395
1398
        if self.show_ids:
1431
1434
            # revision information) so that the output can be fed to patch -p0
1432
1435
            self.show_diff(self.to_exact_file, revision.diff, indent)
1433
1436
 
 
1437
    def get_advice_separator(self):
 
1438
        """Get the text separating the log from the closing advice."""
 
1439
        return '-' * 60 + '\n'
 
1440
 
1434
1441
 
1435
1442
class ShortLogFormatter(LogFormatter):
1436
1443
 
1465
1472
        offset = ' ' * (revno_width + 1)
1466
1473
 
1467
1474
        to_file = self.to_file
1468
 
        is_merge = ''
1469
 
        if len(revision.rev.parent_ids) > 1:
1470
 
            is_merge = ' [merge]'
1471
1475
        tags = ''
1472
1476
        if revision.tags:
1473
1477
            tags = ' {%s}' % (', '.join(revision.tags))
1477
1481
                            revision.rev.timezone or 0,
1478
1482
                            self.show_timezone, date_fmt="%Y-%m-%d",
1479
1483
                            show_offset=False),
1480
 
                tags, is_merge))
 
1484
                tags, self.merge_marker(revision)))
1481
1485
        self.show_properties(revision.rev, indent+offset)
1482
1486
        if self.show_ids:
1483
1487
            to_file.write(indent + offset + 'revision-id:%s\n'