236
236
def calculate_view_revisions(branch, start_revision, end_revision, direction,
237
237
specific_fileid, generate_merge_revisions,
238
238
allow_single_merge_revision):
239
if (not generate_merge_revisions and start_revision is end_revision is
240
None and direction == 'reverse' and specific_fileid is None):
239
if ( not generate_merge_revisions
240
and start_revision is end_revision is None
241
and direction == 'reverse'
242
and specific_fileid is None):
241
243
return _linear_view_revisions(branch)
243
mainline_revs, rev_nos, start_rev_id, end_rev_id = \
244
_get_mainline_revs(branch, start_revision, end_revision)
245
mainline_revs, rev_nos, start_rev_id, end_rev_id = _get_mainline_revs(
246
branch, start_revision, end_revision)
245
247
if not mainline_revs:
248
if direction == 'reverse':
249
start_rev_id, end_rev_id = end_rev_id, start_rev_id
251
250
generate_single_revision = False
252
251
if ((not generate_merge_revisions)
253
252
and ((start_rev_id and (start_rev_id not in rev_nos))
260
259
generate_merge_revisions = generate_single_revision
261
260
view_revs_iter = get_view_revisions(mainline_revs, rev_nos, branch,
262
261
direction, include_merges=generate_merge_revisions)
263
if direction == 'reverse':
264
start_rev_id, end_rev_id = end_rev_id, start_rev_id
263
265
view_revisions = _filter_revision_range(list(view_revs_iter),
267
269
view_revisions = view_revisions[0:1]
268
270
if specific_fileid:
269
271
view_revisions = _filter_revisions_touching_file_id(branch,
274
275
# rebase merge_depth - unless there are no revisions or
275
276
# either the first or last revision have merge_depth = 0.
508
509
:return: The filtered view_revisions.
510
if start_rev_id or end_rev_id:
511
if start_rev_id or end_rev_id:
511
512
revision_ids = [r for r, n, d in view_revisions]
513
514
start_index = revision_ids.index(start_rev_id)
536
537
return view_revisions
539
def _filter_revisions_touching_file_id(branch, file_id, view_revisions,
540
def _filter_revisions_touching_file_id(branch, file_id, view_revisions):
541
541
r"""Return the list of revision ids which touch a given file id.
543
543
The function filters view_revisions and returns a subset.
562
562
This will also be restricted based on a subset of the mainline.
564
564
:param branch: The branch where we can get text revision information.
565
566
:param file_id: Filter out revisions that do not touch file_id.
566
568
:param view_revisions: A list of (revision_id, dotted_revno, merge_depth)
567
569
tuples. This is the list of revisions which will be filtered. It is
568
assumed that view_revisions is in merge_sort order (either forward or
570
:param direction: The direction of view_revisions. See also
571
reverse_by_depth, and get_view_revisions
570
assumed that view_revisions is in merge_sort order (i.e. newest
572
573
:return: A list of (revision_id, dotted_revno, merge_depth) tuples.
574
575
# Lookup all possible text keys to determine which ones actually modified
592
593
del text_keys, next_keys
595
if direction == 'forward':
596
# TODO: The algorithm for finding 'merges' of file changes expects
597
# 'reverse' order (the default from 'merge_sort()'). Instead of
598
# forcing this, we could just use the reverse_by_depth order.
599
view_revisions = reverse_by_depth(view_revisions)
600
596
# Track what revisions will merge the current revision, replace entries
601
597
# with 'None' when they have been added to result
602
598
current_merge_stack = [None]
666
660
revision of that depth. There may be no topological justification for this,
667
661
but it looks much nicer.
663
# Add a fake revision at start so that we can always attach sub revisions
664
merge_sorted_revisions = [(None, None, _depth)] + merge_sorted_revisions
669
665
zd_revisions = []
670
666
for val in merge_sorted_revisions:
671
667
if val[2] == _depth:
668
# Each revision at the current depth becomes a chunk grouping all
669
# higher depth revisions.
672
670
zd_revisions.append([val])
674
672
zd_revisions[-1].append(val)
675
673
for revisions in zd_revisions:
676
674
if len(revisions) > 1:
675
# We have higher depth revisions, let reverse them locally
677
676
revisions[1:] = reverse_by_depth(revisions[1:], _depth + 1)
678
677
zd_revisions.reverse()
680
679
for chunk in zd_revisions:
681
680
result.extend(chunk)
682
# Top level call, get rid of the fake revisions that have been added
683
result = [r for r in result if r[0] is not None and r[1] is not None]
861
863
return str[:max_len-3]+'...'
863
865
def date_string(self, rev):
864
return format_date(rev.timestamp, rev.timezone or 0,
866
return format_date(rev.timestamp, rev.timezone or 0,
865
867
self.show_timezone, date_fmt="%Y-%m-%d",
866
868
show_offset=False)