213
213
revision_iterator = _create_log_revision_iterator(branch,
214
214
start_revision, end_revision, direction, specific_fileid, search,
215
215
generate_merge_revisions, allow_single_merge_revision,
216
generate_delta, limited_output=limit > 0)
217
217
for revs in revision_iterator:
218
218
for (rev_id, revno, merge_depth), rev, delta in revs:
219
219
lr = LogRevision(rev, revno, merge_depth, delta,
232
232
def _create_log_revision_iterator(branch, start_revision, end_revision,
233
233
direction, specific_fileid, search, generate_merge_revisions,
234
allow_single_merge_revision, generate_delta,
235
force_incremental_matching=False):
234
allow_single_merge_revision, generate_delta, limited_output=False):
236
235
"""Create a revision iterator for log.
238
237
:param branch: The branch being logged.
248
247
:param allow_single_merge_revision: If True, logging of a single
249
248
revision off the mainline is to be allowed
250
249
:param generate_delta: Whether to generate a delta for each revision.
251
:param force_incremental_matching: if there's a file_id, use deltas
252
to match it unconditionally
250
:param limited_output: if True, the user only wants a limited result
254
252
:return: An iterator over lists of ((rev_id, revno, merge_depth), rev,
265
263
# default when no limits are given. Delta filtering should give more
266
264
# accurate results (e.g. inclusion of FILE deletions) so arguably
267
265
# it should always be used in the future.
268
use_deltas_for_matching = specific_fileid and (force_incremental_matching
269
or generate_delta or start_rev_id or end_rev_id)
266
use_deltas_for_matching = specific_fileid and (
267
generate_delta or start_rev_id or end_rev_id)
268
delayed_graph_generation = not specific_fileid and (
269
start_rev_id or end_rev_id or limited_output)
270
270
generate_merges = generate_merge_revisions or (specific_fileid and
271
271
not use_deltas_for_matching)
272
272
view_revisions = _calc_view_revisions(branch, start_rev_id, end_rev_id,
273
direction, generate_merges, allow_single_merge_revision)
273
direction, generate_merges, allow_single_merge_revision,
274
delayed_graph_generation=delayed_graph_generation)
274
275
search_deltas_for_fileids = None
275
276
if use_deltas_for_matching:
276
277
search_deltas_for_fileids = set([specific_fileid])
277
278
elif specific_fileid:
279
if not isinstance(view_revisions, list):
280
view_revisions = list(view_revisions)
278
281
view_revisions = _filter_revisions_touching_file_id(branch,
279
specific_fileid, list(view_revisions),
282
specific_fileid, view_revisions,
280
283
include_merges=generate_merge_revisions)
281
284
return make_log_rev_iterator(branch, view_revisions, generate_delta,
282
285
search, file_ids=search_deltas_for_fileids, direction=direction)
285
288
def _calc_view_revisions(branch, start_rev_id, end_rev_id, direction,
286
generate_merge_revisions, allow_single_merge_revision):
289
generate_merge_revisions, allow_single_merge_revision,
290
delayed_graph_generation=False):
287
291
"""Calculate the revisions to view.
289
293
:return: An iterator of (revision_id, dotted_revno, merge_depth) tuples OR
332
336
# so we delay doing it until a merge is detected, incrementally
333
337
# returning initial (non-merge) revisions while we can.
334
338
initial_revisions = []
336
for rev_id, revno, depth in \
337
_linear_view_revisions(branch, start_rev_id, end_rev_id):
338
if _has_merges(branch, rev_id):
342
initial_revisions.append((rev_id, revno, depth))
344
# No merged revisions found
345
if direction == 'reverse':
346
return initial_revisions
347
elif direction == 'forward':
348
return reversed(initial_revisions)
350
raise ValueError('invalid direction %r' % direction)
351
except _StartNotLinearAncestor:
352
# A merge was never detected so the lower revision limit can't
353
# be nested down somewhere
354
raise errors.BzrCommandError('Start revision not found in'
355
' history of end revision.')
339
if delayed_graph_generation:
341
for rev_id, revno, depth in \
342
_linear_view_revisions(branch, start_rev_id, end_rev_id):
343
if _has_merges(branch, rev_id):
347
initial_revisions.append((rev_id, revno, depth))
349
# No merged revisions found
350
if direction == 'reverse':
351
return initial_revisions
352
elif direction == 'forward':
353
return reversed(initial_revisions)
355
raise ValueError('invalid direction %r' % direction)
356
except _StartNotLinearAncestor:
357
# A merge was never detected so the lower revision limit can't
358
# be nested down somewhere
359
raise errors.BzrCommandError('Start revision not found in'
360
' history of end revision.')
357
362
# A log including nested merges is required. If the direction is reverse,
358
363
# we rebase the initial merge depths so that the development line is