# HG changeset patch # User Matt Harbison <matt_harbi...@yahoo.com> # Date 1483842392 18000 # Sat Jan 07 21:26:32 2017 -0500 # Node ID 7347f75339503a8266285ac12412ac5f104d4df0 # Parent 4ab19763d71c2bb9a239dff523b18ed860e34563 revset: add regular expression support to 'desc()'
The legacy behavior of doing a case insensitive match for literals is preserved for BC. This includes with the new 'literal:' prefix for user simplicity. There are two other revsets that do case insensitive matches- 'user()' (and its alias 'author()'), and 'keyword()'. The 'keyword()' predicate only supports literals, so its behavior isn't interesting right now. The 'user()' predicate is documented to support regex, but ends up lowercasing both the needle and the haystack, effectively making it a case insensitive regex. That surprised me, since it's the only instance of that behavior. I'm not sure if this should conform to that because we are stuck with BC, or if that should be considered a bug and changed. If we can't change it, that probably precludes adding an insensitive regex matcher [1]. [1] https://www.mercurial-scm.org/pipermail/mercurial-devel/2017-January/092070.html diff --git a/mercurial/revset.py b/mercurial/revset.py --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -813,16 +813,25 @@ @predicate('desc(string)', safe=True) def desc(repo, subset, x): - """Search commit message for string. The match is case-insensitive. + """Search commit message for string. The match for a literal is + case-insensitive. + + If `string` starts with `re:`, the remainder of the string is treated as + a regular expression. To match a substring that actually starts with `re:`, + use the prefix `literal:`. """ # i18n: "desc" is a keyword - ds = encoding.lower(getstring(x, _("desc requires a string"))) - - def matches(x): - c = repo[x] - return ds in encoding.lower(c.description()) - - return subset.filter(matches, condrepr=('<desc %r>', ds)) + ds = getstring(x, _("desc requires a string")) + + kind, pattern, matcher = util.stringmatcher(ds) + + if kind == 'literal': + # Legacy icase substring behavior for literal patterns. + ds = encoding.lower(pattern) + matcher = lambda s: ds in encoding.lower(s) + + return subset.filter(lambda x: matcher(repo[x].description()), + condrepr=('<desc %r>', ds)) def _descendants(repo, subset, x, followfirst=False): roots = getset(repo, fullreposet(repo), x) diff --git a/tests/test-revset.t b/tests/test-revset.t --- a/tests/test-revset.t +++ b/tests/test-revset.t @@ -901,6 +901,10 @@ 5 $ log 'desc(B)' 5 + $ log 'desc("re:[a-z]")' + 5 + 6 + 9 $ log 'descendants(2 or 3)' 2 3 _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel