Skip to content

Load .gitignore contents relative to their location#262

Merged
arcanis merged 2 commits intomainfrom
fix/pack-gitignore
Mar 12, 2026
Merged

Load .gitignore contents relative to their location#262
arcanis merged 2 commits intomainfrom
fix/pack-gitignore

Conversation

@bgotink
Copy link
Copy Markdown
Member

@bgotink bgotink commented Mar 2, 2026

Currently yarn pack incorrectly applies a * gitignore pattern in repos that use Husky, since /.husky/_/.gitignore is loaded as if it's /.gitignore

75% of tests fail on my machine, including a bunch of tests that are stuck on git commit timing out trying to sign stuff, so I'll have to figure that out before I can fix any tests this PR breaks.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 2, 2026

Confidence Score: 4/5

  • The code change is correct and well-scoped; the main open question is test coverage given the acknowledged test failures.
  • The core fix in pack.rs is logically sound — the from_dir argument to PackIgnore::add correctly scopes each pattern to its owning directory, fixing the root-cause bug. The change also simplifies the call site. The only concern is that the PR author explicitly acknowledges 75% of the test suite is failing on their machine due to unrelated issues (git commit signing), so the full test suite hasn't been validated. The new acceptance test covers the specific regression case correctly.
  • No files require special attention — the change is well-contained within packages/zpm/src/pack.rs.

Important Files Changed

Filename Overview
packages/zpm/src/pack.rs Correctly fixes gitignore scoping: load_ignore now passes each ignore file's containing directory as from_dir to PackIgnore::add, instead of always using the root path. This ensures patterns like * or /index.js are resolved relative to the directory that owns the ignore file.
tests/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js Adds a regression test for the new behaviour. The test correctly verifies that a rooted pattern in a subdirectory gitignore excludes only files in that subdirectory, though the first assertion is slightly ambiguous (see comment).
contributing/general-commands.md Trailing whitespace removed from two section headings — cosmetic only.

Last reviewed commit: 1f0e41e

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 3, 2026

⏱️ Benchmark Results

gatsby install-full-cold

Metric Base Head Difference
Mean 2.546s 2.496s -1.94% ✅
Median 2.545s 2.491s -2.12% ✅
Min 2.353s 2.371s
Max 2.714s 2.600s
Std Dev 0.073s 0.058s
📊 Raw benchmark data (gatsby install-full-cold)

Base times: 2.714s, 2.708s, 2.580s, 2.526s, 2.572s, 2.560s, 2.511s, 2.537s, 2.522s, 2.544s, 2.629s, 2.503s, 2.552s, 2.535s, 2.540s, 2.546s, 2.476s, 2.556s, 2.557s, 2.491s, 2.400s, 2.353s, 2.501s, 2.590s, 2.466s, 2.581s, 2.585s, 2.530s, 2.600s, 2.600s

Head times: 2.518s, 2.503s, 2.495s, 2.557s, 2.569s, 2.579s, 2.464s, 2.438s, 2.475s, 2.522s, 2.454s, 2.479s, 2.472s, 2.596s, 2.528s, 2.565s, 2.553s, 2.549s, 2.472s, 2.486s, 2.392s, 2.466s, 2.497s, 2.504s, 2.488s, 2.600s, 2.432s, 2.437s, 2.424s, 2.371s


gatsby install-cache-and-lock (warm, with lockfile)

Metric Base Head Difference
Mean 0.436s 0.441s +1.05% ⚠️
Median 0.436s 0.439s +0.60% ⚠️
Min 0.431s 0.431s
Max 0.445s 0.483s
Std Dev 0.003s 0.011s
📊 Raw benchmark data (gatsby install-cache-and-lock (warm, with lockfile))

Base times: 0.445s, 0.436s, 0.431s, 0.435s, 0.432s, 0.437s, 0.435s, 0.436s, 0.431s, 0.432s, 0.435s, 0.432s, 0.439s, 0.435s, 0.442s, 0.435s, 0.435s, 0.434s, 0.436s, 0.439s, 0.438s, 0.439s, 0.437s, 0.440s, 0.436s, 0.438s, 0.437s, 0.437s, 0.437s, 0.439s

