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
.gitignoremanpage:# 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 "
.gitignorefile" does not have to be named.gitignorebut 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
.gitignoreexperience: 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
.gitignorehas a pattern which matches the given file/path, then we will returntrue, otherwise we returnfalse.Use this in directory trees where you have multiple
.gitignorefiles in nested directories and are implementing tooling withgit-like.gitignorebehaviour.
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
.gitignorespec differentiates between patterns such asfooandfoo/, 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()markoption which auto-postfixes a/to each directory it produces.
TBD
https://github.com/isaacs/node-glob
Apache 2, see LICENSE.md.