60
63
:param show_ids: If set, includes each file's id.
61
64
:param to_file: If set, write to this file (default stdout.)
62
65
:param show_pending: If set, write pending merges.
63
:param revision: If None the compare latest revision with working tree
64
If not None it must be a RevisionSpec list.
65
If one revision show compared it with working tree.
66
If two revisions show status between first and second.
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.
67
70
:param short: If True, gives short SVN-style status lines.
68
71
:param versioned: If True, only shows versioned files.
70
73
if show_unchanged is not None:
71
warn("show_status_trees with show_unchanged has been deprecated "
74
warn("show_tree_status with show_unchanged has been deprecated "
72
75
"since bzrlib 0.9", DeprecationWarning, stacklevel=2)
74
77
if to_file is None:
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()
145
176
def show_pending_merges(new, to_file, short=False):
146
177
"""Write out a display of pending merges in a working tree."""
147
178
parents = new.get_parent_ids()
148
179
if len(parents) < 2:
182
# we need one extra space for terminals that wrap on last char
183
term_width = osutils.terminal_width() - 1
150
191
pending = parents[1:]
151
192
branch = new.branch
152
193
last_revision = parents[0]
154
195
to_file.write('pending merges:\n')
155
if last_revision is not None:
157
ignore = set(branch.repository.get_ancestry(last_revision,
159
except errors.NoSuchRevision:
160
# the last revision is a ghost : assume everything is new
162
ignore = set([None, last_revision])
165
# TODO: this could be improved using merge_sorted - we'd get the same
166
# output rather than one level of indent.
196
graph = branch.repository.get_graph()
197
other_revisions = [last_revision]
198
log_formatter = log.LineLogFormatter(to_file)
167
199
for merge in pending:
170
from bzrlib.osutils import terminal_width
171
width = terminal_width() - 1 # we need one extra space to avoid
173
m_revision = branch.repository.get_revision(merge)
178
to_file.write(prefix)
179
to_file.write(line_log(m_revision, width - len(prefix)))
181
inner_merges = branch.repository.get_ancestry(merge)
182
assert inner_merges[0] is None
184
inner_merges.reverse()
185
for mmerge in inner_merges:
188
mm_revision = branch.repository.get_revision(mmerge)
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
193
to_file.write(prefix)
194
to_file.write(line_log(mm_revision, width - len(prefix)))
197
except errors.NoSuchRevision:
202
to_file.write(prefix + ' ' + merge)
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')