[PATCH 8 of 8] ignore: allow regex sub-ignores via a config
Durham Goode
durham at fb.com
Wed May 13 10:13:22 CDT 2015
# HG changeset patch
# User Durham Goode <durham at fb.com>
# Date 1431469591 25200
# Tue May 12 15:26:31 2015 -0700
# Node ID 1c775dc497a533542a23382f68ce0c3710601f7a
# Parent 42bafc92b436181ba5d6568967577a214198648d
ignore: allow regex sub-ignores via a config
Normally we don't allow sub-ignores to have regex rules in them, since we can't
reliably build the correct regular expression to represent the prefixed rule.
Let's add a config option that allows a user to opt-in to regular expresion
sub-ignores if they're certain their rules can be composed in the correct
manner.
The alternative to this strategy is to redo the ignore matcher builder to be
a tree of matchers then manually trim the prefix and apply the sub-ignore
matcher. This could be expensive for repos with large hgignores in python, so I
choose to go with this limited-but-opt-in-able strategy for now.
diff --git a/mercurial/ignore.py b/mercurial/ignore.py
--- a/mercurial/ignore.py
+++ b/mercurial/ignore.py
@@ -77,9 +77,17 @@ def ignorepats(ui, root, filepath):
# The ignore file is inside the repo, so make its patterns
# relative to its location.
if linesyntax == 'relre:':
- message = _('cannot use sub-ignore files that use regular '
- 'expressions')
- raise util.Abort(message)
+ if ui.configbool('ui', 'allowregexsubignores'):
+ if line[0] == '^':
+ line = '^%s\/(?:%s)' % (re.escape(subdir), line[1:])
+ else:
+ line = '^%s\/.*(?:%s)' % (re.escape(subdir), line)
+ else:
+ message = _('cannot use sub-ignore files that use regular '
+ 'expressions')
+ hint = _('set ui.allowregexsubignores=True if you know '
+ 'your regexs can be wrapped as "^subdir\/(?:XXX)"')
+ raise util.Abort(message, hint=hint)
elif linesyntax == 'relglob:':
line = '%s/*%s' % (subdir, line)
patterns.append(linesyntax + line)
diff --git a/tests/test-hgignore.t b/tests/test-hgignore.t
--- a/tests/test-hgignore.t
+++ b/tests/test-hgignore.t
@@ -189,12 +189,20 @@ Check including sub-ignores with regexs
$ echo "regexp:f.le1" > dir1/.hgignore
$ hg debugignore
abort: cannot use sub-ignore files that use regular expressions
+ (set ui.allowregexsubignores=True if you know your regexs can be wrapped as "^subdir\/(?:XXX)")
[255]
- $ echo "" > dir1/.hgignore
+ $ cat >> .hg/hgrc <<EOF
+ > [ui]
+ > allowregexsubignores=True
+ > EOF
$ hg debugignore
- (?:(?:|.*/)dir2\/[^/]*file[^/]*2(?:/|$))
+ (?:^dir1\/.*(?:f.le1)|(?:|.*/)dir2\/[^/]*file[^/]*2(?:/|$))
+
+ $ hg status | grep -v hgignore
+ ? dir1/file2
+ ? dir2/file1
Check multiple levels of sub-ignores
@@ -204,11 +212,9 @@ Check multiple levels of sub-ignores
$ echo "glob:fil*3" >> dir1/subdir/.hgignore
$ hg debugignore
- (?:(?:|.*/)dir1\/subdir\/[^/]*fil[^/]*3(?:/|$)|(?:|.*/)dir2\/[^/]*file[^/]*2(?:/|$))
+ (?:^dir1\/.*(?:f.le1)|(?:|.*/)dir1\/subdir\/[^/]*fil[^/]*3(?:/|$)|(?:|.*/)dir2\/[^/]*file[^/]*2(?:/|$))
$ hg status | grep -v hgignore
- ? dir1/file1
? dir1/file2
- ? dir1/subdir/subfile1
? dir1/subdir/subfile4
? dir2/file1
More information about the Mercurial-devel
mailing list