# HG changeset patch # User Durham Goode # Date 2015-05-16 22:56:52 # Node ID 4040e06e9b997e2c67611ef40405d8d166bbdd6f # Parent 08703b10c3ae48a42a31972ff90211ff6997bce4 match: add 'include:' syntax This allows the matcher to understand 'include:path/to/file' style rules. The files support the standard hgignore syntax and any rules read from the file are included in the matcher without regard to the files location in the repository (i.e. if the included file is in somedir/otherdir, all of it's rules will still apply to the entire repository). diff --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -75,6 +75,7 @@ class match(object): 'relpath:' - a path relative to cwd 'relre:' - a regexp that needn't match the start of a name 'set:' - a fileset expression + 'include:' - a file of patterns to read and include '' - a pattern of the specified default type """ @@ -228,6 +229,19 @@ class match(object): auditor): kindpats.append((k, p, pat)) continue + elif kind == 'include': + try: + includepats = readpatternfile(pat, self._warn) + for k, p, source in self._normalize(includepats, default, + root, cwd, auditor): + kindpats.append((k, p, source or pat)) + except util.Abort, inst: + raise util.Abort('%s: %s' % (pat, inst[0])) + except IOError, inst: + if self._warn: + self._warn(_("skipping unreadable pattern file " + "'%s': %s\n") % (pat, inst.strerror)) + continue # else: re or relre - which cannot be normalized kindpats.append((kind, pat, '')) return kindpats @@ -335,7 +349,7 @@ def _patsplit(pattern, default): if ':' in pattern: kind, pat = pattern.split(':', 1) if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre', - 'listfile', 'listfile0', 'set'): + 'listfile', 'listfile0', 'set', 'include'): return kind, pat return default, pattern @@ -515,7 +529,8 @@ def readpatternfile(filepath, warn): '''parse a pattern file, returning a list of patterns. These patterns should be given to compile() to be validated and converted into a match function.''' - syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'} + syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:', + 'include': 'include'} syntax = 'relre:' patterns = [] diff --git a/tests/test-hgignore.t b/tests/test-hgignore.t --- a/tests/test-hgignore.t +++ b/tests/test-hgignore.t @@ -167,3 +167,25 @@ Check recursive glob pattern matches no ? a.c ? a.o ? syntax + +Check using 'include:' in ignore file + + $ hg purge --all --config extensions.purge= + $ touch foo.included + + $ echo ".*.included" > otherignore + $ hg status -I "include:otherignore" + ? foo.included + + $ echo "include:otherignore" >> .hgignore + $ hg status + A dir/b.o + ? .hgignore + ? otherignore + +Check recursive uses of 'include:' + + $ echo "include:nestedignore" >> otherignore + $ echo "glob:*ignore" > nestedignore + $ hg status + A dir/b.o