Gitignore Parser
A simple yet complete .gitignore
parser for node.js.
npm install @gerhobbelt/gitignore-parser
Supports all features listed in the GIT SCM gitignore manpage:
-
handles the
**
wildcard anywhere- in both the usual usage, e.g.
foo/**/bar
, and also in complexes such asyo/**la/bin
- can be used multiple times in a single pattern, e.g.
foo/**/rec**on
- in both the usual usage, e.g.
-
handles the
*
wildcard -
handles the
?
wildcard -
handles
[a-z]
style character ranges -
understands
!
-prefixed negated patterns -
understands
\#
,\[
,\\
, etc. filename escapes, thus handles patterns like\#*#
correctly (hint: this is NOT a comment line!) -
deals with any sequence of positive and negative patterns, like this one from the
.gitignore
manpage:# exclude everything except directory foo/bar /* !/foo /foo/* !/foo/bar
-
handles any empty lines and
#
comment lines you feed it -
we're filename agnostic: the "
.gitignore
file" does not have to be named.gitignore
but can be named anything: this parser accepts.gitignore
-formatted content from anywhere: you load the file, we do the parsing, you feed ouraccepts()
ordenies()
APIs any filenames / paths you want filtered and we'll tell you if it's a go or a no go. -
extra: an additional API is available for those of you who wish to have the complete and utter
.gitignore
experience: use ourinspects(path)
API to know whether the given gitignore filter set did actively filter the given file or did simple allow it to pass through.Read as: if the
.gitignore
has a pattern which matches the given file/path, then we will returntrue
, otherwise we returnfalse
.Use this in directory trees where you have multiple
.gitignore
files in nested directories and are implementing tooling withgit
-like.gitignore
behaviour.
var parser = require('@gerhobbelt/gitignore-parser'),
fs = require('fs');
var gitignore = parser.compile(fs.readFileSync('.gitignore', 'utf8'));
gitignore.accepts('LICENSE.md') === true;
gitignore.denies('LICENSE.md') === false;
gitignore.inspects('LICENSE.md') === false;
gitignore.accepts('node_modules/mocha/bin') === false;
gitignore.denies('node_modules/mocha/bin') === true;
gitignore.inspects('node_modules/mocha/bin') === true;
gitignore.accepts('foo/bar') === true;
gitignore.denies('foo/bar') === false;
gitignore.inspects('foo/bar') === true; // <-- as there's a negated pattern `!foo/bar` addressing this one
var files = [
'.gitignore',
'.travis.yml',
'LICENSE.md',
'README.md',
'package.json',
'lib/index.js',
'test/index.js',
'test/mocha.opts',
'node_modules/mocha/bin/mocha',
'node_modules/mocha/README.md'
];
// produce only files that are not gitignored
let list = files.filter(gitignore.accepts);
// produce only files that *are* gitignored
let list = files.filter(gitignore.denies);
-
As the
.gitignore
spec differentiates between patterns such asfoo
andfoo/
, where the latter only matches any directory namedfoo
, you MUST pass the is-this-a-file-or-a-directory info to us when you invoke any of ouraccepts()
,denies()
andinspects()
APIs by making sure directory paths have a trailing/
.When you feed us straight from
glob()
, you can accomplish this in the quickest possible way by using theglob()
mark
option which auto-postfixes a/
to each directory it produces.
TBD
https://github.com/isaacs/node-glob
Apache 2, see LICENSE.md.