#874·fff

[Bug]: indexing ignores git's global core.excludesFile

Author: valkyriwebCreated Sep 17, 2026Updated Sep 17, 2026

Summary

FFF honors repo-local .gitignore and .ignore, but not git's global excludes file (core.excludesFile, commonly ~/.gitignore_global). Directories a user has globally ignored are still fully indexed.

This is a correctness gap rather than a feature request, so I filed it separately from #530 (which asks for opt-in ignore control / --no-ignore). Happy to fold them together if you'd prefer.

Why it matters

Tools like Worktrunk put git worktrees inside the repo (<repo>/.worktrees/<branch>) and hide them via the global excludes file precisely to avoid editing tracked .gitignore across many repos. That works for git, so the setup looks correct — but FFF indexes every one of those files.

Every worktree file is also a near-duplicate of a real path in the main tree, so the damage is not just size: real matches get crowded out. In one repo a search for an unrelated term returned 5/5 hits from .worktrees/, and the result set was capped at 5/65836.

Measured on my workspace:

Scope Files
one repo, real sources 260,197
same repo, .worktrees/ 497,193 (66% of index)
52 repos, total worktree duplication 2,143,597

Reproduction

bash
cd "$(mktemp -d)"
mkdir -p src .worktrees/wt1
echo x > src/hit.ts; echo x > .worktrees/wt1/hit.ts
git init -q .
printf '.worktrees/\n' > global_ignore
git config core.excludesFile "$PWD/global_ignore"

git check-ignore -q .worktrees/wt1 && echo "git: ignored"   # -> git: ignored

Then index that dir and search hit:

javascript
const f = FileFinder.create({ basePath, aiMode: true }).value;
await f.waitForScan(8000);
f.fileSearch("hit").value.items.map(i => i.relativePath);

Actual: .worktrees/wt1/hit.ts and src/hit.ts Expected: src/hit.ts only — git considers .worktrees/ ignored.

Control results from the same harness, confirming the gap is specific to the global file:

Ignore source Honored
repo-local .gitignore
repo-local .ignore
global core.excludesFile

Adding a repo-local .ignore with .worktrees/ drops the same query from 97 hits to 0, which confirms the walker is working correctly and only the ignore source is missing.

Notes

Observed via @ff-labs/pi-fff 0.10.6 / @ff-labs/fff-node 0.10.6 on darwin-arm64, but it looks like walker-level behavior rather than anything binding-specific. strings on libfff_c.dylib shows core.excludesfile already present, so libgit2 config reading may already be in reach.

Precedent: ripgrep reads core.excludesFile by default (--no-require-git aside), and fd does the same via the ignore crate — so honoring it would match what users expect from comparable tools.

Workaround

Repo-local .ignore restating the globally-ignored dirs; I automate it with a worktree-creation hook. Works, but needs repeating per repo.