206
192
cut_revs = which_revs[(start_revision-1):(end_revision)]
196
# convert the revision history to a dictionary:
197
rev_nos = dict((k, v) for v, k in cut_revs)
209
199
# override the mainline to look like the revision history.
210
200
mainline_revs = [revision_id for index, revision_id in cut_revs]
211
201
if cut_revs[0][0] == 1:
212
202
mainline_revs.insert(0, None)
214
204
mainline_revs.insert(0, which_revs[start_revision-2][1])
216
merge_sorted_revisions = merge_sort(
217
branch.repository.get_revision_graph(mainline_revs[-1]),
221
if direction == 'reverse':
223
elif direction == 'forward':
224
# forward means oldest first.
225
merge_sorted_revisions.reverse()
205
if getattr(lf, 'show_merge', None) is not None:
206
include_merges = True
227
raise ValueError('invalid direction %r' % direction)
229
revision_history = branch.revision_history()
231
# convert the revision history to a dictionary:
233
for index, rev_id in cut_revs:
234
rev_nos[rev_id] = index
208
include_merges = False
209
view_revisions = list(get_view_revisions(mainline_revs, rev_nos, branch,
210
direction, include_merges=include_merges))
236
212
def iter_revisions():
237
revision_ids = [r for s, r, m, e in merge_sorted_revisions]
213
# r = revision, n = revno, d = merge depth
214
revision_ids = [r for r, n, d in view_revisions]
215
zeros = set(r for r, n, d in view_revisions if d == 0)
217
repository = branch.repository
239
218
while revision_ids:
240
revisions = branch.repository.get_revisions(revision_ids[:num])
220
revisions = repository.get_revisions(revision_ids[:num])
221
if verbose or specific_fileid:
222
delta_revisions = [r for r in revisions if
223
r.revision_id in zeros]
224
deltas = repository.get_deltas_for_revisions(delta_revisions)
225
cur_deltas = dict(izip((r.revision_id for r in
226
delta_revisions), deltas))
241
227
for revision in revisions:
228
# The delta value will be None unless
229
# 1. verbose or specific_fileid is specified, and
230
# 2. the revision is a mainline revision
231
yield revision, cur_deltas.get(revision.revision_id)
243
232
revision_ids = revision_ids[num:]
244
233
num = int(num * 1.5)
246
revisions = branch.repository.get_revisions()
247
for revision in revisions:
249
235
# now we just print all the revisions
250
for ((sequence, rev_id, merge_depth, end_of_merge), rev) in \
251
izip(merge_sorted_revisions, iter_revisions()):
236
for ((rev_id, revno, merge_depth), (rev, delta)) in \
237
izip(view_revisions, iter_revisions()):
254
240
if not searchRE.search(rev.message):
267
251
# although we calculated it, throw it away without display
270
lf.show(rev_nos[rev_id], rev, delta)
271
elif hasattr(lf, 'show_merge'):
254
lf.show(revno, rev, delta)
272
256
lf.show_merge(rev, merge_depth)
275
def deltas_for_log_dummy(branch, which_revs):
276
"""Return all the revisions without intermediate deltas.
278
Useful for log commands that won't need the delta information.
281
for revno, revision_id in which_revs:
282
yield revno, branch.get_revision(revision_id), None
285
def deltas_for_log_reverse(branch, which_revs):
286
"""Compute deltas for display in latest-to-earliest order.
292
Sequence of (revno, revision_id) for the subset of history to examine
295
Sequence of (revno, rev, delta)
297
The delta is from the given revision to the next one in the
298
sequence, which makes sense if the log is being displayed from
301
last_revno = last_revision_id = last_tree = None
302
for revno, revision_id in which_revs:
303
this_tree = branch.revision_tree(revision_id)
304
this_revision = branch.get_revision(revision_id)
307
yield last_revno, last_revision, compare_trees(this_tree, last_tree, False)
309
this_tree = EmptyTree(branch.get_root_id())
312
last_revision = this_revision
313
last_tree = this_tree
317
this_tree = EmptyTree(branch.get_root_id())
259
def get_view_revisions(mainline_revs, rev_nos, branch, direction,
260
include_merges=True):
261
"""Produce an iterator of revisions to show
262
:return: an iterator of (revision_id, revno, merge_depth)
263
(if there is no revno for a revision, None is supplied)
265
if include_merges is False:
266
revision_ids = mainline_revs[1:]
267
if direction == 'reverse':
268
revision_ids.reverse()
269
for revision_id in revision_ids:
270
yield revision_id, rev_nos[revision_id], 0
272
merge_sorted_revisions = merge_sort(
273
branch.repository.get_revision_graph(mainline_revs[-1]),
277
if direction == 'forward':
278
# forward means oldest first.
279
merge_sorted_revisions = reverse_by_depth(merge_sorted_revisions)
280
elif direction != 'reverse':
281
raise ValueError('invalid direction %r' % direction)
283
revision_history = branch.revision_history()
285
for sequence, rev_id, merge_depth, end_of_merge in merge_sorted_revisions:
286
yield rev_id, rev_nos.get(rev_id), merge_depth
289
def reverse_by_depth(merge_sorted_revisions, _depth=0):
290
"""Reverse revisions by depth.
292
Revisions with a different depth are sorted as a group with the previous
293
revision of that depth. There may be no topological justification for this,
294
but it looks much nicer.
297
for val in merge_sorted_revisions:
299
zd_revisions.append([val])
319
this_revno = last_revno - 1
320
this_revision_id = branch.revision_history()[this_revno]
321
this_tree = branch.revision_tree(this_revision_id)
322
yield last_revno, last_revision, compare_trees(this_tree, last_tree, False)
325
def deltas_for_log_forward(branch, which_revs):
326
"""Compute deltas for display in forward log.
328
Given a sequence of (revno, revision_id) pairs, return
331
The delta is from the given revision to the next one in the
332
sequence, which makes sense if the log is being displayed from
335
last_revno = last_revision_id = last_tree = None
336
prev_tree = EmptyTree(branch.get_root_id())
338
for revno, revision_id in which_revs:
339
this_tree = branch.revision_tree(revision_id)
340
this_revision = branch.get_revision(revision_id)
344
last_tree = EmptyTree(branch.get_root_id())
346
last_revno = revno - 1
347
last_revision_id = branch.revision_history()[last_revno]
348
last_tree = branch.revision_tree(last_revision_id)
350
yield revno, this_revision, compare_trees(last_tree, this_tree, False)
353
last_revision = this_revision
354
last_tree = this_tree
301
assert val[2] > _depth
302
zd_revisions[-1].append(val)
303
for revisions in zd_revisions:
304
if len(revisions) > 1:
305
revisions[1:] = reverse_by_depth(revisions[1:], _depth + 1)
306
zd_revisions.reverse()
308
for chunk in zd_revisions:
357
313
class LogFormatter(object):