35
33
# if known, but only if really going to the terminal (not into a file)
36
@deprecated_function(zero_eight)
37
def show_status(branch, show_unchanged=None,
43
"""Display summary of changes.
45
Please use show_tree_status instead.
47
By default this compares the working tree to a previous revision.
48
If the revision argument is given, summarizes changes between the
49
working tree and another, or between two revisions.
51
The result is written out as Unicode and to_file should be able
55
If set, includes unchanged files.
58
If set, only show the status of files in this list.
61
If set, includes each file's id.
64
If set, write to this file (default stdout.)
67
If set, write pending merges.
70
If None the compare latest revision with working tree
71
If one revision show compared it with working tree.
72
If two revisions show status between first and second.
74
show_tree_status(branch.bzrdir.open_workingtree(), show_unchanged,
75
specific_files, show_ids, to_file, show_pending, revision)
38
78
def show_tree_status(wt, show_unchanged=None,
39
79
specific_files=None,
63
103
:param show_ids: If set, includes each file's id.
64
104
:param to_file: If set, write to this file (default stdout.)
65
105
:param show_pending: If set, write pending merges.
66
:param revision: If None, compare latest revision with working tree
67
If not None, it must be a RevisionSpec list.
68
If one revision, compare with working tree.
69
If two revisions, show status between first and second.
106
:param revision: If None the compare latest revision with working tree
107
If not None it must be a RevisionSpec list.
108
If one revision show compared it with working tree.
109
If two revisions show status between first and second.
70
110
:param short: If True, gives short SVN-style status lines.
71
111
:param versioned: If True, only shows versioned files.
73
113
if show_unchanged is not None:
74
warn("show_tree_status with show_unchanged has been deprecated "
114
warn("show_status_trees with show_unchanged has been deprecated "
75
115
"since bzrlib 0.9", DeprecationWarning, stacklevel=2)
77
117
if to_file is None:
123
163
show_ids=show_ids,
124
164
show_unchanged=show_unchanged,
125
165
short_status=False)
126
# show the new conflicts only for now. XXX: get them from the
128
conflicts = new.conflicts()
129
if specific_files is not None:
130
conflicts = conflicts.select_conflicts(new, specific_files,
131
ignore_misses=True, recurse=True)[1]
132
if len(conflicts) > 0 and not short:
133
to_file.write("conflicts:\n")
134
for conflict in conflicts:
166
conflict_title = False
167
# show the new conflicts only for now. XXX: get them from the delta.
168
for conflict in new.conflicts():
169
if not short and conflict_title is False:
170
print >> to_file, "conflicts:"
171
conflict_title = True
139
to_file.write("%s %s\n" % (prefix, conflict))
140
if (new_is_working_tree and show_pending
141
and specific_files is None):
176
print >> to_file, "%s %s" % (prefix, conflict)
177
if new_is_working_tree and show_pending:
142
178
show_pending_merges(new, to_file, short)
150
def _get_sorted_revisions(tip_revision, revision_ids, parent_map):
151
"""Get an iterator which will return the revisions in merge sorted order.
153
This will build up a list of all nodes, such that only nodes in the list
154
are referenced. It then uses MergeSorter to return them in 'merge-sorted'
157
:param revision_ids: A set of revision_ids
158
:param parent_map: The parent information for each node. Revisions which
159
are considered ghosts should not be present in the map.
160
:return: iterator from MergeSorter.iter_topo_order()
162
# MergeSorter requires that all nodes be present in the graph, so get rid
163
# of any references pointing outside of this graph.
165
for revision_id in revision_ids:
166
if revision_id not in parent_map: # ghost
167
parent_graph[revision_id] = []
169
# Only include parents which are in this sub-graph
170
parent_graph[revision_id] = [p for p in parent_map[revision_id]
171
if p in revision_ids]
172
sorter = tsort.MergeSorter(parent_graph, tip_revision)
173
return sorter.iter_topo_order()
176
185
def show_pending_merges(new, to_file, short=False):
177
186
"""Write out a display of pending merges in a working tree."""
178
187
parents = new.get_parent_ids()
179
188
if len(parents) < 2:
182
# we need one extra space for terminals that wrap on last char
183
term_width = osutils.terminal_width() - 1
191
190
pending = parents[1:]
192
191
branch = new.branch
193
192
last_revision = parents[0]
195
to_file.write('pending merges:\n')
196
graph = branch.repository.get_graph()
197
other_revisions = [last_revision]
198
log_formatter = log.LineLogFormatter(to_file)
194
print >>to_file, 'pending merges:'
195
if last_revision is not None:
197
ignore = set(branch.repository.get_ancestry(last_revision))
198
except errors.NoSuchRevision:
199
# the last revision is a ghost : assume everything is new
201
ignore = set([None, last_revision])
204
# TODO: this could be improved using merge_sorted - we'd get the same
205
# output rather than one level of indent.
199
206
for merge in pending:
201
rev = branch.repository.get_revisions([merge])[0]
202
except errors.NoSuchRevision:
203
# If we are missing a revision, just print out the revision id
204
to_file.write(first_prefix + '(ghost) ' + merge + '\n')
205
other_revisions.append(merge)
208
# Log the merge, as it gets a slightly different formatting
209
log_message = log_formatter.log_string(None, rev,
210
term_width - len(first_prefix))
211
to_file.write(first_prefix + log_message + '\n')
212
# Find all of the revisions in the merge source, which are not in the
213
# last committed revision.
214
merge_extra = graph.find_unique_ancestors(merge, other_revisions)
215
other_revisions.append(merge)
216
merge_extra.discard(_mod_revision.NULL_REVISION)
218
# Get a handle to all of the revisions we will need
220
revisions = dict((rev.revision_id, rev) for rev in
221
branch.repository.get_revisions(merge_extra))
222
except errors.NoSuchRevision:
223
# One of the sub nodes is a ghost, check each one
225
for revision_id in merge_extra:
227
rev = branch.repository.get_revisions([revision_id])[0]
228
except errors.NoSuchRevision:
229
revisions[revision_id] = None
209
from bzrlib.osutils import terminal_width
210
width = terminal_width()
211
m_revision = branch.repository.get_revision(merge)
216
print >> to_file, prefix, line_log(m_revision, width - 4)
217
inner_merges = branch.repository.get_ancestry(merge)
218
assert inner_merges[0] is None
220
inner_merges.reverse()
221
for mmerge in inner_merges:
224
mm_revision = branch.repository.get_revision(mmerge)
231
revisions[revision_id] = rev
233
# Display the revisions brought in by this merge.
234
rev_id_iterator = _get_sorted_revisions(merge, merge_extra,
235
branch.repository.get_parent_map(merge_extra))
236
# Skip the first node
237
num, first, depth, eom = rev_id_iterator.next()
239
raise AssertionError('Somehow we misunderstood how'
240
' iter_topo_order works %s != %s' % (first, merge))
241
for num, sub_merge, depth, eom in rev_id_iterator:
242
rev = revisions[sub_merge]
244
to_file.write(sub_prefix + '(ghost) ' + sub_merge + '\n')
246
log_message = log_formatter.log_string(None,
247
revisions[sub_merge],
248
term_width - len(sub_prefix))
249
to_file.write(sub_prefix + log_message + '\n')
229
print >> to_file, prefix, line_log(mm_revision, width - 5)
231
except errors.NoSuchRevision:
236
print >> to_file, prefix, merge