14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from __future__ import absolute_import
68
70
changes = new.iter_changes(old, want_unchanged, specific_files,
69
require_versioned=False, want_unversioned=want_unversioned)
71
require_versioned=False, want_unversioned=want_unversioned)
70
72
_mod_delta.report_changes(changes, show_short_reporter)
72
74
delta = new.changes_from(old, want_unchanged=want_unchanged,
73
specific_files=specific_files,
74
want_unversioned=want_unversioned)
75
specific_files=specific_files,
76
want_unversioned=want_unversioned)
75
77
# 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
delta.unversioned = [unversioned for unversioned in
80
delta.unversioned if not new.is_ignored(unversioned[0])]
79
81
show_long_callback(to_file, delta,
81
83
show_unchanged=want_unchanged,
138
141
old = revision[0].as_tree(wt.branch)
139
142
except errors.NoSuchRevision as e:
140
raise errors.CommandError(str(e))
143
raise errors.BzrCommandError(str(e))
141
144
if (len(revision) > 1) and (revision[1].spec is not None):
143
146
new = revision[1].as_tree(wt.branch)
144
147
new_is_working_tree = False
145
148
except errors.NoSuchRevision as e:
146
raise errors.CommandError(str(e))
149
raise errors.BzrCommandError(str(e))
149
with old.lock_read(), new.lock_read():
150
155
for hook in hooks['pre_status']:
151
hook(StatusHookParams(
152
old, new, to_file, versioned, show_ids, short, verbose,
153
specific_files=specific_files))
156
hook(StatusHookParams(old, new, to_file, versioned,
157
show_ids, short, verbose, specific_files=specific_files))
155
159
specific_files, nonexistents \
156
160
= _filter_nonexistent(specific_files, old, new)
157
161
want_unversioned = not versioned
159
163
# Reporter used for short outputs
160
reporter = _mod_delta._ChangeReporter(
161
output_file=to_file, unversioned_filter=new.is_ignored,
164
reporter = _mod_delta._ChangeReporter(output_file=to_file,
165
unversioned_filter=new.is_ignored, classify=classify)
163
166
report_changes(to_file, old, new, specific_files,
164
167
reporter, show_long_callback,
165
168
short=short, want_unversioned=want_unversioned,
170
173
if specific_files is not None:
171
174
# Ignored files is sorted because specific_files is already sorted
172
175
ignored_files = [specific for specific in
173
specific_files if new.is_ignored(specific)]
176
specific_files if new.is_ignored(specific)]
174
177
if len(ignored_files) > 0 and not short:
175
178
to_file.write("ignored:\n")
184
187
conflicts = new.conflicts()
185
188
if specific_files is not None:
186
conflicts = conflicts.select_conflicts(
187
new, specific_files, ignore_misses=True, recurse=True)[1]
189
conflicts = conflicts.select_conflicts(new, specific_files,
190
ignore_misses=True, recurse=True)[1]
188
191
if len(conflicts) > 0 and not short:
189
192
to_file.write("conflicts:\n")
190
193
for conflict in conflicts:
195
to_file.write("%s %s\n" % (prefix, conflict.describe()))
198
to_file.write("%s %s\n" % (prefix, unicode(conflict)))
196
199
# Show files that were requested but don't exist (and are
197
200
# not versioned). We don't involve delta in this; these
198
201
# paths are really the province of just the status
215
218
raise errors.PathsDoNotExist(nonexistents)
216
219
for hook in hooks['post_status']:
217
hook(StatusHookParams(
218
old, new, to_file, versioned, show_ids, short, verbose,
219
specific_files=specific_files))
220
hook(StatusHookParams(old, new, to_file, versioned,
221
show_ids, short, verbose, specific_files=specific_files))
222
229
def _get_sorted_revisions(tip_revision, revision_ids, parent_map):
235
242
# of any references pointing outside of this graph.
236
243
parent_graph = {}
237
244
for revision_id in revision_ids:
238
if revision_id not in parent_map: # ghost
245
if revision_id not in parent_map: # ghost
239
246
parent_graph[revision_id] = []
241
248
# Only include parents which are in this sub-graph
242
249
parent_graph[revision_id] = [p for p in parent_map[revision_id]
243
if p in revision_ids]
250
if p in revision_ids]
244
251
sorter = tsort.MergeSorter(parent_graph, tip_revision)
245
252
return sorter.iter_topo_order()
287
294
rev = branch.repository.get_revision(merge)
288
295
except errors.NoSuchRevision:
289
296
# If we are missing a revision, just print out the revision id
290
to_file.write(first_prefix + '(ghost) ' +
291
merge.decode('utf-8') + '\n')
297
to_file.write(first_prefix + '(ghost) ' + merge + '\n')
292
298
other_revisions.append(merge)
309
315
# Display the revisions brought in by this merge.
310
316
rev_id_iterator = _get_sorted_revisions(merge, merge_extra,
311
branch.repository.get_parent_map(merge_extra))
317
branch.repository.get_parent_map(merge_extra))
312
318
# Skip the first node
313
319
num, first, depth, eom = next(rev_id_iterator)
314
320
if first != merge:
315
321
raise AssertionError('Somehow we misunderstood how'
316
' iter_topo_order works %s != %s' % (first, merge))
322
' iter_topo_order works %s != %s' % (first, merge))
317
323
for num, sub_merge, depth, eom in rev_id_iterator:
318
324
rev = revisions[sub_merge]
320
to_file.write(sub_prefix + '(ghost) ' +
321
sub_merge.decode('utf-8') + '\n')
326
to_file.write(sub_prefix + '(ghost) ' + sub_merge + '\n')
323
328
show_log_message(revisions[sub_merge], sub_prefix)
342
347
s = old_tree.filter_unversioned_files(orig_paths)
343
348
s = new_tree.filter_unversioned_files(s)
344
349
nonexistent = [path for path in s if not new_tree.has_filename(path)]
345
remaining = [path for path in orig_paths if path not in nonexistent]
350
remaining = [path for path in orig_paths if not path in nonexistent]
346
351
# Sorting the 'remaining' list doesn't have much effect in
347
352
# practice, since the various status output sections will sort
348
353
# their groups individually. But for consistency of this
366
371
_mod_hooks.Hooks.__init__(self, "breezy.status", "hooks")
372
self.add_hook('post_status',
369
373
"Called with argument StatusHookParams after Bazaar has "
370
374
"displayed the status. StatusHookParams has the attributes "
371
375
"(old_tree, new_tree, to_file, versioned, show_ids, short, "
373
377
"line options specified by the user for the status command. "
374
378
"to_file is the output stream for writing.",
380
self.add_hook('pre_status',
378
381
"Called with argument StatusHookParams before Bazaar "
379
382
"displays the status. StatusHookParams has the attributes "
380
383
"(old_tree, new_tree, to_file, versioned, show_ids, short, "
399
402
def __init__(self, old_tree, new_tree, to_file, versioned, show_ids,
400
short, verbose, specific_files=None):
403
short, verbose, specific_files=None):
401
404
"""Create a group of post_status hook parameters.
403
406
:param old_tree: Start tree (basis tree) for comparison.
408
411
:param short: Use short status indicators.
409
412
:param verbose: Verbose flag.
410
413
:param specific_files: If set, a list of filenames whose status should be
411
shown. It is an error to give a filename that is not in the
412
working tree, or in the working inventory or in the basis inventory.
414
shown. It is an error to give a filename that is not in the working
415
tree, or in the working inventory or in the basis inventory.
414
417
self.old_tree = old_tree
415
418
self.new_tree = new_tree
424
427
return self.__dict__ == other.__dict__
426
429
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)
430
return "<%s(%s, %s, %s, %s, %s, %s, %s, %s)>" % (self.__class__.__name__,
431
self.old_tree, self.new_tree, self.to_file, self.versioned,
432
self.show_ids, self.short, self.verbose, self.specific_files)
433
435
def _show_shelve_summary(params):