231
235
message_search=None, levels=1, generate_tags=True,
233
237
diff_type=None, _match_using_deltas=True,
234
exclude_common_ancestry=False,
238
exclude_common_ancestry=False, match=None,
237
241
"""Convenience function for making a logging request dictionary.
282
286
range operator or as a graph difference.
284
288
:param signature: show digital signature information
290
:param match: Dictionary of list of search strings to use when filtering
291
revisions. Keys can be 'message', 'author', 'committer', 'bugs' or
292
the empty string to match any of the preceding properties.
296
# Take care of old style message_search parameter
299
if 'message' in match:
300
match['message'].append(message_search)
302
match['message'] = [message_search]
304
match={ 'message': [message_search] }
287
307
'direction': direction,
288
308
'specific_fileids': specific_fileids,
289
309
'start_revision': start_revision,
290
310
'end_revision': end_revision,
292
'message_search': message_search,
293
312
'levels': levels,
294
313
'generate_tags': generate_tags,
295
314
'delta_type': delta_type,
296
315
'diff_type': diff_type,
297
316
'exclude_common_ancestry': exclude_common_ancestry,
298
317
'signature': signature,
299
319
# Add 'private' attributes for features that may be deprecated
300
320
'_match_using_deltas': _match_using_deltas,
508
528
# Apply the other filters
509
529
return make_log_rev_iterator(self.branch, view_revisions,
510
rqst.get('delta_type'), rqst.get('message_search'),
530
rqst.get('delta_type'), rqst.get('match'),
511
531
file_ids=rqst.get('specific_fileids'),
512
532
direction=rqst.get('direction'))
526
546
rqst.get('specific_fileids')[0], view_revisions,
527
547
include_merges=rqst.get('levels') != 1)
528
548
return make_log_rev_iterator(self.branch, view_revisions,
529
rqst.get('delta_type'), rqst.get('message_search'))
549
rqst.get('delta_type'), rqst.get('match'))
532
552
def _calc_view_revisions(branch, start_rev_id, end_rev_id, direction,
851
871
return log_rev_iterator
854
def _make_search_filter(branch, generate_delta, search, log_rev_iterator):
874
def _make_search_filter(branch, generate_delta, match, log_rev_iterator):
855
875
"""Create a filtered iterator of log_rev_iterator matching on a regex.
857
877
:param branch: The branch being logged.
858
878
:param generate_delta: Whether to generate a delta for each revision.
859
:param search: A user text search string.
879
:param match: A dictionary with properties as keys and lists of strings
880
as values. To match, a revision may match any of the supplied strings
881
within a single property but must match at least one string for each
860
883
:param log_rev_iterator: An input iterator containing all revisions that
861
884
could be displayed, in lists.
862
885
:return: An iterator over lists of ((rev_id, revno, merge_depth), rev,
866
889
return log_rev_iterator
867
searchRE = lazy_regex.lazy_compile(search, re.IGNORECASE)
868
return _filter_message_re(searchRE, log_rev_iterator)
871
def _filter_message_re(searchRE, log_rev_iterator):
890
searchRE = [(k, [re.compile(x, re.IGNORECASE) for x in v])
891
for (k,v) in match.iteritems()]
892
return _filter_re(searchRE, log_rev_iterator)
895
def _filter_re(searchRE, log_rev_iterator):
872
896
for revs in log_rev_iterator:
874
for (rev_id, revno, merge_depth), rev, delta in revs:
875
if searchRE.search(rev.message):
876
new_revs.append(((rev_id, revno, merge_depth), rev, delta))
897
new_revs = [rev for rev in revs if _match_filter(searchRE, rev[1])]
901
def _match_filter(searchRE, rev):
903
'message': (rev.message,),
904
'committer': (rev.committer,),
905
'author': (rev.get_apparent_authors()),
906
'bugs': list(rev.iter_bugs())
908
strings[''] = [item for inner_list in strings.itervalues()
909
for item in inner_list]
911
for (k,v) in searchRE:
912
if k in strings and not _match_any_filter(strings[k], v):
916
def _match_any_filter(strings, res):
917
return any([filter(None, map(re.search, strings)) for re in res])
880
919
def _make_delta_filter(branch, generate_delta, search, log_rev_iterator,
881
920
fileids=None, direction='reverse'):