~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/info.py

  • Committer: Patch Queue Manager
  • Date: 2016-04-21 05:06:57 UTC
  • mfrom: (6603.4.1 bzr)
  • Revision ID: pqm@pqm.ubuntu.com-20160421050657-ygnzfybewvudf1j9
(richard-wilbur) Use initial_comment as commit_message for lp_propose.(Shawn
 Wang) (Shawn Wang)

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
from __future__ import absolute_import
 
18
 
17
19
__all__ = ['show_bzrdir_info']
18
20
 
19
21
from cStringIO import StringIO
20
 
import os
21
22
import time
22
23
import sys
23
24
 
24
25
from bzrlib import (
25
26
    bzrdir,
26
 
    diff,
 
27
    controldir,
27
28
    errors,
28
29
    hooks as _mod_hooks,
29
30
    osutils,
78
79
        return ["  %*s: %s\n" % (max_len, l, u) for l, u in self.locs ]
79
80
 
80
81
 
81
 
def gather_location_info(repository, branch=None, working=None):
 
82
def gather_location_info(repository=None, branch=None, working=None,
 
83
        control=None):
82
84
    locs = {}
83
 
    repository_path = repository.bzrdir.root_transport.base
84
85
    if branch is not None:
85
 
        branch_path = branch.bzrdir.root_transport.base
 
86
        branch_path = branch.user_url
86
87
        master_path = branch.get_bound_location()
87
88
        if master_path is None:
88
89
            master_path = branch_path
89
90
    else:
90
91
        branch_path = None
91
92
        master_path = None
 
93
        try:
 
94
            if control is not None and control.get_branch_reference():
 
95
                locs['checkout of branch'] = control.get_branch_reference()
 
96
        except NotBranchError:
 
97
            pass
92
98
    if working:
93
 
        working_path = working.bzrdir.root_transport.base
 
99
        working_path = working.user_url
94
100
        if working_path != branch_path:
95
101
            locs['light checkout root'] = working_path
96
102
        if master_path != branch_path:
107
113
            locs['branch root'] = branch_path
108
114
    else:
109
115
        working_path = None
110
 
        if repository.is_shared():
 
116
        if repository is not None and repository.is_shared():
111
117
            # lightweight checkout of branch in shared repository
112
118
            if branch_path is not None:
113
119
                locs['repository branch'] = branch_path
114
120
        elif branch_path is not None:
115
121
            # standalone
116
122
            locs['branch root'] = branch_path
117
 
            if master_path != branch_path:
118
 
                locs['bound to branch'] = master_path
 
123
        elif repository is not None:
 
124
            locs['repository'] = repository.user_url
 
125
        elif control is not None:
 
126
            locs['control directory'] = control.user_url
119
127
        else:
120
 
            locs['repository'] = repository_path
121
 
    if repository.is_shared():
 
128
            # Really, at least a control directory should be
 
129
            # passed in for this method to be useful.
 
130
            pass
 
131
        if master_path != branch_path:
 
132
            locs['bound to branch'] = master_path
 
133
    if repository is not None and repository.is_shared():
122
134
        # lightweight checkout of branch in shared repository
123
 
        locs['shared repository'] = repository_path
124
 
    order = ['light checkout root', 'repository checkout root',
125
 
             'checkout root', 'checkout of branch', 'shared repository',
 
135
        locs['shared repository'] = repository.user_url
 
136
    order = ['control directory', 'light checkout root',
 
137
             'repository checkout root', 'checkout root',
 
138
             'checkout of branch', 'shared repository',
126
139
             'repository', 'repository branch', 'branch root',
127
140
             'bound to branch']
128
141
    return [(n, locs[n]) for n in order if n in locs]
160
173
        outfile.writelines(locs.get_lines())
161
174
 
162
175
 
 
176
def _show_control_dir_info(control, outfile):
 
177
    """Show control dir information."""
 
178
    if control._format.colocated_branches:
 
179
        outfile.write('\n')
 
180
        outfile.write('Control directory:\n')
 
181
        outfile.write('         %d branches\n' % len(control.list_branches()))
 
182
 
 
183
 
163
184
def _show_format_info(control=None, repository=None, branch=None,
164
185
                      working=None, outfile=None):
165
186
    """Show known formats for control, working, branch and repository."""
179
200
            repository._format.get_format_description())
180
201
 
181
202
 
182
 
def _show_locking_info(repository, branch=None, working=None, outfile=None):
 
203
def _show_locking_info(repository=None, branch=None, working=None,
 
204
        outfile=None):
183
205
    """Show locking status of working, branch and repository."""
184
 
    if (repository.get_physical_lock_status() or
 
206
    if (repository and repository.get_physical_lock_status() or
185
207
        (branch and branch.get_physical_lock_status()) or
186
208
        (working and working.get_physical_lock_status())):
187
209
        outfile.write('\n')
223
245
    """Show missing revisions in working tree."""
224
246
    branch = working.branch
225
247
    basis = working.basis_tree()
226
 
    work_inv = working.inventory
227
 
    branch_revno, branch_last_revision = branch.last_revision_info()
 
248
    try:
 
249
        branch_revno, branch_last_revision = branch.last_revision_info()
 
250
    except errors.UnsupportedOperation:
 
251
        return
228
252
    try:
229
253
        tree_last_id = working.get_parent_ids()[0]
230
254
    except IndexError:
241
265
def _show_working_stats(working, outfile):
242
266
    """Show statistics about a working tree."""
243
267
    basis = working.basis_tree()
244
 
    work_inv = working.inventory
245
268
    delta = working.changes_from(basis, want_unchanged=True)
246
269
 
247
270
    outfile.write('\n')
262
285
    outfile.write('  %8d ignored\n' % ignore_cnt)
263
286
 
264
287
    dir_cnt = 0
265
 
    for file_id in work_inv:
266
 
        if (work_inv.get_file_kind(file_id) == 'directory' and
267
 
            not work_inv.is_root(file_id)):
 
288
    root_id = working.get_root_id()
 
289
    for path, entry in working.iter_entries_by_dir():
 
290
        if entry.kind == 'directory' and entry.file_id != root_id:
268
291
            dir_cnt += 1
269
292
    outfile.write('  %8d versioned %s\n' % (dir_cnt,
270
293
        plural(dir_cnt, 'subdirectory', 'subdirectories')))
272
295
 
273
296
def _show_branch_stats(branch, verbose, outfile):
274
297
    """Show statistics about a branch."""
275
 
    revno, head = branch.last_revision_info()
 
298
    try:
 
299
        revno, head = branch.last_revision_info()
 
300
    except errors.UnsupportedOperation:
 
301
        return {}
276
302
    outfile.write('\n')
277
303
    outfile.write('Branch history:\n')
278
304
    outfile.write('  %8d revision%s\n' % (revno, plural(revno)))
324
350
    try:
325
351
        tree = a_bzrdir.open_workingtree(
326
352
            recommend_upgrade=False)
327
 
    except (NoWorkingTree, NotLocalUrl):
 
353
    except (NoWorkingTree, NotLocalUrl, NotBranchError):
328
354
        tree = None
329
355
        try:
330
 
            branch = a_bzrdir.open_branch()
 
356
            branch = a_bzrdir.open_branch(name="")
331
357
        except NotBranchError:
332
358
            branch = None
333
359
            try:
334
360
                repository = a_bzrdir.open_repository()
335
361
            except NoRepositoryPresent:
336
 
                # Return silently; cmd_info already returned NotBranchError
337
 
                # if no bzrdir could be opened.
338
 
                return
 
362
                lockable = None
 
363
                repository = None
339
364
            else:
340
365
                lockable = repository
341
366
        else:
346
371
        repository = branch.repository
347
372
        lockable = tree
348
373
 
349
 
    lockable.lock_read()
 
374
    if lockable is not None:
 
375
        lockable.lock_read()
350
376
    try:
351
377
        show_component_info(a_bzrdir, repository, branch, tree, verbose,
352
378
                            outfile)
353
379
    finally:
354
 
        lockable.unlock()
 
380
        if lockable is not None:
 
381
            lockable.unlock()
355
382
 
356
383
 
357
384
def show_component_info(control, repository, branch=None, working=None,
363
390
        verbose = 1
364
391
    if verbose is True:
365
392
        verbose = 2
366
 
    layout = describe_layout(repository, branch, working)
 
393
    layout = describe_layout(repository, branch, working, control)
367
394
    format = describe_format(control, repository, branch, working)
368
395
    outfile.write("%s (format: %s)\n" % (layout, format))
369
 
    _show_location_info(gather_location_info(repository, branch, working),
370
 
                        outfile)
 
396
    _show_location_info(
 
397
        gather_location_info(control=control, repository=repository,
 
398
            branch=branch, working=working),
 
399
        outfile)
371
400
    if branch is not None:
372
401
        _show_related_info(branch, outfile)
373
402
    if verbose == 0:
374
403
        return
375
404
    _show_format_info(control, repository, branch, working, outfile)
376
405
    _show_locking_info(repository, branch, working, outfile)
 
406
    _show_control_dir_info(control, outfile)
377
407
    if branch is not None:
378
408
        _show_missing_revisions_branch(branch, outfile)
379
409
    if working is not None:
384
414
    if branch is not None:
385
415
        show_committers = verbose >= 2
386
416
        stats = _show_branch_stats(branch, show_committers, outfile)
387
 
    else:
 
417
    elif repository is not None:
388
418
        stats = repository.gather_stats()
389
 
    if branch is None and working is None:
 
419
    if branch is None and working is None and repository is not None:
390
420
        _show_repository_info(repository, outfile)
391
 
    _show_repository_stats(repository, stats, outfile)
392
 
 
393
 
 
394
 
def describe_layout(repository=None, branch=None, tree=None):
 
421
    if repository is not None:
 
422
        _show_repository_stats(repository, stats, outfile)
 
423
 
 
424
 
 
425
def describe_layout(repository=None, branch=None, tree=None, control=None):
395
426
    """Convert a control directory layout into a user-understandable term
396
427
 
397
428
    Common outputs include "Standalone tree", "Repository branch" and
398
429
    "Checkout".  Uncommon outputs include "Unshared repository with trees"
399
430
    and "Empty control directory"
400
431
    """
 
432
    if branch is None and control is not None:
 
433
        try:
 
434
            branch_reference = control.get_branch_reference()
 
435
        except NotBranchError:
 
436
            pass
 
437
        else:
 
438
            if branch_reference is not None:
 
439
                return "Dangling branch reference"
401
440
    if repository is None:
402
441
        return 'Empty control directory'
403
442
    if branch is None and tree is None:
405
444
            phrase = 'Shared repository'
406
445
        else:
407
446
            phrase = 'Unshared repository'
 
447
        extra = []
408
448
        if repository.make_working_trees():
409
 
            phrase += ' with trees'
 
449
            extra.append('trees')
 
450
        if len(control.get_branches()) > 0:
 
451
            extra.append('colocated branches')
 
452
        if extra:
 
453
            phrase += ' with ' + " and ".join(extra)
410
454
        return phrase
411
455
    else:
412
456
        if repository.is_shared():
420
464
        if branch is None and tree is not None:
421
465
            phrase = "branchless tree"
422
466
        else:
423
 
            if (tree is not None and tree.bzrdir.root_transport.base !=
424
 
                branch.bzrdir.root_transport.base):
 
467
            if (tree is not None and tree.user_url !=
 
468
                branch.user_url):
425
469
                independence = ''
426
470
                phrase = "Lightweight checkout"
427
471
            elif branch.get_bound_location() is not None:
446
490
    """
447
491
    candidates  = []
448
492
    if (branch is not None and tree is not None and
449
 
        branch.bzrdir.root_transport.base !=
450
 
        tree.bzrdir.root_transport.base):
 
493
        branch.user_url != tree.user_url):
451
494
        branch = None
452
495
        repository = None
453
 
    non_aliases = set(bzrdir.format_registry.keys())
454
 
    non_aliases.difference_update(bzrdir.format_registry.aliases())
 
496
    non_aliases = set(controldir.format_registry.keys())
 
497
    non_aliases.difference_update(controldir.format_registry.aliases())
455
498
    for key in non_aliases:
456
 
        format = bzrdir.format_registry.make_bzrdir(key)
 
499
        format = controldir.format_registry.make_bzrdir(key)
457
500
        if isinstance(format, bzrdir.BzrDirMetaFormat1):
458
501
            if (tree and format.workingtree_format !=
459
502
                tree._format):
471
514
        return 'unnamed'
472
515
    candidates.sort()
473
516
    new_candidates = [c for c in candidates if not
474
 
        bzrdir.format_registry.get_info(c).hidden]
 
517
        controldir.format_registry.get_info(c).hidden]
475
518
    if len(new_candidates) > 0:
476
519
        # If there are any non-hidden formats that match, only return those to
477
520
        # avoid listing hidden formats except when only a hidden format will
484
527
    """Hooks for the info command."""
485
528
 
486
529
    def __init__(self):
487
 
        super(InfoHooks, self).__init__()
488
 
        self.create_hook(_mod_hooks.HookPoint('repository',
 
530
        super(InfoHooks, self).__init__("bzrlib.info", "hooks")
 
531
        self.add_hook('repository',
489
532
            "Invoked when displaying the statistics for a repository. "
490
533
            "repository is called with a statistics dictionary as returned "
491
 
            "by the repository and a file-like object to write to.", (1, 15), 
492
 
            None))
 
534
            "by the repository and a file-like object to write to.", (1, 15))
493
535
 
494
536
 
495
537
hooks = InfoHooks()