Skip to content

fix: Respect dirty .gitignore patterns during task input hashing#12557

Merged
anthonyshew merged 1 commit intomainfrom
shew/investigate-12554
Apr 5, 2026
Merged

fix: Respect dirty .gitignore patterns during task input hashing#12557
anthonyshew merged 1 commit intomainfrom
shew/investigate-12554

Conversation

@anthonyshew
Copy link
Copy Markdown
Contributor

@anthonyshew anthonyshew commented Apr 5, 2026

Summary

Fixes #12554

When .gitignore is modified but not yet committed, its ignore patterns are silently dropped during untracked file discovery, causing gitignored paths (like node_modules/) to leak into task input hashes, which breaks caching.

Reason

PR #12339 replaced subprocess-based git ls-files with in-process gix-index for file discovery. The new find_untracked_files() function pre-builds gitignore matchers by scanning ls_tree_hashes — the set of clean tracked files whose stat matches the git index. When .gitignore is dirty (modified on disk), its stat no longer matches the index entry, so it gets classified as Modified and placed in status_entries instead. The matcher construction loop never looks there, so no ignore rules from that file are applied.

The old git ls-files --others --exclude-standard approach didn't have this problem because git reads .gitignore from the working tree, not from the index.

Fix

The gitignore matcher construction now scans both ls_tree_hashes and non-deleted entries in status_entries for .gitignore files. Since the code already reads .gitignore content from the filesystem (not from the index), the only change needed was expanding the iteration to include dirty tracked files.

Testing

Two regression tests added covering root-level and nested dirty .gitignore files. Both fail before the fix and pass after.

When .gitignore is modified but not yet committed, its stat no longer
matches the git index entry, so it gets classified as Modified and
placed in status_entries rather than ls_tree_hashes. The gitignore
matcher construction in find_untracked_files() only scanned
ls_tree_hashes, causing the dirty .gitignore to be invisible — its
patterns were silently dropped and gitignored paths like node_modules/
leaked into task input hashes.

Now scan both ls_tree_hashes and status_entries for .gitignore files.

Fixes #12554
@anthonyshew anthonyshew requested a review from a team as a code owner April 5, 2026 21:57
@anthonyshew anthonyshew requested review from tknickman and removed request for a team April 5, 2026 21:57
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented Apr 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
examples-basic-web Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-designsystem-docs Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-gatsby-web Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-kitchensink-blog Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-nonmonorepo Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-svelte-web Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-tailwind-web Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
examples-vite-web Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
turbo-site Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm
turborepo-agents Ready Ready Preview, Comment, Open in v0 Apr 5, 2026 9:58pm

@anthonyshew anthonyshew merged commit 1254916 into main Apr 5, 2026
59 checks passed
@anthonyshew anthonyshew deleted the shew/investigate-12554 branch April 5, 2026 22:34
github-actions Bot added a commit that referenced this pull request Apr 5, 2026
## Release v2.9.4

Versioned docs: https://v2-9-4.turborepo.dev

### Changes

- release(turborepo): 2.9.3 (#12524) (`0b48404`)
- fix: Always update $schema URL to versioned format during migration
(#12529) (`389cd5e`)
- release(turborepo): 2.9.4-canary.1 (#12530) (`7f8cb9a`)
- fix: Support `turbo.jsonc` in codemod transforms (#12532) (`e570d29`)
- feat: Add incremental task caching (#12531) (`39c4934`)
- release(turborepo): 2.9.4-canary.2 (#12533) (`d2944c4`)
- docs: Send siteId as label on feedback GitHub issues (#12527)
(`6644f34`)
- Replace local ai-agent-detection with @vercel/agent-readability
(#12528) (`86d34cc`)
- fix: Prevent `filterUsingTasks` `--filter` from pulling dependents
into Task Graph (#12535) (`d3aca27`)
- release(turborepo): 2.9.4-canary.3 (#12536) (`074a0ef`)
- build(deps): Bump @xmldom/xmldom from 0.8.11 to 0.8.12 in
/examples/with-react-native-web (#12537) (`295a89b`)
- fix: Only enforce signature key length for keys that exist (#12538)
(`27ac52f`)
- release(turborepo): 2.9.4-canary.4 (#12539) (`f745fc7`)
- fix: Validate engine concurrency after task-level filtering (#12540)
(`a38658a`)
- release(turborepo): 2.9.4-canary.5 (#12541) (`ac99fac`)
- fix: Preserve prerelease info in schema URL during codemod migration
(#12542) (`81b39a5`)
- feat: Allow `--affected` and `--filter` to be combined (#12543)
(`98ab3b6`)
- fix(config): Deep-merge nested OTEL config across priority sources
(#12513) (`f214dc8`)
- release(turborepo): 2.9.4-canary.6 (#12544) (`0e763f8`)
- fix: Retain microfrontend proxy tasks when using `filterUsingTasks`
(#12545) (`a4b943e`)
- release(turborepo): 2.9.4-canary.7 (#12546) (`b7d89a4`)
- fix: Bun workspace lockfile pruning producing invalid output (#12548)
(`0346076`)
- fix: Respect dirty .gitignore patterns during task input hashing
(#12557) (`1254916`)
- release(turborepo): 2.9.4-canary.8 (#12558) (`01802b4`)

---------

Co-authored-by: Turbobot <turbobot@vercel.com>
github-actions Bot added a commit that referenced this pull request Apr 6, 2026
## Release v2.9.5-canary.1

Versioned docs: https://v2-9-5-canary-1.turborepo.dev

### Changes

- fix: Respect dirty .gitignore patterns during task input hashing
(#12557) (`1254916`)
- release(turborepo): 2.9.4-canary.8 (#12558) (`01802b4`)
- release(turborepo): 2.9.4 (#12559) (`20dfb78`)
- feat: Replace package manager commands in scaffolded README files
(#6747) (`8f6f012`)

Co-authored-by: Turbobot <turbobot@vercel.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Dirty .gitignore causes gitignored files to leak into task input hashes (v2.8.18+)

1 participant