matcher: do not prepend '.*' to pattern using ^ after flags
Since the previous commit (fixing wider issue), the code generated strange
regex. This is now fixed and tested.
--- a/mercurial/match.py Wed Nov 16 16:38:42 2022 +0100
+++ b/mercurial/match.py Wed Nov 16 15:39:10 2022 +0100
@@ -1323,7 +1323,7 @@
return res
-FLAG_RE = util.re.compile(b'^\(\?([aiLmsux]+)\)')
+FLAG_RE = util.re.compile(b'^\(\?([aiLmsux]+)\)(.*)')
def _regex(kind, pat, globsuffix):
@@ -1354,11 +1354,15 @@
return b'.*' + globre[len(b'[^/]*') :] + globsuffix
return b'(?:|.*/)' + globre + globsuffix
if kind == b'relre':
- if pat.startswith(b'^'):
- return pat
- if FLAG_RE.match(pat):
- return FLAG_RE.sub(br'(?\1:.*', pat) + b')'
- return b'.*' + pat
+ flag = None
+ m = FLAG_RE.match(pat)
+ if m:
+ flag, pat = m.groups()
+ if not pat.startswith(b'^'):
+ pat = b'.*' + pat
+ if flag is not None:
+ pat = br'(?%s:%s)' % (flag, pat)
+ return pat
if kind in (b'glob', b'rootglob'):
return _globre(pat) + globsuffix
raise error.ProgrammingError(b'not a regex pattern: %s:%s' % (kind, pat))
--- a/rust/hg-core/src/filepatterns.rs Wed Nov 16 16:38:42 2022 +0100
+++ b/rust/hg-core/src/filepatterns.rs Wed Nov 16 15:39:10 2022 +0100
@@ -205,7 +205,14 @@
&b"(?"[..],
&pattern[s + 2..e - 1],
&b":"[..],
- &b".*"[..],
+ if pattern[e] == b'^'
+ || pattern[e] == b'*'
+ || pattern[e..].starts_with(b".*")
+ {
+ &b""[..]
+ } else {
+ &b".*"[..]
+ },
&pattern[e..],
&b")"[..],
]
@@ -752,5 +759,14 @@
.unwrap(),
Some(b"(?ia:.*ba{2}r)".to_vec()),
);
+ assert_eq!(
+ build_single_regex(&IgnorePattern::new(
+ PatternSyntax::RelRegexp,
+ b"(?ia)^ba{2}r",
+ Path::new("")
+ ))
+ .unwrap(),
+ Some(b"(?ia:^ba{2}r)".to_vec()),
+ );
}
}
--- a/tests/test-hgignore.t Wed Nov 16 16:38:42 2022 +0100
+++ b/tests/test-hgignore.t Wed Nov 16 15:39:10 2022 +0100
@@ -74,6 +74,8 @@
A dir/b.o
? a.c
? syntax
+ $ hg debugignore
+ <includematcher includes='(?i:.*\\.O$)|.*.hgignore'>
regex with flag is not the first one
@@ -83,6 +85,8 @@
A dir/b.o
? a.c
? syntax
+ $ hg debugignore
+ <includematcher includes='.*.hgignore|(?i:.*\\.O$)'>
flag in a pattern should affect that pattern only
@@ -93,6 +97,8 @@
? .hgignore
? a.c
? syntax
+ $ hg debugignore
+ <includematcher includes='(?i:.*\\.O$)|.*.HGIGNORE'>
$ echo 're:.HGIGNORE' > .hgignore
$ echo 're:(?i)\.O$' >> .hgignore
@@ -101,6 +107,32 @@
? .hgignore
? a.c
? syntax
+ $ hg debugignore
+ <includematcher includes='.*.HGIGNORE|(?i:.*\\.O$)'>
+
+Check that '^' after flag is properly detected.
+
+ $ echo 're:(?i)^[^a].*\.O$' > .hgignore
+ $ echo 're:.HGIGNORE' >> .hgignore
+ $ hg status
+ A dir/b.o
+ ? .hgignore
+ ? a.c
+ ? a.o
+ ? syntax
+ $ hg debugignore
+ <includematcher includes='(?i:^[^a].*\\.O$)|.*.HGIGNORE'>
+
+ $ echo 're:.HGIGNORE' > .hgignore
+ $ echo 're:(?i)^[^a].*\.O$' >> .hgignore
+ $ hg status
+ A dir/b.o
+ ? .hgignore
+ ? a.c
+ ? a.o
+ ? syntax
+ $ hg debugignore
+ <includematcher includes='.*.HGIGNORE|(?i:^[^a].*\\.O$)'>
further testing