fix(canonical): apply .gitignore consistently across publisher and consumer content-hash walks - #1205
Conversation
026e3e0 to
29008fb
Compare
29008fb to
edecdef
Compare
edecdef to
811d00a
Compare
There was a problem hiding this comment.
Stale comment
Left a non-blocking comment; no reviewers assigned. Cursor Bugbot passed with no unresolved findings that need human review (Security Agent was not running). This is not approved because the content-hash walker change is not a small fixup.
Sent by Cursor Approval Agent: Pull Request Router and Approver
811d00a to
69330a8
Compare
There was a problem hiding this comment.
Stale comment
Left a non-blocking comment; no reviewers assigned. Cursor Bugbot passed with no unresolved findings that need human review (Security Agent was not running). This is not approved because the content-hash walker change is not a small fixup.
Sent by Cursor Approval Agent: Pull Request Router and Approver
…nsumer content-hash walks
69330a8 to
7cd15fb
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 7cd15fb. Configure here.
| .parents(false) | ||
| .require_git(false) | ||
| .git_global(false) | ||
| .git_exclude(false) |
There was a problem hiding this comment.
Ancestor ignore skip hashes local junk
High Severity
.parents(false) stops the publisher from applying workspace .gitignore rules, so untracked files that Git ignores at the repo root are hashed. Consumers unpack git archive and never see those files, so verification fails and the package cannot be resolved.
Reviewed by Cursor Bugbot for commit 7cd15fb. Configure here.




Detail bug report: View on Detail
Bug
pcb-canonicalcomputes a BLAKE3 content hash over a package's files, recorded bypcbc publishin an annotated git tag and recomputed bypcb-zen's resolver over the fetched package, which bails (verify_tag_hashes) if the two differ. The walker usedignore::WalkBuilderwith defaults, so committed.gitignorerules were only applied when a.git/.jjdirectory existed above the walked root (ignore's defaultrequire_git(true)): the publisher walks inside the workspace git repo (.gitpresent →.gitignoreapplied), while the consumer walks agit archiveextract (.gitabsent →.gitignoreignored). For a tracked file matching a committed.gitignorerule (e.g. a force-addeddebug.logagainst*.log, or a file committed before being added to.gitignore), the two walks saw different file sets, so the hashes diverged and every consumer's verification failed — the package became unresolvable.Fix
Set the walker to
.require_git(false)so committed.gitignoreis applied regardless of whether.gitis present, and.git_global(false)/.git_exclude(false)to ignore the per-machine global gitignore and.git/info/exclude(neither is part of the committed tree andgit archiveignores both, so honoring them was itself a divergence source).git_ignore(true)stays the default, so committed.gitignoreis now honored identically on both sides — preserving the documented "Respect .gitignore" canonicalization rule — while the hash becomes environment-independent and matches whatgit archiveactually emits.Added a regression test (
publisher_and_consumer_hashes_agree_for_tracked_but_ignored_file) that runs a realgitround-trip: it force-addsdebug.logagainst a*.log.gitignore, commits, hashes the in-repo dir as the publisher, extractsgit archive HEADinto a.git-less tempdir as the consumer, and asserts both sides dropdebug.logand produce equal hashes. This is the only test that exercises the publisher side with a real.git, closing the gap that let this bug go undetected.Testing
gitignore_patternssnapshot test now reflects.gitignorebeing applied in a non-git tempdir (the snapshot was updated to drop the previously-included ignored files — please review and approve that snapshot change).pcb-zensuite passes (112/112), including all other canonical snapshot tests (golden hash stability, nested-package exclusion,pcb.sumexclusion, single-file hashing, determinism).-D warnings), andcargo fmt --checkare clean; doctests pass.pcbctests (publish/release/tag) pass where the layout pipeline is not required; the remainingpcbcfailures in this sandbox are pre-existing KiCad-version incompatibilities (footprint-library format and missingkicad-cli pcb drc/ercsubcommands — the environment has KiCad 7.0.11, CI uses 10.0.5). A baseline comparison (same tests with the fix reverted under the same KiCad 7) produced the identical failures, confirming no regressions from this change.Automatic Fixes PRs can be configured here.
Note
Medium Risk
Changes which files enter content hashes, so previously published tags can disagree until republished; this directly affects publish verification and dependency resolution integrity.
Overview
Aligns package content hashing so publish-time walks in a git repo and consumer walks over
git archiveextracts see the same files.The canonical
WalkBuildernow applies only package-local.gitignore/.ignore(.parents(false),.require_git(false)) and skips ancestor rules, global gitignore, and.git/info/exclude. That removes hash mismatches that broke tag verification when committed ignore rules were honored on one side but not the other.Adds a git round-trip regression test (in-repo package dir vs archive extract) and updates the
gitignore_patternssnapshot to match ignore behavior in non-git tempdirs. Docs and changelog note that older published hashes tied to ancestor or machine-local excludes may need a new package version.Reviewed by Cursor Bugbot for commit 7cd15fb. Bugbot is set up for automated code reviews on this repo. Configure here.