Head times: 0.440s, 0.444s, 0.441s, 0.438s, 0.443s, 0.437s, 0.443s, 0.448s, 0.441s, 0.472s, 0.441s, 0.440s, 0.442s, 0.441s, 0.438s, 0.443s, 0.440s, 0.483s, 0.437s, 0.433s, 0.433s, 0.431s, 0.436s, 0.436s, 0.433s, 0.432s, 0.434s, 0.436s, 0.435s, 0.438s

@arcanis
Copy link
Copy Markdown
Member

arcanis commented Mar 4, 2026

Looks good; do you think you could add a test? If you only run that one it probably won't crash on git or anything

@bgotink bgotink force-pushed the fix/pack-gitignore branch from 25eace1 to 93cf3c8 Compare March 10, 2026 18:28
@bgotink bgotink force-pushed the fix/pack-gitignore branch from 93cf3c8 to 1f0e41e Compare March 10, 2026 18:29
@bgotink
Copy link
Copy Markdown
Member Author

bgotink commented Mar 10, 2026

Done, sorry for the wait I was out of the country for a few days ^^

await run(`install`);

const {stdout} = await run(`pack`, `--dry-run`);
expect(stdout).toMatch(/index\.js/);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First assertion matches subdirectory path as a substring

/index\.js/ will also match the string subdir/index.js (because index.js appears as a substring). The two assertions together still correctly validate the intended behaviour — the second one guarantees subdir/index.js is absent, so the first one in practice can only be satisfied by the root-level file. However, if the root index.js were accidentally excluded while subdir/index.js was kept, the test would still pass (both assertions satisfied: "index.js" present as a substring of "subdir/index.js", and the literal "subdir/index.js" not present — wait, that contradicts; actually it would fail the second assertion). The subtle risk is that a future developer reading only the first assertion might think it exclusively verifies the root file. Using a more anchored pattern makes the intent explicit:

Suggested change
expect(stdout).toMatch(/index\.js/);
expect(stdout).toMatch(/(?<![/\\])index\.js/);

Or alternatively, assert on the full relative path that should be present:

Suggested change
expect(stdout).toMatch(/index\.js/);
expect(stdout).toMatch(/\bindex\.js\b/);
expect(stdout).toMatch(/index\.js/); // root-level file included

This is a minor style concern — the test is functionally correct as-is.

Prompt To Fix With AI
This is a comment left during a code review.
Path: tests/acceptance-tests/pkg-tests-specs/sources/commands/pack.test.js
Line: 294

Comment:
**First assertion matches subdirectory path as a substring**

`/index\.js/` will also match the string `subdir/index.js` (because `index.js` appears as a substring). The two assertions together still correctly validate the intended behaviour — the second one guarantees `subdir/index.js` is absent, so the first one in practice can only be satisfied by the root-level file. However, if the root `index.js` were accidentally excluded while `subdir/index.js` was kept, the test would still pass (both assertions satisfied: "index.js" present as a substring of "subdir/index.js", and the literal "subdir/index.js" not present — wait, that contradicts; actually it would fail the second assertion). The subtle risk is that a future developer reading only the first assertion might think it exclusively verifies the root file. Using a more anchored pattern makes the intent explicit:

```suggestion
        expect(stdout).toMatch(/(?<![/\\])index\.js/);
```

Or alternatively, assert on the full relative path that *should* be present:

```suggestion
        expect(stdout).toMatch(/\bindex\.js\b/);
        expect(stdout).toMatch(/index\.js/); // root-level file included
```

This is a minor style concern — the test is functionally correct as-is.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of the suggested changes solve the "problem"

@arcanis arcanis merged commit 55bc16e into main Mar 12, 2026
14 checks passed
@arcanis arcanis deleted the fix/pack-gitignore branch March 12, 2026 10:18
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.

2 participants