A spec-compliant .gitignore parser and path filter, 100% git-compatible, with an include/whitelist mode and a streaming, memory-bounded CLI
Project description
igittigitt
igittigitt is a spec-compliant .gitignore parser for Python - a library and a
command-line tool. Point it at .gitignore rules (or pass rules as strings) and ask
whether a path is ignored, or use it directly as the ignore= callback of
shutil.copytree.
Features
- 100% git-compatible matching. The matching engine reproduces git's algorithm
exactly - a single ordered pass with last-matching-pattern-wins, correct
negations (
!pattern), the rule that a file cannot be re-included when a parent directory is excluded, per-directory.gitignoreprecedence, anchors, trailing-slash (directory-only),**,*,?and[...]character classes. Compatibility is proven by a differential test suite that compares igittigitt against realgit check-ignoreon hundreds of generated cases. (This fixes the negation and nested-precedence limitations of older releases.) - Include / whitelist mode.
IncludeParserinverts the logic: patterns describe what to keep. It is directory-aware (rsync-like), so it works correctly as acopytreefilter even for deeply nested includes. - Memory-safe for millions of files. Both modes stream per directory and decide each
path in
O(depth x rules). Memory scales with the number of rules, never with the number of files or directories - so it stays flat on trees with millions of entries. - Scriptable CLI with piping.
igittigitt checkmirrorsgit check-ignore, andigittigitt filteris a Unix filter that reads paths from stdin and prints the survivors - newline- or NUL-separated (-z), streamed, with clean SIGPIPE handling, so it drops cleanly intofind ... | igittigitt filter. - Typed library, pure Python. Ships
py.typed, no runtime dependency on thegitbinary.
Install
uv is the recommended installer.
# as a project dependency
uv add igittigitt
# as a standalone CLI tool (isolated environment, added to PATH)
uv tool install igittigitt
# run once without installing
uvx igittigitt --help
# or classic pip / pipx
pip install igittigitt
pipx install igittigitt
The project targets Python 3.10+ and is tested on Linux, macOS and Windows across CPython 3.10-3.14. See INSTALL.md for every install method.
Library usage
Ignore mode
import igittigitt
parser = igittigitt.IgnoreParser()
# discover and parse every .gitignore below base_dir (per-directory precedence)
parser.parse_rule_files(base_dir="/home/user/project")
# ... or add rules explicitly
parser.add_rule("*.py[cod]", base_path="/home/user/project")
parser.add_rule("!keep.pyc", base_path="/home/user/project")
parser.match("/home/user/project/main.pyc") # True (ignored)
parser.match("/home/user/project/keep.pyc") # False (re-included by the negation)
Use it as a shutil.copytree filter to copy a tree without the ignored files:
import shutil, igittigitt
parser = igittigitt.IgnoreParser()
parser.parse_rule_files(base_dir="src_tree")
shutil.copytree("src_tree", "dst_tree", ignore=parser.shutil_ignore)
Whitelist / include mode
IncludeParser keeps only what matches; everything else is dropped. Including a
directory keeps its whole subtree, and unanchored patterns are found at any depth:
import shutil, igittigitt
inc = igittigitt.IncludeParser()
inc.add_rule("*.py", base_path="src_tree") # keep only python files...
inc.add_rule("docs/", base_path="src_tree") # ...and the whole docs/ subtree
# copy only the kept files (parent directories are descended into automatically)
shutil.copytree("src_tree", "dst_tree", ignore=inc.shutil_include)
inc.match("src_tree/pkg/deep.py") # True (kept)
CLI usage
# which of these paths are ignored? (like `git check-ignore`)
igittigitt check -C /path/to/repo a.log src/main.py
# exit 0 if at least one path is ignored, 1 if none
# show the matching rule (source:line:pattern), like `git check-ignore -v`
igittigitt check -C /path/to/repo -v a.log
# Unix filter: drop ignored paths from a stream
find . -type f | igittigitt filter
# keep only what matches the include patterns
find . -type f | igittigitt filter --include -r '*.py'
# NUL-separated I/O for paths with spaces/newlines
find . -print0 | igittigitt filter -z | xargs -0 ...
# inline rules and explicit ignore files
igittigitt check -r '*.tmp' -f .gitignore --stdin < paths.txt
Global options
| Option | Description |
|---|---|
--version |
Print the version and exit. |
--traceback / --no-traceback |
Show a full Python traceback on errors (default: off). |
--profile NAME |
Load configuration from a named profile. |
--set SECTION.KEY=VALUE |
Override one config value (repeatable), e.g. --set performance.dir_cache_max=16384. |
--env-file PATH |
Use an explicit .env file (skips the upward search). |
-h, --help |
Show help. |
Commands
| Command | What it does |
|---|---|
info |
Print resolved package metadata. |
check [PATHS...] |
Print the paths that are ignored (mirrors git check-ignore). Reads stdin with --stdin/-. Exit 0 if any matched, 1 if none. |
filter |
Unix filter: read paths from stdin and print the survivors. --include switches to whitelist mode. |
config |
Print the merged, layered configuration (with provenance). |
config-deploy |
Write the default config files into the app/host/user config directories. |
config-generate-examples |
Write example config files you can copy and edit. |
logdemo |
Emit sample log records (handy to preview logging themes). |
Shared check / filter options: -C/--base-dir, -f/--gitignore FILE (repeatable),
-r/--rule PATTERN (repeatable), --scan/--no-scan, --default-patterns, -z/--zero
(NUL I/O), and (check only) -v/--verbose and --stdin.
check and filter stream their input and write results immediately, with clean
SIGPIPE handling - so ... | igittigitt filter | head works without errors.
Configuration
igittigitt uses lib_layered_config: settings are merged from, lowest to highest precedence,
bundled defaults -> app -> host -> user -> .env file -> environment variables -> --set
Inspect the effective configuration with igittigitt config, and deploy editable copies
with igittigitt config-deploy. Override a single value per run with --set, in a .env
file as SECTION__KEY=value, or via an environment variable as IGITTIGITT___SECTION__KEY=value.
[performance] - engine and CLI tuning
These knobs only affect speed and cache memory, never which paths match. Defaults were chosen by measurement; all keep memory bounded.
| Key | Default | Meaning |
|---|---|---|
dir_cache_max |
8192 |
Capacity of the per-parser directory-decision LRU cache (0 disables it). The main speed-up on tree-shaped workloads; memory is O(this), not O(#files). |
pattern_cache_max |
4096 |
Capacity of the process-wide compiled-regex cache (keyed by distinct pattern). |
stdin_chunk_bytes |
65536 |
Read granularity for streaming paths from stdin. |
max_token_bytes |
1048576 |
Per-path safety bound; a separator-less token larger than this is rejected instead of buffered unbounded. |
Example: igittigitt --set performance.dir_cache_max=32768 filter -C repo.
[lib_log_rich] - logging
Logging is provided by lib_log_rich. The
[lib_log_rich] section configures console level/theme, journald/eventlog/Graylog
backends, queueing, scrubbing and payload limits. Every key is documented inline in the
deployed config.d/90-logging.toml; for example set the console level with
igittigitt --set lib_log_rich.console_level=DEBUG info or
IGITTIGITT___LIB_LOG_RICH__CONSOLE_LEVEL=DEBUG.
The full, commented settings live in the bundled config files (see config-generate-examples)
and in CONFIG.md.
Claude Code skill
This repo is itself a Claude Code
plugin/marketplace and ships a skill (skills/python-gitignore/)
that teaches Claude how to install, configure and use igittigitt (library, CLI, and bash
piping). Install it in any project:
/plugin marketplace add bitranox/igittigitt
/plugin install igittigitt
The same skill is also mirrored in the central bitranox marketplace
(https://github.com/bitranox/bitranox-skills) as python-gitignore.
AI transparency
This project was built by a human with AI assistance, used as a tool under human direction.
- ai-stance.md - why we work this way and how we think about AI in software.
- ai-disclosure.md - exactly where AI was and was not used in this project, and what has and has not been tested.
Further Documentation
- INSTALL.md - every installation method.
- DEVELOPMENT.md - make targets, testing, release workflow.
- CHANGELOG.md - release history.
- CONTRIBUTING.md - how to contribute.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file igittigitt-2.2.0.tar.gz.
File metadata
- Download URL: igittigitt-2.2.0.tar.gz
- Upload date:
- Size: 97.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
69832765092953a44bed41df42158610c5bfd36172442e2b6289fb56c9c1ddb0
|
|
| MD5 |
a6682f6acc6edcf8a83b4c184b1e11dd
|
|
| BLAKE2b-256 |
a8c5616f668db34269c6548a0156d165e6b65366534aacc624d810c1bf59abca
|
Provenance
The following attestation bundles were made for igittigitt-2.2.0.tar.gz:
Publisher:
default_release_public.yml on bitranox/igittigitt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
igittigitt-2.2.0.tar.gz -
Subject digest:
69832765092953a44bed41df42158610c5bfd36172442e2b6289fb56c9c1ddb0 - Sigstore transparency entry: 1970142769
- Sigstore integration time:
-
Permalink:
bitranox/igittigitt@ee1733c0664e81cbb1d438644028c19a0e7321c2 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/bitranox
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
default_release_public.yml@ee1733c0664e81cbb1d438644028c19a0e7321c2 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file igittigitt-2.2.0-py3-none-any.whl.
File metadata
- Download URL: igittigitt-2.2.0-py3-none-any.whl
- Upload date:
- Size: 69.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
70d87afc5aa0327b8e3902a3adbd1da65e30fa639e7ed66216bf7fa801950499
|
|
| MD5 |
d2f6084600bb759b70fa97f79e9537f8
|
|
| BLAKE2b-256 |
7e8164745cdbc17cf368e8d60365310e4810e236ece7b311ec1e1cf2ccd8a889
|
Provenance
The following attestation bundles were made for igittigitt-2.2.0-py3-none-any.whl:
Publisher:
default_release_public.yml on bitranox/igittigitt
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
igittigitt-2.2.0-py3-none-any.whl -
Subject digest:
70d87afc5aa0327b8e3902a3adbd1da65e30fa639e7ed66216bf7fa801950499 - Sigstore transparency entry: 1970143070
- Sigstore integration time:
-
Permalink:
bitranox/igittigitt@ee1733c0664e81cbb1d438644028c19a0e7321c2 -
Branch / Tag:
refs/heads/master - Owner: https://github.com/bitranox
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
default_release_public.yml@ee1733c0664e81cbb1d438644028c19a0e7321c2 -
Trigger Event:
workflow_dispatch
-
Statement type: