25
27
revision as _mod_revision,
27
from . import errors as errors
28
from .trace import mutter, warning
29
from .workingtree import ShelvingUnsupported
29
import bzrlib.errors as errors
30
from bzrlib.trace import mutter, warning
32
32
# TODO: when showing single-line logs, truncate to the width of the terminal
33
33
# if known, but only if really going to the terminal (not into a file)
36
def report_changes(to_file, old, new, specific_files,
37
show_short_reporter, show_long_callback,
38
short=False, want_unchanged=False,
36
def report_changes(to_file, old, new, specific_files,
37
show_short_reporter, show_long_callback,
38
short=False, want_unchanged=False,
39
39
want_unversioned=False, show_ids=False, classify=True):
40
40
"""Display summary of changes.
42
This compares two trees with regards to a list of files, and delegates
42
This compares two trees with regards to a list of files, and delegates
43
43
the display to underlying elements.
45
45
For short output, it creates an iterator on all changes, and lets a given
68
68
changes = new.iter_changes(old, want_unchanged, specific_files,
69
require_versioned=False, want_unversioned=want_unversioned)
69
require_versioned=False, want_unversioned=want_unversioned)
70
70
_mod_delta.report_changes(changes, show_short_reporter)
72
73
delta = new.changes_from(old, want_unchanged=want_unchanged,
73
specific_files=specific_files,
74
want_unversioned=want_unversioned)
74
specific_files=specific_files,
75
want_unversioned=want_unversioned)
75
76
# filter out unknown files. We may want a tree method for
77
delta.unversioned = [change for change in delta.unversioned
78
if not new.is_ignored(change.path[1])]
79
show_long_callback(to_file, delta,
78
delta.unversioned = [unversioned for unversioned in
79
delta.unversioned if not new.is_ignored(unversioned[0])]
80
show_long_callback(to_file, delta,
81
82
show_unchanged=want_unchanged,
85
def show_tree_status(wt,
86
def show_tree_status(wt, show_unchanged=None,
86
87
specific_files=None,
121
124
:param versioned: If True, only shows versioned files.
122
125
:param classify: Add special symbols to indicate file kind.
123
:param show_long_callback: A callback: message = show_long_callback(to_file, delta,
126
:param show_long_callback: A callback: message = show_long_callback(to_file, delta,
124
127
show_ids, show_unchanged, indent, filter), only used with the long output
129
if show_unchanged is not None:
130
warn("show_tree_status with show_unchanged has been deprecated "
131
"since bzrlib 0.9", DeprecationWarning, stacklevel=2)
126
133
if to_file is None:
127
134
to_file = sys.stdout
130
138
new_is_working_tree = True
131
139
if revision is None:
132
140
if wt.last_revision() != wt.branch.last_revision():
133
warning("working tree is out of date, run 'brz update'")
141
warning("working tree is out of date, run 'bzr update'")
135
143
old = new.basis_tree()
136
144
elif len(revision) > 0:
138
146
old = revision[0].as_tree(wt.branch)
139
except errors.NoSuchRevision as e:
140
raise errors.CommandError(str(e))
147
except errors.NoSuchRevision, e:
148
raise errors.BzrCommandError(str(e))
141
149
if (len(revision) > 1) and (revision[1].spec is not None):
143
151
new = revision[1].as_tree(wt.branch)
144
152
new_is_working_tree = False
145
except errors.NoSuchRevision as e:
146
raise errors.CommandError(str(e))
153
except errors.NoSuchRevision, e:
154
raise errors.BzrCommandError(str(e))
149
with old.lock_read(), new.lock_read():
150
160
for hook in hooks['pre_status']:
151
hook(StatusHookParams(
152
old, new, to_file, versioned, show_ids, short, verbose,
153
specific_files=specific_files))
161
hook(StatusHookParams(old, new, to_file, versioned,
162
show_ids, short, verbose, specific_files=specific_files))
155
164
specific_files, nonexistents \
156
165
= _filter_nonexistent(specific_files, old, new)
157
166
want_unversioned = not versioned
159
168
# Reporter used for short outputs
160
reporter = _mod_delta._ChangeReporter(
161
output_file=to_file, unversioned_filter=new.is_ignored,
163
report_changes(to_file, old, new, specific_files,
164
reporter, show_long_callback,
165
short=short, want_unversioned=want_unversioned,
166
show_ids=show_ids, classify=classify)
169
reporter = _mod_delta._ChangeReporter(output_file=to_file,
170
unversioned_filter=new.is_ignored, classify=classify)
171
report_changes(to_file, old, new, specific_files,
172
reporter, show_long_callback,
173
short=short, want_unchanged=show_unchanged,
174
want_unversioned=want_unversioned, show_ids=show_ids,
168
177
# show the ignored files among specific files (i.e. show the files
169
# identified from input that we choose to ignore).
178
# identified from input that we choose to ignore).
170
179
if specific_files is not None:
171
180
# Ignored files is sorted because specific_files is already sorted
172
181
ignored_files = [specific for specific in
173
specific_files if new.is_ignored(specific)]
182
specific_files if new.is_ignored(specific)]
174
183
if len(ignored_files) > 0 and not short:
175
184
to_file.write("ignored:\n")
215
224
raise errors.PathsDoNotExist(nonexistents)
216
225
for hook in hooks['post_status']:
217
hook(StatusHookParams(
218
old, new, to_file, versioned, show_ids, short, verbose,
219
specific_files=specific_files))
226
hook(StatusHookParams(old, new, to_file, versioned,
227
show_ids, short, verbose, specific_files=specific_files))
222
235
def _get_sorted_revisions(tip_revision, revision_ids, parent_map):
304
316
merge_extra.discard(_mod_revision.NULL_REVISION)
306
318
# Get a handle to all of the revisions we will need
307
revisions = dict(branch.repository.iter_revisions(merge_extra))
320
revisions = dict((rev.revision_id, rev) for rev in
321
branch.repository.get_revisions(merge_extra))
322
except errors.NoSuchRevision:
323
# One of the sub nodes is a ghost, check each one
325
for revision_id in merge_extra:
327
rev = branch.repository.get_revisions([revision_id])[0]
328
except errors.NoSuchRevision:
329
revisions[revision_id] = None
331
revisions[revision_id] = rev
309
333
# Display the revisions brought in by this merge.
310
334
rev_id_iterator = _get_sorted_revisions(merge, merge_extra,
311
branch.repository.get_parent_map(merge_extra))
335
branch.repository.get_parent_map(merge_extra))
312
336
# Skip the first node
313
num, first, depth, eom = next(rev_id_iterator)
337
num, first, depth, eom = rev_id_iterator.next()
314
338
if first != merge:
315
339
raise AssertionError('Somehow we misunderstood how'
316
' iter_topo_order works %s != %s' % (first, merge))
340
' iter_topo_order works %s != %s' % (first, merge))
317
341
for num, sub_merge, depth, eom in rev_id_iterator:
318
342
rev = revisions[sub_merge]
320
to_file.write(sub_prefix + '(ghost) ' +
321
sub_merge.decode('utf-8') + '\n')
344
to_file.write(sub_prefix + '(ghost) ' + sub_merge + '\n')
323
346
show_log_message(revisions[sub_merge], sub_prefix)
424
445
return self.__dict__ == other.__dict__
426
447
def __repr__(self):
427
return "<%s(%s, %s, %s, %s, %s, %s, %s, %s)>" % (
428
self.__class__.__name__, self.old_tree, self.new_tree,
429
self.to_file, self.versioned, self.show_ids, self.short,
430
self.verbose, self.specific_files)
448
return "<%s(%s, %s, %s, %s, %s, %s, %s, %s)>" % (self.__class__.__name__,
449
self.old_tree, self.new_tree, self.to_file, self.versioned,
450
self.show_ids, self.short, self.verbose, self.specific_files)
433
453
def _show_shelve_summary(params):
442
462
get_shelf_manager = getattr(params.new_tree, 'get_shelf_manager', None)
443
463
if get_shelf_manager is None:
446
manager = get_shelf_manager()
447
except ShelvingUnsupported:
448
mutter('shelving not supported by tree, not displaying shelves.')
450
shelves = manager.active_shelves()
452
singular = '%d shelf exists. '
453
plural = '%d shelves exist. '
454
if len(shelves) == 1:
458
params.to_file.write(fmt % len(shelves))
459
params.to_file.write('See "brz shelve --list" for details.\n')
465
manager = get_shelf_manager()
466
shelves = manager.active_shelves()
468
singular = '%d shelf exists. '
469
plural = '%d shelves exist. '
470
if len(shelves) == 1:
474
params.to_file.write(fmt % len(shelves))
475
params.to_file.write('See "bzr shelve --list" for details.\n')
462
478
hooks = StatusHooks()
465
481
hooks.install_named_hook('post_status', _show_shelve_summary,