44
def _repo_rel_url(repo_url, inner_url):
45
"""Return path with common prefix of repository path removed.
47
If path is not part of the repository, the original path is returned.
48
If path is equal to the repository, the current directory marker '.' is
50
Otherwise, a relative path is returned, with trailing '/' stripped.
52
inner_url = urlutils.normalize_url(inner_url)
53
repo_url = urlutils.normalize_url(repo_url)
54
if inner_url == repo_url:
56
result = urlutils.relative_url(repo_url, inner_url)
57
if result != inner_url:
58
result = result.rstrip('/')
61
class _UrlList(object):
66
def add_url(self, label, url):
67
self.add_path(label, urlutils.unescape_for_display(url, 'ascii'))
69
def add_url(self, label, url):
70
self.add_path(label, url)
46
class LocationList(object):
48
def __init__(self, base_path):
50
self.base_path = base_path
52
def add_url(self, label, url):
53
"""Add a URL to the list, converting it to a path if possible"""
57
path = urlutils.local_path_from_url(url)
58
except errors.InvalidURL:
59
self.locs.append((label, url))
61
self.add_path(label, path)
72
63
def add_path(self, label, path):
73
self.urls.append((label, path))
64
"""Add a path, converting it to a relative path if possible"""
66
path = osutils.relpath(self.base_path, path)
67
except errors.PathNotChild:
73
path = path.rstrip('/')
74
self.locs.append((label, path))
75
def print_lines(self):
76
max_len = max(len(l) for l, u in self.urls)
77
for label, url in self.urls:
78
print " %*s: %s" % (max_len, label, url)
77
max_len = max(len(l) for l, u in self.locs)
78
return [" %*s: %s\n" % (max_len, l, u) for l, u in self.locs ]
81
81
def gather_location_info(repository, branch=None, working=None):
130
128
return [(n, locs[n]) for n in order if n in locs]
133
def _show_location_info(locs):
131
def _show_location_info(locs, outfile):
134
132
"""Show known locations for working, branch and repository."""
136
path_list = _UrlList()
133
outfile.write('Location:\n')
134
path_list = LocationList(osutils.getcwd())
137
135
for name, loc in locs:
138
136
path_list.add_url(name, loc)
139
path_list.print_lines()
142
def _show_related_info(branch):
137
outfile.writelines(path_list.get_lines())
140
def _gather_related_branches(branch):
141
locs = LocationList(osutils.getcwd())
142
locs.add_url('public branch', branch.get_public_branch())
143
locs.add_url('push branch', branch.get_push_location())
144
locs.add_url('parent branch', branch.get_parent())
145
locs.add_url('submit branch', branch.get_submit_branch())
149
def _show_related_info(branch, outfile):
143
150
"""Show parent and push location of branch."""
144
if branch.get_parent() or branch.get_push_location():
146
print 'Related branches:'
147
if branch.get_parent():
148
if branch.get_push_location():
149
print ' parent branch: %s' % branch.get_parent()
151
print ' parent branch: %s' % branch.get_parent()
152
if branch.get_push_location():
153
print ' publish to branch: %s' % branch.get_push_location()
156
def _show_format_info(control=None, repository=None, branch=None, working=None):
151
locs = _gather_related_branches(branch)
152
if len(locs.locs) > 0:
154
outfile.write('Related branches:\n')
155
outfile.writelines(locs.get_lines())
158
def _show_format_info(control=None, repository=None, branch=None,
159
working=None, outfile=None):
157
160
"""Show known formats for control, working, branch and repository."""
162
outfile.write('Format:\n')
161
print ' control: %s' % control._format.get_format_description()
164
outfile.write(' control: %s\n' %
165
control._format.get_format_description())
163
print ' working tree: %s' % working._format.get_format_description()
167
outfile.write(' working tree: %s\n' %
168
working._format.get_format_description())
165
print ' branch: %s' % branch._format.get_format_description()
170
outfile.write(' branch: %s\n' %
171
branch._format.get_format_description())
167
print ' repository: %s' % repository._format.get_format_description()
170
def _show_locking_info(repository, branch=None, working=None):
173
outfile.write(' repository: %s\n' %
174
repository._format.get_format_description())
177
def _show_locking_info(repository, branch=None, working=None, outfile=None):
171
178
"""Show locking status of working, branch and repository."""
172
179
if (repository.get_physical_lock_status() or
173
180
(branch and branch.get_physical_lock_status()) or
174
181
(working and working.get_physical_lock_status())):
183
outfile.write('Lock status:\n')
178
185
if working.get_physical_lock_status():
179
186
status = 'locked'
181
188
status = 'unlocked'
182
print ' working tree: %s' % status
189
outfile.write(' working tree: %s\n' % status)
184
191
if branch.get_physical_lock_status():
185
192
status = 'locked'
187
194
status = 'unlocked'
188
print ' branch: %s' % status
195
outfile.write(' branch: %s\n' % status)
190
197
if repository.get_physical_lock_status():
191
198
status = 'locked'
193
200
status = 'unlocked'
194
print ' repository: %s' % status
197
def _show_missing_revisions_branch(branch):
201
outfile.write(' repository: %s\n' % status)
204
def _show_missing_revisions_branch(branch, outfile):
198
205
"""Show missing master revisions in branch."""
199
206
# Try with inaccessible branch ?
200
207
master = branch.get_master_branch()
202
209
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):
212
outfile.write(('Branch is out of date: missing %d '
213
'revision%s.\n') % (len(remote_extra),
214
plural(len(remote_extra))))
217
def _show_missing_revisions_working(working, outfile):
210
218
"""Show missing revisions in working tree."""
211
219
branch = working.branch
212
220
basis = working.basis_tree()
220
228
if branch_revno and tree_last_id != branch_last_revision:
221
229
tree_last_revno = branch.revision_id_to_revno(tree_last_id)
222
230
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):
232
outfile.write(('Working tree is out of date: missing %d '
233
'revision%s.\n') % (missing_count, plural(missing_count)))
236
def _show_working_stats(working, outfile):
229
237
"""Show statistics about a working tree."""
230
238
basis = working.basis_tree()
231
239
work_inv = working.inventory
232
240
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)
243
outfile.write('In the working tree:\n')
244
outfile.write(' %8s unchanged\n' % len(delta.unchanged))
245
outfile.write(' %8d modified\n' % len(delta.modified))
246
outfile.write(' %8d added\n' % len(delta.added))
247
outfile.write(' %8d removed\n' % len(delta.removed))
248
outfile.write(' %8d renamed\n' % len(delta.renamed))
242
250
ignore_cnt = unknown_cnt = 0
243
251
for path in working.extras():
248
print ' %8d unknown' % unknown_cnt
249
print ' %8d ignored' % ignore_cnt
256
outfile.write(' %8d unknown\n' % unknown_cnt)
257
outfile.write(' %8d ignored\n' % ignore_cnt)
252
260
for file_id in work_inv:
253
261
if (work_inv.get_file_kind(file_id) == 'directory' and
254
262
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):
264
outfile.write(' %8d versioned %s\n' % (dir_cnt,
265
plural(dir_cnt, 'subdirectory', 'subdirectories')))
268
def _show_branch_stats(branch, verbose, outfile):
262
269
"""Show statistics about a branch."""
263
270
revno, head = branch.last_revision_info()
265
print 'Branch history:'
266
print ' %8d revision%s' % (revno, plural(revno))
272
outfile.write('Branch history:\n')
273
outfile.write(' %8d revision%s\n' % (revno, plural(revno)))
267
274
stats = branch.repository.gather_stats(head, committers=verbose)
269
276
committers = stats['committers']
270
print ' %8d committer%s' % (committers, plural(committers))
277
outfile.write(' %8d committer%s\n' % (committers,
272
280
timestamp, timezone = stats['firstrev']
273
281
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,
282
outfile.write(' %8d day%s old\n' % (age, plural(age)))
283
outfile.write(' first revision: %s\n' %
284
osutils.format_date(timestamp, timezone))
277
285
timestamp, timezone = stats['latestrev']
278
print ' latest revision: %s' % osutils.format_date(timestamp,
286
outfile.write(' latest revision: %s\n' %
287
osutils.format_date(timestamp, timezone))
283
def _show_repository_info(repository):
291
def _show_repository_info(repository, outfile):
284
292
"""Show settings of a repository."""
285
293
if repository.make_working_trees():
287
print 'Create working tree for new branches inside the repository.'
290
def _show_repository_stats(stats):
295
outfile.write('Create working tree for new branches inside '
299
def _show_repository_stats(stats, outfile):
291
300
"""Show statistics about a repository."""
292
301
if 'revisions' in stats or 'size' in stats:
303
outfile.write('Repository:\n')
295
304
if 'revisions' in stats:
296
305
revisions = stats['revisions']
297
print ' %8d revision%s' % (revisions, plural(revisions))
306
outfile.write(' %8d revision%s\n' % (revisions, plural(revisions)))
298
307
if 'size' in stats:
299
print ' %8d KiB' % (stats['size']/1024)
301
def show_bzrdir_info(a_bzrdir, verbose=False):
308
outfile.write(' %8d KiB\n' % (stats['size']/1024))
311
def show_bzrdir_info(a_bzrdir, verbose=False, outfile=None):
302
312
"""Output to stdout the 'info' for a_bzrdir."""
304
316
tree = a_bzrdir.open_workingtree(
305
317
recommend_upgrade=False)
328
340
lockable.lock_read()
330
show_component_info(a_bzrdir, repository, branch, tree, verbose)
342
show_component_info(a_bzrdir, repository, branch, tree, verbose,
332
345
lockable.unlock()
335
348
def show_component_info(control, repository, branch=None, working=None,
349
verbose=1, outfile=None):
337
350
"""Write info about all bzrdir components to stdout"""
338
353
if verbose is False:
340
355
if verbose is True:
342
357
layout = describe_layout(repository, branch, working)
343
358
format = describe_format(control, repository, branch, working)
344
print "%s (format: %s)" % (layout, format)
345
_show_location_info(gather_location_info(repository, branch, working))
359
outfile.write("%s (format: %s)\n" % (layout, format))
360
_show_location_info(gather_location_info(repository, branch, working),
362
if branch is not None:
363
_show_related_info(branch, outfile)
348
if branch is not None:
349
_show_related_info(branch)
350
_show_format_info(control, repository, branch, working)
351
_show_locking_info(repository, branch, working)
352
if branch is not None:
353
_show_missing_revisions_branch(branch)
366
_show_format_info(control, repository, branch, working, outfile)
367
_show_locking_info(repository, branch, working, outfile)
368
if branch is not None:
369
_show_missing_revisions_branch(branch, outfile)
354
370
if working is not None:
355
_show_missing_revisions_working(working)
356
_show_working_stats(working)
371
_show_missing_revisions_working(working, outfile)
372
_show_working_stats(working, outfile)
357
373
elif branch is not None:
358
_show_missing_revisions_branch(branch)
374
_show_missing_revisions_branch(branch, outfile)
359
375
if branch is not None:
360
stats = _show_branch_stats(branch, verbose==2)
376
stats = _show_branch_stats(branch, verbose==2, outfile)
362
378
stats = repository.gather_stats()
363
379
if branch is None and working is None:
364
_show_repository_info(repository)
365
_show_repository_stats(stats)
380
_show_repository_info(repository, outfile)
381
_show_repository_stats(stats, outfile)
368
384
def describe_layout(repository=None, branch=None, tree=None):
449
465
if len(new_candidates) > 0:
450
466
candidates = new_candidates
451
467
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)