1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1
# Copyright (C) 2005-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
78
77
return [" %*s: %s\n" % (max_len, l, u) for l, u in self.locs ]
81
def gather_location_info(repository, branch=None, working=None):
80
def gather_location_info(repository=None, branch=None, working=None,
83
repository_path = repository.bzrdir.root_transport.base
84
83
if branch is not None:
85
branch_path = branch.bzrdir.root_transport.base
84
branch_path = branch.user_url
86
85
master_path = branch.get_bound_location()
87
86
if master_path is None:
88
87
master_path = branch_path
92
if control is not None and control.get_branch_reference():
93
locs['checkout of branch'] = control.get_branch_reference()
94
except NotBranchError:
93
working_path = working.bzrdir.root_transport.base
97
working_path = working.user_url
94
98
if working_path != branch_path:
95
99
locs['light checkout root'] = working_path
96
100
if master_path != branch_path:
107
111
locs['branch root'] = branch_path
109
113
working_path = None
110
if repository.is_shared():
114
if repository is not None and repository.is_shared():
111
115
# lightweight checkout of branch in shared repository
112
116
if branch_path is not None:
113
117
locs['repository branch'] = branch_path
114
118
elif branch_path is not None:
116
120
locs['branch root'] = branch_path
117
if master_path != branch_path:
118
locs['bound to branch'] = master_path
121
elif repository is not None:
122
locs['repository'] = repository.user_url
123
elif control is not None:
124
locs['control directory'] = control.user_url
120
locs['repository'] = repository_path
121
if repository.is_shared():
126
# Really, at least a control directory should be
127
# passed in for this method to be useful.
129
if master_path != branch_path:
130
locs['bound to branch'] = master_path
131
if repository is not None and repository.is_shared():
122
132
# 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',
133
locs['shared repository'] = repository.user_url
134
order = ['control directory', 'light checkout root',
135
'repository checkout root', 'checkout root',
136
'checkout of branch', 'shared repository',
126
137
'repository', 'repository branch', 'branch root',
127
138
'bound to branch']
128
139
return [(n, locs[n]) for n in order if n in locs]
160
171
outfile.writelines(locs.get_lines())
174
def _show_control_dir_info(control, outfile):
175
"""Show control dir information."""
176
if control._format.colocated_branches:
178
outfile.write('Control directory:\n')
179
outfile.write(' %d branches\n' % len(control.list_branches()))
163
182
def _show_format_info(control=None, repository=None, branch=None,
164
183
working=None, outfile=None):
165
184
"""Show known formats for control, working, branch and repository."""
223
242
"""Show missing revisions in working tree."""
224
243
branch = working.branch
225
244
basis = working.basis_tree()
226
work_inv = working.inventory
227
branch_revno, branch_last_revision = branch.last_revision_info()
246
branch_revno, branch_last_revision = branch.last_revision_info()
247
except errors.UnsupportedOperation:
229
250
tree_last_id = working.get_parent_ids()[0]
230
251
except IndexError:
241
262
def _show_working_stats(working, outfile):
242
263
"""Show statistics about a working tree."""
243
264
basis = working.basis_tree()
244
work_inv = working.inventory
245
265
delta = working.changes_from(basis, want_unchanged=True)
247
267
outfile.write('\n')
262
282
outfile.write(' %8d ignored\n' % ignore_cnt)
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)):
285
root_id = working.get_root_id()
286
for path, entry in working.iter_entries_by_dir():
287
if entry.kind == 'directory' and entry.file_id != root_id:
269
289
outfile.write(' %8d versioned %s\n' % (dir_cnt,
270
290
plural(dir_cnt, 'subdirectory', 'subdirectories')))
273
293
def _show_branch_stats(branch, verbose, outfile):
274
294
"""Show statistics about a branch."""
275
revno, head = branch.last_revision_info()
296
revno, head = branch.last_revision_info()
297
except errors.UnsupportedOperation:
276
299
outfile.write('\n')
277
300
outfile.write('Branch history:\n')
278
301
outfile.write(' %8d revision%s\n' % (revno, plural(revno)))
325
348
tree = a_bzrdir.open_workingtree(
326
349
recommend_upgrade=False)
327
except (NoWorkingTree, NotLocalUrl):
350
except (NoWorkingTree, NotLocalUrl, NotBranchError):
330
353
branch = a_bzrdir.open_branch()
346
368
repository = branch.repository
371
if lockable is not None:
351
374
show_component_info(a_bzrdir, repository, branch, tree, verbose,
377
if lockable is not None:
357
381
def show_component_info(control, repository, branch=None, working=None,
364
388
if verbose is True:
366
layout = describe_layout(repository, branch, working)
390
layout = describe_layout(repository, branch, working, control)
367
391
format = describe_format(control, repository, branch, working)
368
392
outfile.write("%s (format: %s)\n" % (layout, format))
369
_show_location_info(gather_location_info(repository, branch, working),
394
gather_location_info(control=control, repository=repository,
395
branch=branch, working=working),
371
397
if branch is not None:
372
398
_show_related_info(branch, outfile)
375
401
_show_format_info(control, repository, branch, working, outfile)
376
402
_show_locking_info(repository, branch, working, outfile)
403
_show_control_dir_info(control, outfile)
377
404
if branch is not None:
378
405
_show_missing_revisions_branch(branch, outfile)
379
406
if working is not None:
391
418
_show_repository_stats(repository, stats, outfile)
394
def describe_layout(repository=None, branch=None, tree=None):
421
def describe_layout(repository=None, branch=None, tree=None, control=None):
395
422
"""Convert a control directory layout into a user-understandable term
397
424
Common outputs include "Standalone tree", "Repository branch" and
398
425
"Checkout". Uncommon outputs include "Unshared repository with trees"
399
426
and "Empty control directory"
428
if branch is None and control is not None:
430
branch_reference = control.get_branch_reference()
431
except NotBranchError:
434
if branch_reference is not None:
435
return "Dangling branch reference"
401
436
if repository is None:
402
437
return 'Empty control directory'
403
438
if branch is None and tree is None:
420
455
if branch is None and tree is not None:
421
456
phrase = "branchless tree"
423
if (tree is not None and tree.bzrdir.root_transport.base !=
424
branch.bzrdir.root_transport.base):
458
if (tree is not None and tree.user_url !=
425
460
independence = ''
426
461
phrase = "Lightweight checkout"
427
462
elif branch.get_bound_location() is not None:
448
483
if (branch is not None and tree is not None and
449
branch.bzrdir.root_transport.base !=
450
tree.bzrdir.root_transport.base):
484
branch.user_url != tree.user_url):
452
486
repository = None
453
non_aliases = set(bzrdir.format_registry.keys())
454
non_aliases.difference_update(bzrdir.format_registry.aliases())
487
non_aliases = set(controldir.format_registry.keys())
488
non_aliases.difference_update(controldir.format_registry.aliases())
455
489
for key in non_aliases:
456
format = bzrdir.format_registry.make_bzrdir(key)
490
format = controldir.format_registry.make_bzrdir(key)
457
491
if isinstance(format, bzrdir.BzrDirMetaFormat1):
458
492
if (tree and format.workingtree_format !=
472
506
candidates.sort()
473
507
new_candidates = [c for c in candidates if not
474
bzrdir.format_registry.get_info(c).hidden]
508
controldir.format_registry.get_info(c).hidden]
475
509
if len(new_candidates) > 0:
476
510
# If there are any non-hidden formats that match, only return those to
477
511
# avoid listing hidden formats except when only a hidden format will
484
518
"""Hooks for the info command."""
486
520
def __init__(self):
487
super(InfoHooks, self).__init__()
488
self.create_hook(_mod_hooks.HookPoint('repository',
521
super(InfoHooks, self).__init__("bzrlib.info", "hooks")
522
self.add_hook('repository',
489
523
"Invoked when displaying the statistics for a repository. "
490
524
"repository is called with a statistics dictionary as returned "
491
"by the repository and a file-like object to write to.", (1, 15),
525
"by the repository and a file-like object to write to.", (1, 15))
495
528
hooks = InfoHooks()