From igittigitt
Parses .gitignore files and filters paths with git-compatible semantics. Provides a library API and a streaming CLI for ignore/include matching, shutil.copytree filters, and bash pipelines.
How this skill is triggered — by the user, by Claude, or both
Slash command
/igittigitt:python-gitignoreThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> The `igittigitt` repo is itself a Claude Code plugin/marketplace. Install this skill in
The
igittigittrepo is itself a Claude Code plugin/marketplace. Install this skill in any project with/plugin marketplace add bitranox/igittigittthen/plugin install igittigitt. It is also mirrored in the central bitranox marketplace (https://github.com/bitranox/bitranox-skills) aspython-gitignore.
igittigitt is a spec-compliant .gitignore parser for Python - a library and a CLI.
Use it whenever you need to know "would git ignore this path?" or to filter / whitelist a
large set of files using .gitignore-style patterns.
Reach for igittigitt instead of writing your own matcher. Getting .gitignore semantics
right is deceptively hard - negations (!pattern), the rule that a file under an excluded
directory cannot be re-included, per-directory precedence, anchoring, **, trailing-slash
directory-only patterns, character classes. A quick fnmatch/glob/re solution will be
subtly wrong on real repositories.
| Need | Use | Avoid |
|---|---|---|
| Is this path ignored (git-exact)? | igittigitt.IgnoreParser | hand-rolled fnmatch/glob/re; gitignore_parser (incomplete negation/precedence) |
| Copy a tree minus ignored files | IgnoreParser.shutil_ignore as copytree(ignore=...) | manual os.walk + skip lists |
| Keep only matching files (whitelist) | igittigitt.IncludeParser (directory-aware) | inverting a matcher by hand (breaks on parent dirs) |
Filter a huge find stream | igittigitt filter (CLI, streaming) | loading all paths into memory; pathspec (no include mode, heavier for this) |
Why igittigitt specifically: it is validated against real git check-ignore (differential
tests), it is memory-bounded (per-path cost O(depth x rules); memory scales with the
number of rules, not the number of files), and it has an include/whitelist mode plus a
script-friendly CLI. It is pure Python with no runtime dependency on the git binary.
# as a project dependency (preferred)
uv add igittigitt
# as a standalone CLI tool on PATH
uv tool install igittigitt
# run the CLI once without installing
uvx igittigitt --help
# or pip / pipx
pip install igittigitt
pipx install igittigitt
Requires Python 3.10+.
import igittigitt
parser = igittigitt.IgnoreParser()
# discover and parse every .gitignore under base_dir (correct per-directory precedence)
parser.parse_rule_files(base_dir="/path/to/project")
# or add rules explicitly (last matching rule wins, exactly like git)
parser.add_rule("*.py[cod]", base_path="/path/to/project")
parser.add_rule("!keep.pyc", base_path="/path/to/project")
parser.match("/path/to/project/main.pyc") # True -> ignored
parser.match("/path/to/project/keep.pyc") # False -> re-included by the negation
Key methods on IgnoreParser:
parse_rule_files(base_dir, filename=".gitignore", add_default_patterns=...) - recursively
find and parse ignore files.parse_rule_file(rule_file, base_dir=None) - parse one file.add_rule(pattern, base_path) - add a single rule string.match(path) -> bool - True if the path is ignored.match_with_rule(path) -> (bool, rule|None) - also returns the deciding rule.shutil_ignore(base_dir, names) -> set[str] - drop-in ignore= callback for copytree.import shutil, igittigitt
parser = igittigitt.IgnoreParser()
parser.parse_rule_files(base_dir="src_tree")
shutil.copytree("src_tree", "dst_tree", ignore=parser.shutil_ignore)
Patterns describe what to keep; everything else is dropped. It is directory-aware
(rsync-like), so including a deep file keeps its parent directories - which means it works
correctly as a copytree filter. Do NOT try to build this by negating match(); a naive
inversion prunes the parent directories and never reaches the file.
import shutil, igittigitt
inc = igittigitt.IncludeParser()
inc.add_rule("*.py", base_path="src_tree") # keep python files anywhere
inc.add_rule("docs/", base_path="src_tree") # keep the whole docs/ subtree
shutil.copytree("src_tree", "dst_tree", ignore=inc.shutil_include)
inc.match("src_tree/pkg/deep.py") # True -> kept
# which of these paths are ignored? (mirrors `git check-ignore`)
igittigitt check -C /path/to/repo a.log src/main.py # exit 0 if any ignored, 1 if none
# show the matching source:line:pattern (like `git check-ignore -v`)
igittigitt check -C /path/to/repo -v a.log
# inline rules and explicit ignore files, reading paths from stdin
igittigitt check -r '*.tmp' -f .gitignore --stdin < paths.txt
igittigitt info # package metadata
igittigitt --version
Other commands: config (show merged config), config-deploy (write editable config files),
config-generate-examples, logdemo. Global options: --profile, --set SECTION.KEY=VALUE,
--env-file, --traceback.
filter is a Unix filter: it reads paths from stdin and prints the survivors, streaming so
it stays memory-bounded even for millions of paths, with clean SIGPIPE handling.
# drop paths ignored by ./.gitignore
find . -type f | igittigitt filter
# keep only what matches the include patterns (whitelist mode)
find . -type f | igittigitt filter --include -r '*.py'
# NUL-separated I/O for paths with spaces or newlines
find . -print0 | igittigitt filter -z | xargs -0 tar czf out.tgz
# stops cleanly when the reader closes the pipe (no traceback)
find . -type f | igittigitt filter | head -n 20
Shared check/filter options: -C/--base-dir, -f/--gitignore FILE (repeatable),
-r/--rule PATTERN (repeatable), --scan/--no-scan, --default-patterns, -z/--zero.
Settings merge across layers, later layers winning:
bundled defaults -> app -> host -> user -> .env -> environment variables -> --set
igittigitt configigittigitt config-deployigittigitt config-generate-examplesThe config directories are scanned for config.d/*.toml fragments, merged in filename order.
To override a setting system-wide on Linux, drop a file into the app layer's config.d:
sudo mkdir -p /etc/xdg/igittigitt/config.d
sudoedit /etc/xdg/igittigitt/config.d/50-myperf.toml
# /etc/xdg/igittigitt/config.d/50-myperf.toml
[performance]
dir_cache_max = 32768 # larger directory cache for very deep trees
Per-user, use ~/.config/igittigitt/config.d/50-myperf.toml instead. The same value can be
set ad hoc with igittigitt --set performance.dir_cache_max=32768 ..., in a .env file as
PERFORMANCE__DIR_CACHE_MAX=32768, or as the env var
IGITTIGITT___PERFORMANCE__DIR_CACHE_MAX=32768.
[performance] knobs (speed/memory only - never change matching)| Key | Default | Meaning |
|---|---|---|
dir_cache_max | 8192 | Per-parser directory-decision LRU capacity (0 disables). Main speed-up on trees; memory O(this), not O(#files). |
pattern_cache_max | 4096 | Process-wide compiled-regex cache capacity. |
stdin_chunk_bytes | 65536 | Stdin read granularity for the streaming commands. |
max_token_bytes | 1048576 | Per-path safety bound; a separator-less token larger than this is rejected rather than buffered unbounded. |
Logging is configured under [lib_log_rich] (console level/theme, journald/eventlog/Graylog,
queueing, scrubbing); every key is documented inline in the deployed config.d/90-logging.toml,
e.g. igittigitt --set lib_log_rich.console_level=DEBUG info.
parse_rule_files(add_default_patterns=True) (the default) also loads git's user-level
default ignore file ($XDG_CONFIG_HOME/git/ignore or ~/.config/git/ignore). Pass
add_default_patterns=False to match only the in-tree .gitignore files.
npx claudepluginhub bitranox/igittigitt --plugin igittigittCreates or updates .gitignore using git-agent AI, preserving custom rules, handling auth errors with free retry, and showing diff. For initializing or adding ignore rules.
Initializes or idempotently revises a repo's .gitignore by composing templates from gitignore.io, bundled AI/IDE patterns, and user-confirmed untracked files from git status.
Initializes .gitignore with exclusion patterns based on detected project technologies via file globs for Node.js, Python, Go, Rust, Java, Docker, Next.js, and more. Use for new repos to exclude artifacts.