Summary — After a wildcard ignore /*/ re-includes a directory via negation (!/keep/), the walker still drops that directory's nested subdirectories, omitting files git tracks. A literal ignore-then-reinclude (/keep/ + !/keep/) works correctly, so it's specific to the /*/ wildcard.
Repro — .gitignore containing /*/ then !/keep/, with a tree:
q := make(chan *gocodewalker.File, 1024)
w := gocodewalker.NewParallelFileWalker([]string{"."}, q)
go func() { _ = w.Start() }()
for f := range q { fmt.Println(f.Location) }
Expected (matches git ls-files): keep/a.rs and keep/sub/c.rs.
Actual: only keep/a.rs — keep/sub/c.rs (depth-2, git-tracked) is missing.
Isolation
.gitignore |
git keeps |
gocodewalker walks |
/*/ + !/keep/ |
keep/a.rs, keep/sub/c.rs |
keep/a.rs only ❌ |
/keep/ + !/keep/ |
keep/a.rs, keep/sub/c.rs |
both ✅ |
/drop/ (no negation) |
sub/drop/y.rs |
sub/drop/y.rs ✅ |
/*/ keeps matching the re-included directory's nested subdirectories (keep/sub/), even though a leading-slash pattern is anchored to the .gitignore directory and /*/ should only match first-level entries.
Versions — Reproduces on v1.5.1 (latest release) and current master (via ghcr.io/boyter/scc:master, built 2026-06-26). Looks like the same root-anchoring issue as boyter/scc#408, closed as fixed by the gocodewalker rewrite — this wildcard and negation case seems to have slipped through.
Summary — After a wildcard ignore
/*/re-includes a directory via negation (!/keep/), the walker still drops that directory's nested subdirectories, omitting files git tracks. A literal ignore-then-reinclude (/keep/+!/keep/) works correctly, so it's specific to the/*/wildcard.Repro —
.gitignorecontaining/*/then!/keep/, with a tree:Expected (matches
git ls-files):keep/a.rsandkeep/sub/c.rs.Actual: only
keep/a.rs—keep/sub/c.rs(depth-2, git-tracked) is missing.Isolation
.gitignore/*/+!/keep//keep/+!/keep//drop/(no negation)/*/keeps matching the re-included directory's nested subdirectories (keep/sub/), even though a leading-slash pattern is anchored to the.gitignoredirectory and/*/should only match first-level entries.Versions — Reproduces on
v1.5.1(latest release) and currentmaster(viaghcr.io/boyter/scc:master, built 2026-06-26). Looks like the same root-anchoring issue as boyter/scc#408, closed as fixed by the gocodewalker rewrite — this wildcard and negation case seems to have slipped through.