13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
17
__all__ = ['show_bzrdir_info']
19
from cStringIO import StringIO
23
23
from bzrlib import (
30
30
from bzrlib.errors import (NoWorkingTree, NotBranchError,
31
31
NoRepositoryPresent, NotLocalUrl)
32
32
from bzrlib.missing import find_unmerged
33
from bzrlib.symbol_versioning import (deprecated_function,
34
zero_eight, zero_eighteen)
35
37
def plural(n, base='', pl=None):
126
128
return [(n, locs[n]) for n in order if n in locs]
129
def _show_location_info(locs, outfile):
131
def _show_location_info(locs):
130
132
"""Show known locations for working, branch and repository."""
131
outfile.write('Location:\n')
132
path_list = LocationList(osutils.getcwd())
134
path_list = LocationList(os.getcwd())
133
135
for name, loc in locs:
134
136
path_list.add_url(name, loc)
135
outfile.writelines(path_list.get_lines())
137
sys.stdout.writelines(path_list.get_lines())
138
139
def _gather_related_branches(branch):
139
locs = LocationList(osutils.getcwd())
140
locs = LocationList(os.getcwd())
140
141
locs.add_url('public branch', branch.get_public_branch())
141
142
locs.add_url('push branch', branch.get_push_location())
142
143
locs.add_url('parent branch', branch.get_parent())
143
144
locs.add_url('submit branch', branch.get_submit_branch())
145
locs.add_url('stacked on', branch.get_stacked_on_url())
146
except (errors.UnstackableBranchFormat, errors.UnstackableRepositoryFormat,
152
147
def _show_related_info(branch, outfile):
153
148
"""Show parent and push location of branch."""
154
149
locs = _gather_related_branches(branch)
155
150
if len(locs.locs) > 0:
157
outfile.write('Related branches:\n')
152
print >> outfile, 'Related branches:'
158
153
outfile.writelines(locs.get_lines())
161
def _show_format_info(control=None, repository=None, branch=None,
162
working=None, outfile=None):
156
def _show_format_info(control=None, repository=None, branch=None, working=None):
163
157
"""Show known formats for control, working, branch and repository."""
165
outfile.write('Format:\n')
167
outfile.write(' control: %s\n' %
168
control._format.get_format_description())
161
print ' control: %s' % control._format.get_format_description()
170
outfile.write(' working tree: %s\n' %
171
working._format.get_format_description())
163
print ' working tree: %s' % working._format.get_format_description()
173
outfile.write(' branch: %s\n' %
174
branch._format.get_format_description())
165
print ' branch: %s' % branch._format.get_format_description()
176
outfile.write(' repository: %s\n' %
177
repository._format.get_format_description())
180
def _show_locking_info(repository, branch=None, working=None, outfile=None):
167
print ' repository: %s' % repository._format.get_format_description()
170
def _show_locking_info(repository, branch=None, working=None):
181
171
"""Show locking status of working, branch and repository."""
182
172
if (repository.get_physical_lock_status() or
183
173
(branch and branch.get_physical_lock_status()) or
184
174
(working and working.get_physical_lock_status())):
186
outfile.write('Lock status:\n')
188
178
if working.get_physical_lock_status():
189
179
status = 'locked'
191
181
status = 'unlocked'
192
outfile.write(' working tree: %s\n' % status)
182
print ' working tree: %s' % status
194
184
if branch.get_physical_lock_status():
195
185
status = 'locked'
197
187
status = 'unlocked'
198
outfile.write(' branch: %s\n' % status)
188
print ' branch: %s' % status
200
190
if repository.get_physical_lock_status():
201
191
status = 'locked'
203
193
status = 'unlocked'
204
outfile.write(' repository: %s\n' % status)
207
def _show_missing_revisions_branch(branch, outfile):
194
print ' repository: %s' % status
197
def _show_missing_revisions_branch(branch):
208
198
"""Show missing master revisions in branch."""
209
199
# Try with inaccessible branch ?
210
200
master = branch.get_master_branch()
212
202
local_extra, remote_extra = find_unmerged(branch, master)
215
outfile.write(('Branch is out of date: missing %d '
216
'revision%s.\n') % (len(remote_extra),
217
plural(len(remote_extra))))
220
def _show_missing_revisions_working(working, outfile):
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):
221
210
"""Show missing revisions in working tree."""
222
211
branch = working.branch
223
212
basis = working.basis_tree()
231
220
if branch_revno and tree_last_id != branch_last_revision:
232
221
tree_last_revno = branch.revision_id_to_revno(tree_last_id)
233
222
missing_count = branch_revno - tree_last_revno
235
outfile.write(('Working tree is out of date: missing %d '
236
'revision%s.\n') % (missing_count, plural(missing_count)))
239
def _show_working_stats(working, outfile):
224
print 'Working tree is out of date: missing %d revision%s.' % (
225
missing_count, plural(missing_count))
228
def _show_working_stats(working):
240
229
"""Show statistics about a working tree."""
241
230
basis = working.basis_tree()
242
231
work_inv = working.inventory
243
232
delta = working.changes_from(basis, want_unchanged=True)
246
outfile.write('In the working tree:\n')
247
outfile.write(' %8s unchanged\n' % len(delta.unchanged))
248
outfile.write(' %8d modified\n' % len(delta.modified))
249
outfile.write(' %8d added\n' % len(delta.added))
250
outfile.write(' %8d removed\n' % len(delta.removed))
251
outfile.write(' %8d renamed\n' % len(delta.renamed))
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)
253
242
ignore_cnt = unknown_cnt = 0
254
243
for path in working.extras():
259
outfile.write(' %8d unknown\n' % unknown_cnt)
260
outfile.write(' %8d ignored\n' % ignore_cnt)
248
print ' %8d unknown' % unknown_cnt
249
print ' %8d ignored' % ignore_cnt
263
252
for file_id in work_inv:
264
if (work_inv.get_file_kind(file_id) == 'directory' and
253
if (work_inv.get_file_kind(file_id) == 'directory' and
265
254
not work_inv.is_root(file_id)):
267
outfile.write(' %8d versioned %s\n' % (dir_cnt,
268
plural(dir_cnt, 'subdirectory', 'subdirectories')))
271
def _show_branch_stats(branch, verbose, outfile):
256
print ' %8d versioned %s' \
258
plural(dir_cnt, 'subdirectory', 'subdirectories'))
261
def _show_branch_stats(branch, verbose):
272
262
"""Show statistics about a branch."""
273
263
revno, head = branch.last_revision_info()
275
outfile.write('Branch history:\n')
276
outfile.write(' %8d revision%s\n' % (revno, plural(revno)))
265
print 'Branch history:'
266
print ' %8d revision%s' % (revno, plural(revno))
277
267
stats = branch.repository.gather_stats(head, committers=verbose)
279
269
committers = stats['committers']
280
outfile.write(' %8d committer%s\n' % (committers,
270
print ' %8d committer%s' % (committers, plural(committers))
283
272
timestamp, timezone = stats['firstrev']
284
273
age = int((time.time() - timestamp) / 3600 / 24)
285
outfile.write(' %8d day%s old\n' % (age, plural(age)))
286
outfile.write(' first revision: %s\n' %
287
osutils.format_date(timestamp, timezone))
274
print ' %8d day%s old' % (age, plural(age))
275
print ' first revision: %s' % osutils.format_date(timestamp,
288
277
timestamp, timezone = stats['latestrev']
289
outfile.write(' latest revision: %s\n' %
290
osutils.format_date(timestamp, timezone))
278
print ' latest revision: %s' % osutils.format_date(timestamp,
294
def _show_repository_info(repository, outfile):
283
def _show_repository_info(repository):
295
284
"""Show settings of a repository."""
296
285
if repository.make_working_trees():
298
outfile.write('Create working tree for new branches inside '
302
def _show_repository_stats(repository, stats, outfile):
287
print 'Create working tree for new branches inside the repository.'
290
def _show_repository_stats(stats):
303
291
"""Show statistics about a repository."""
292
if 'revisions' in stats or 'size' in stats:
305
295
if 'revisions' in stats:
306
296
revisions = stats['revisions']
307
f.write(' %8d revision%s\n' % (revisions, plural(revisions)))
297
print ' %8d revision%s' % (revisions, plural(revisions))
308
298
if 'size' in stats:
309
f.write(' %8d KiB\n' % (stats['size']/1024))
310
for hook in hooks['repository']:
311
hook(repository, stats, f)
312
if f.getvalue() != "":
314
outfile.write('Repository:\n')
315
outfile.write(f.getvalue())
318
def show_bzrdir_info(a_bzrdir, verbose=False, outfile=None):
299
print ' %8d KiB' % (stats['size']/1024)
301
def show_bzrdir_info(a_bzrdir, verbose=False):
319
302
"""Output to stdout the 'info' for a_bzrdir."""
323
304
tree = a_bzrdir.open_workingtree(
324
305
recommend_upgrade=False)
347
328
lockable.lock_read()
349
show_component_info(a_bzrdir, repository, branch, tree, verbose,
330
show_component_info(a_bzrdir, repository, branch, tree, verbose)
352
332
lockable.unlock()
355
335
def show_component_info(control, repository, branch=None, working=None,
356
verbose=1, outfile=None):
357
337
"""Write info about all bzrdir components to stdout"""
360
338
if verbose is False:
362
340
if verbose is True:
364
342
layout = describe_layout(repository, branch, working)
365
343
format = describe_format(control, repository, branch, working)
366
outfile.write("%s (format: %s)\n" % (layout, format))
367
_show_location_info(gather_location_info(repository, branch, working),
344
print "%s (format: %s)" % (layout, format)
345
_show_location_info(gather_location_info(repository, branch, working))
369
346
if branch is not None:
370
_show_related_info(branch, outfile)
347
_show_related_info(branch, sys.stdout)
373
_show_format_info(control, repository, branch, working, outfile)
374
_show_locking_info(repository, branch, working, outfile)
350
_show_format_info(control, repository, branch, working)
351
_show_locking_info(repository, branch, working)
375
352
if branch is not None:
376
_show_missing_revisions_branch(branch, outfile)
353
_show_missing_revisions_branch(branch)
377
354
if working is not None:
378
_show_missing_revisions_working(working, outfile)
379
_show_working_stats(working, outfile)
355
_show_missing_revisions_working(working)
356
_show_working_stats(working)
380
357
elif branch is not None:
381
_show_missing_revisions_branch(branch, outfile)
358
_show_missing_revisions_branch(branch)
382
359
if branch is not None:
383
show_committers = verbose >= 2
384
stats = _show_branch_stats(branch, show_committers, outfile)
360
stats = _show_branch_stats(branch, verbose==2)
386
362
stats = repository.gather_stats()
387
363
if branch is None and working is None:
388
_show_repository_info(repository, outfile)
389
_show_repository_stats(repository, stats, outfile)
364
_show_repository_info(repository)
365
_show_repository_stats(stats)
392
368
def describe_layout(repository=None, branch=None, tree=None):
466
441
candidates.append(key)
467
442
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
470
447
new_candidates = [c for c in candidates if not
471
448
bzrdir.format_registry.get_info(c).hidden]
472
449
if len(new_candidates) > 0:
473
# If there are any non-hidden formats that match, only return those to
474
# avoid listing hidden formats except when only a hidden format will
476
450
candidates = new_candidates
477
451
return ' or '.join(candidates)
480
class InfoHooks(_mod_hooks.Hooks):
481
"""Hooks for the info command."""
484
super(InfoHooks, self).__init__()
485
self.create_hook(_mod_hooks.HookPoint('repository',
486
"Invoked when displaying the statistics for a repository. "
487
"repository is called with a statistics dictionary as returned "
488
"by the repository and a file-like object to write to.", (1, 15),
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)