~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/log.py

  • Committer: Vincent Ladeuil
  • Date: 2009-04-27 16:10:10 UTC
  • mto: (4310.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 4311.
  • Revision ID: v.ladeuil+lp@free.fr-20090427161010-7swfzeagf63cpixd
Fix bug #367726 by reverting some default user handling introduced
while fixing bug #256612.

* bzrlib/transport/ssh.py:
(_paramiko_auth): Explicitly use getpass.getuser() as default
user.

* bzrlib/transport/ftp/_gssapi.py:
(GSSAPIFtpTransport._create_connection): Explicitly use
getpass.getuser() as default user.

* bzrlib/transport/ftp/__init__.py:
(FtpTransport._create_connection): Explicitly use
getpass.getuser() as default user.

* bzrlib/tests/test_sftp_transport.py:
(TestUsesAuthConfig.test_sftp_is_none_if_no_config)
(TestUsesAuthConfig.test_sftp_doesnt_prompt_username): Revert to
None as the default user.

* bzrlib/tests/test_remote.py:
(TestRemoteSSHTransportAuthentication): The really offending one:
revert to None as the default user.

* bzrlib/tests/test_config.py:
(TestAuthenticationConfig.test_username_default_no_prompt): Update
test (and some PEP8).

* bzrlib/smtp_connection.py:
(SMTPConnection._authenticate): Revert to None as the default
user.

* bzrlib/plugins/launchpad/account.py:
(_get_auth_user): Revert default value handling.

* bzrlib/config.py:
(AuthenticationConfig.get_user): Fix doc-string. Leave default
value handling to callers.

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
 
1311
1290
    preferred_levels = 0
1312
1291
 
1313
1292
    def __init__(self, to_file, show_ids=False, show_timezone='original',
1314
 
                 delta_format=None, levels=None):
 
1293
                 delta_format=None, levels=None, show_advice=False):
1315
1294
        """Create a LogFormatter.
1316
1295
 
1317
1296
        :param to_file: the file to output to
1318
1297
        :param show_ids: if True, revision-ids are to be displayed
1319
1298
        :param show_timezone: the timezone to use
1320
1299
        :param delta_format: the level of delta information to display
1321
 
          or None to leave it u to the formatter to decide
 
1300
          or None to leave it to the formatter to decide
1322
1301
        :param levels: the number of levels to display; None or -1 to
1323
1302
          let the log formatter decide.
 
1303
        :param show_advice: whether to show advice at the end of the
 
1304
          log or not
1324
1305
        """
1325
1306
        self.to_file = to_file
1326
1307
        # 'exact' stream used to show diff, it should print content 'as is'
1333
1314
            delta_format = 2 # long format
1334
1315
        self.delta_format = delta_format
1335
1316
        self.levels = levels
 
1317
        self._show_advice = show_advice
 
1318
        self._merge_count = 0
1336
1319
 
1337
1320
    def get_levels(self):
1338
1321
        """Get the number of levels to display or 0 for all."""
1339
1322
        if getattr(self, 'supports_merge_revisions', False):
1340
1323
            if self.levels is None or self.levels == -1:
1341
 
                return self.preferred_levels
1342
 
            else:
1343
 
                return self.levels
1344
 
        return 1
 
1324
                self.levels = self.preferred_levels
 
1325
        else:
 
1326
            self.levels = 1
 
1327
        return self.levels
1345
1328
 
1346
1329
    def log_revision(self, revision):
1347
1330
        """Log a revision.
1350
1333
        """
1351
1334
        raise NotImplementedError('not implemented in abstract base')
1352
1335
 
 
1336
    def show_advice(self):
 
1337
        """Output user advice, if any, when the log is completed."""
 
1338
        if self._show_advice and self.levels == 1 and self._merge_count > 0:
 
1339
            advice_sep = self.get_advice_separator()
 
1340
            if advice_sep:
 
1341
                self.to_file.write(advice_sep)
 
1342
            self.to_file.write(
 
1343
                "Use --include-merges or -n0 to see merged revisions.\n")
 
1344
 
 
1345
    def get_advice_separator(self):
 
1346
        """Get the text separating the log from the closing advice."""
 
1347
        return ''
 
1348
 
1353
1349
    def short_committer(self, rev):
1354
1350
        name, address = config.parse_username(rev.committer)
1355
1351
        if name:
1362
1358
            return name
1363
1359
        return address
1364
1360
 
 
1361
    def merge_marker(self, revision):
 
1362
        """Get the merge marker to include in the output or '' if none."""
 
1363
        if len(revision.rev.parent_ids) > 1:
 
1364
            self._merge_count += 1
 
1365
            return ' [merge]'
 
1366
        else:
 
1367
            return ''
 
1368
 
1365
1369
    def show_properties(self, revision, indent):
1366
1370
        """Displays the custom properties returned by each registered handler.
1367
1371
 
1379
1383
class LongLogFormatter(LogFormatter):
1380
1384
 
1381
1385
    supports_merge_revisions = True
 
1386
    preferred_levels = 1
1382
1387
    supports_delta = True
1383
1388
    supports_tags = True
1384
1389
    supports_diff = True
1389
1394
        to_file = self.to_file
1390
1395
        to_file.write(indent + '-' * 60 + '\n')
1391
1396
        if revision.revno is not None:
1392
 
            to_file.write(indent + 'revno: %s\n' % (revision.revno,))
 
1397
            to_file.write(indent + 'revno: %s%s\n' % (revision.revno,
 
1398
                self.merge_marker(revision)))
1393
1399
        if revision.tags:
1394
1400
            to_file.write(indent + 'tags: %s\n' % (', '.join(revision.tags)))
1395
1401
        if self.show_ids:
1431
1437
            # revision information) so that the output can be fed to patch -p0
1432
1438
            self.show_diff(self.to_exact_file, revision.diff, indent)
1433
1439
 
 
1440
    def get_advice_separator(self):
 
1441
        """Get the text separating the log from the closing advice."""
 
1442
        return '-' * 60 + '\n'
 
1443
 
1434
1444
 
1435
1445
class ShortLogFormatter(LogFormatter):
1436
1446
 
1465
1475
        offset = ' ' * (revno_width + 1)
1466
1476
 
1467
1477
        to_file = self.to_file
1468
 
        is_merge = ''
1469
 
        if len(revision.rev.parent_ids) > 1:
1470
 
            is_merge = ' [merge]'
1471
1478
        tags = ''
1472
1479
        if revision.tags:
1473
1480
            tags = ' {%s}' % (', '.join(revision.tags))
1477
1484
                            revision.rev.timezone or 0,
1478
1485
                            self.show_timezone, date_fmt="%Y-%m-%d",
1479
1486
                            show_offset=False),
1480
 
                tags, is_merge))
 
1487
                tags, self.merge_marker(revision)))
1481
1488
        self.show_properties(revision.rev, indent+offset)
1482
1489
        if self.show_ids:
1483
1490
            to_file.write(indent + offset + 'revision-id:%s\n'
1826
1833
    info_list = []
1827
1834
    start_rev_info, end_rev_info = _get_revision_range(revisionspec_list, b,
1828
1835
        "log")
 
1836
    if relpaths in ([], [u'']):
 
1837
        return b, [], start_rev_info, end_rev_info
1829
1838
    if start_rev_info is None and end_rev_info is None:
1830
1839
        if tree is None:
1831
1840
            tree = b.basis_tree()