128
128
return [(n, locs[n]) for n in order if n in locs]
131
def _show_location_info(locs):
131
def _show_location_info(locs, outfile):
132
132
"""Show known locations for working, branch and repository."""
134
path_list = LocationList(os.getcwd())
133
outfile.write('Location:\n')
134
path_list = LocationList(osutils.getcwd())
135
135
for name, loc in locs:
136
136
path_list.add_url(name, loc)
137
sys.stdout.writelines(path_list.get_lines())
137
outfile.writelines(path_list.get_lines())
139
140
def _gather_related_branches(branch):
140
locs = LocationList(os.getcwd())
141
locs = LocationList(osutils.getcwd())
141
142
locs.add_url('public branch', branch.get_public_branch())
142
143
locs.add_url('push branch', branch.get_push_location())
143
144
locs.add_url('parent branch', branch.get_parent())
144
145
locs.add_url('submit branch', branch.get_submit_branch())
147
locs.add_url('stacked on', branch.get_stacked_on_url())
148
except (errors.UnstackableBranchFormat, errors.UnstackableRepositoryFormat,
147
154
def _show_related_info(branch, outfile):
148
155
"""Show parent and push location of branch."""
149
156
locs = _gather_related_branches(branch)
150
157
if len(locs.locs) > 0:
152
print >> outfile, 'Related branches:'
159
outfile.write('Related branches:\n')
153
160
outfile.writelines(locs.get_lines())
156
def _show_format_info(control=None, repository=None, branch=None, working=None):
163
def _show_format_info(control=None, repository=None, branch=None,
164
working=None, outfile=None):
157
165
"""Show known formats for control, working, branch and repository."""
167
outfile.write('Format:\n')
161
print ' control: %s' % control._format.get_format_description()
169
outfile.write(' control: %s\n' %
170
control._format.get_format_description())
163
print ' working tree: %s' % working._format.get_format_description()
172
outfile.write(' working tree: %s\n' %
173
working._format.get_format_description())
165
print ' branch: %s' % branch._format.get_format_description()
175
outfile.write(' branch: %s\n' %
176
branch._format.get_format_description())
167
print ' repository: %s' % repository._format.get_format_description()
170
def _show_locking_info(repository, branch=None, working=None):
178
outfile.write(' repository: %s\n' %
179
repository._format.get_format_description())
182
def _show_locking_info(repository, branch=None, working=None, outfile=None):
171
183
"""Show locking status of working, branch and repository."""
172
184
if (repository.get_physical_lock_status() or
173
185
(branch and branch.get_physical_lock_status()) or
174
186
(working and working.get_physical_lock_status())):
188
outfile.write('Lock status:\n')
178
190
if working.get_physical_lock_status():
179
191
status = 'locked'
181
193
status = 'unlocked'
182
print ' working tree: %s' % status
194
outfile.write(' working tree: %s\n' % status)
184
196
if branch.get_physical_lock_status():
185
197
status = 'locked'
187
199
status = 'unlocked'
188
print ' branch: %s' % status
200
outfile.write(' branch: %s\n' % status)
190
202
if repository.get_physical_lock_status():
191
203
status = 'locked'
193
205
status = 'unlocked'
194
print ' repository: %s' % status
197
def _show_missing_revisions_branch(branch):
206
outfile.write(' repository: %s\n' % status)
209
def _show_missing_revisions_branch(branch, outfile):
198
210
"""Show missing master revisions in branch."""
199
211
# Try with inaccessible branch ?
200
212
master = branch.get_master_branch()
202
214
local_extra, remote_extra = find_unmerged(branch, master)
205
print 'Branch is out of date: missing %d revision%s.' % (
206
len(remote_extra), plural(len(remote_extra)))
209
def _show_missing_revisions_working(working):
217
outfile.write(('Branch is out of date: missing %d '
218
'revision%s.\n') % (len(remote_extra),
219
plural(len(remote_extra))))
222
def _show_missing_revisions_working(working, outfile):
210
223
"""Show missing revisions in working tree."""
211
224
branch = working.branch
212
225
basis = working.basis_tree()
220
233
if branch_revno and tree_last_id != branch_last_revision:
221
234
tree_last_revno = branch.revision_id_to_revno(tree_last_id)
222
235
missing_count = branch_revno - tree_last_revno
224
print 'Working tree is out of date: missing %d revision%s.' % (
225
missing_count, plural(missing_count))
228
def _show_working_stats(working):
237
outfile.write(('Working tree is out of date: missing %d '
238
'revision%s.\n') % (missing_count, plural(missing_count)))
241
def _show_working_stats(working, outfile):
229
242
"""Show statistics about a working tree."""
230
243
basis = working.basis_tree()
231
244
work_inv = working.inventory
232
245
delta = working.changes_from(basis, want_unchanged=True)
235
print 'In the working tree:'
236
print ' %8s unchanged' % len(delta.unchanged)
237
print ' %8d modified' % len(delta.modified)
238
print ' %8d added' % len(delta.added)
239
print ' %8d removed' % len(delta.removed)
240
print ' %8d renamed' % len(delta.renamed)
248
outfile.write('In the working tree:\n')
249
outfile.write(' %8s unchanged\n' % len(delta.unchanged))
250
outfile.write(' %8d modified\n' % len(delta.modified))
251
outfile.write(' %8d added\n' % len(delta.added))
252
outfile.write(' %8d removed\n' % len(delta.removed))
253
outfile.write(' %8d renamed\n' % len(delta.renamed))
242
255
ignore_cnt = unknown_cnt = 0
243
256
for path in working.extras():
248
print ' %8d unknown' % unknown_cnt
249
print ' %8d ignored' % ignore_cnt
261
outfile.write(' %8d unknown\n' % unknown_cnt)
262
outfile.write(' %8d ignored\n' % ignore_cnt)
252
265
for file_id in work_inv:
253
if (work_inv.get_file_kind(file_id) == 'directory' and
266
if (work_inv.get_file_kind(file_id) == 'directory' and
254
267
not work_inv.is_root(file_id)):
256
print ' %8d versioned %s' \
258
plural(dir_cnt, 'subdirectory', 'subdirectories'))
261
def _show_branch_stats(branch, verbose):
269
outfile.write(' %8d versioned %s\n' % (dir_cnt,
270
plural(dir_cnt, 'subdirectory', 'subdirectories')))
273
def _show_branch_stats(branch, verbose, outfile):
262
274
"""Show statistics about a branch."""
263
275
revno, head = branch.last_revision_info()
265
print 'Branch history:'
266
print ' %8d revision%s' % (revno, plural(revno))
277
outfile.write('Branch history:\n')
278
outfile.write(' %8d revision%s\n' % (revno, plural(revno)))
267
279
stats = branch.repository.gather_stats(head, committers=verbose)
269
281
committers = stats['committers']
270
print ' %8d committer%s' % (committers, plural(committers))
282
outfile.write(' %8d committer%s\n' % (committers,
272
285
timestamp, timezone = stats['firstrev']
273
286
age = int((time.time() - timestamp) / 3600 / 24)
274
print ' %8d day%s old' % (age, plural(age))
275
print ' first revision: %s' % osutils.format_date(timestamp,
287
outfile.write(' %8d day%s old\n' % (age, plural(age)))
288
outfile.write(' first revision: %s\n' %
289
osutils.format_date(timestamp, timezone))
277
290
timestamp, timezone = stats['latestrev']
278
print ' latest revision: %s' % osutils.format_date(timestamp,
291
outfile.write(' latest revision: %s\n' %
292
osutils.format_date(timestamp, timezone))
283
def _show_repository_info(repository):
296
def _show_repository_info(repository, outfile):
284
297
"""Show settings of a repository."""
285
298
if repository.make_working_trees():
287
print 'Create working tree for new branches inside the repository.'
290
def _show_repository_stats(stats):
300
outfile.write('Create working tree for new branches inside '
304
def _show_repository_stats(repository, stats, outfile):
291
305
"""Show statistics about a repository."""
292
if 'revisions' in stats or 'size' in stats:
295
307
if 'revisions' in stats:
296
308
revisions = stats['revisions']
297
print ' %8d revision%s' % (revisions, plural(revisions))
309
f.write(' %8d revision%s\n' % (revisions, plural(revisions)))
298
310
if 'size' in stats:
299
print ' %8d KiB' % (stats['size']/1024)
301
def show_bzrdir_info(a_bzrdir, verbose=False):
311
f.write(' %8d KiB\n' % (stats['size']/1024))
312
for hook in hooks['repository']:
313
hook(repository, stats, f)
314
if f.getvalue() != "":
316
outfile.write('Repository:\n')
317
outfile.write(f.getvalue())
320
def show_bzrdir_info(a_bzrdir, verbose=False, outfile=None):
302
321
"""Output to stdout the 'info' for a_bzrdir."""
304
325
tree = a_bzrdir.open_workingtree(
305
326
recommend_upgrade=False)
328
349
lockable.lock_read()
330
show_component_info(a_bzrdir, repository, branch, tree, verbose)
351
show_component_info(a_bzrdir, repository, branch, tree, verbose,
332
354
lockable.unlock()
335
357
def show_component_info(control, repository, branch=None, working=None,
358
verbose=1, outfile=None):
337
359
"""Write info about all bzrdir components to stdout"""
338
362
if verbose is False:
340
364
if verbose is True:
342
366
layout = describe_layout(repository, branch, working)
343
367
format = describe_format(control, repository, branch, working)
344
print "%s (format: %s)" % (layout, format)
345
_show_location_info(gather_location_info(repository, branch, working))
368
outfile.write("%s (format: %s)\n" % (layout, format))
369
_show_location_info(gather_location_info(repository, branch, working),
346
371
if branch is not None:
347
_show_related_info(branch, sys.stdout)
372
_show_related_info(branch, outfile)
350
_show_format_info(control, repository, branch, working)
351
_show_locking_info(repository, branch, working)
375
_show_format_info(control, repository, branch, working, outfile)
376
_show_locking_info(repository, branch, working, outfile)
352
377
if branch is not None:
353
_show_missing_revisions_branch(branch)
378
_show_missing_revisions_branch(branch, outfile)
354
379
if working is not None:
355
_show_missing_revisions_working(working)
356
_show_working_stats(working)
380
_show_missing_revisions_working(working, outfile)
381
_show_working_stats(working, outfile)
357
382
elif branch is not None:
358
_show_missing_revisions_branch(branch)
383
_show_missing_revisions_branch(branch, outfile)
359
384
if branch is not None:
360
stats = _show_branch_stats(branch, verbose==2)
385
show_committers = verbose >= 2
386
stats = _show_branch_stats(branch, show_committers, outfile)
362
388
stats = repository.gather_stats()
363
389
if branch is None and working is None:
364
_show_repository_info(repository)
365
_show_repository_stats(stats)
390
_show_repository_info(repository, outfile)
391
_show_repository_stats(repository, stats, outfile)
368
394
def describe_layout(repository=None, branch=None, tree=None):
441
469
candidates.append(key)
442
470
if len(candidates) == 0:
444
new_candidates = [c for c in candidates if c != 'default']
445
if len(new_candidates) > 0:
446
candidates = new_candidates
447
473
new_candidates = [c for c in candidates if not
448
474
bzrdir.format_registry.get_info(c).hidden]
449
475
if len(new_candidates) > 0:
476
# If there are any non-hidden formats that match, only return those to
477
# avoid listing hidden formats except when only a hidden format will
450
479
candidates = new_candidates
451
480
return ' or '.join(candidates)
453
@deprecated_function(zero_eight)
455
"""Please see show_bzrdir_info."""
456
return show_bzrdir_info(b.bzrdir)
459
@deprecated_function(zero_eighteen)
460
def show_tree_info(working, verbose):
461
"""Output to stdout the 'info' for working."""
462
branch = working.branch
463
repository = branch.repository
464
control = working.bzrdir
465
show_component_info(control, repository, branch, working, verbose)
468
@deprecated_function(zero_eighteen)
469
def show_branch_info(branch, verbose):
470
"""Output to stdout the 'info' for branch."""
471
repository = branch.repository
472
control = branch.bzrdir
473
show_component_info(control, repository, branch, verbose=verbose)
476
@deprecated_function(zero_eighteen)
477
def show_repository_info(repository, verbose):
478
"""Output to stdout the 'info' for repository."""
479
control = repository.bzrdir
480
show_component_info(control, repository, verbose=verbose)
483
class InfoHooks(_mod_hooks.Hooks):
484
"""Hooks for the info command."""
487
self.create_hook(_mod_hooks.HookPoint('repository',
488
"Invoked when displaying the statistics for a repository. "
489
"repository is called with a statistics dictionary as returned "
490
"by the repository and a file-like object to write to.", (1, 15),