Replace go-git gitignore matcher with custom implementation#99
Merged
Conversation
a1186c6 to
686cbad
Compare
go-git's gitignore.Matcher doesn't handle negation patterns correctly. Repos with deny-by-default .gitignore patterns (/* then !.github/) cause DependenciesInWorkingDir and where to skip entire directory trees that should be visible, breaking diff on clean working trees. Add internal/gitignore package with a matcher that correctly implements gitignore semantics: last-match-wins, directory-only trailing slash, leading/middle slash anchoring, ** in all positions, and pattern scoping for nested .gitignore files. Verified against git check-ignore. Remove LoadIgnoreMatcher/IgnoreMatcher from repository.go. Add GetExcludeDirs for configurable directory skipping via git config. Ref #98
The "escaped wildcards" test case creates files named hello* and hello? on disk, which Windows does not support. Skip this case on Windows since it's a filesystem limitation, not a matcher bug.
npm lockfiles can contain the same package at multiple versions due to dependency hoisting (e.g. ini@6.0.0 and ini@4.1.1). Both computeDiff and AnalyzeCommit used single-value maps keyed by package name, so duplicate versions collapsed to whichever was iterated last. When the database and working tree paths iterated in different orders, this produced phantom "modified" entries on clean workspaces. Replace single-value maps with multi-maps in both locations: - computeDiff: group by manifest:name, compare version sets when a package appears at multiple versions - AnalyzeCommit: replace beforeByName/afterByName with multi-maps so PreviousRequirement reflects the actual replaced version Fixes #53
Git's wildmatch supports POSIX character classes like [[:space:]], [[:alpha:]], [[:digit:]] inside bracket expressions. Our parseBracket found the first ] as the closing bracket, splitting [[:space:]] into [[:space:] plus a literal ]. Fix by skipping past [:...:] sequences when scanning for the closing bracket. Test cases adapted from git/t/t3070-wildmatch.sh, including multiple classes in one bracket and mixing ranges with POSIX classes.
In wildmatch, \X inside a bracket expression means literal X. The bracket parser was blindly doubling all backslashes for the regex engine, which broke patterns like [\-_] (literal dash and underscore), [\1-\3] (range 1-3), and [[-\]] (range [ to ]). The fix processes escape sequences during both bracket scanning (so \] does not prematurely close the bracket) and content building (so \X resolves to the literal character).
c476f27 to
224ce8d
Compare
Replace the internal gitignore package with the standalone module.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
go-git's gitignore matcher doesn't handle negation patterns correctly. Repos with deny-by-default .gitignore patterns (
/*then!.github/) causeDependenciesInWorkingDirandwhereto skip directory trees that should be visible, breakingdiffon clean working trees.Adds
internal/gitignorepackage with a matcher that correctly implements gitignore semantics: last-match-wins, directory-only trailing slash, leading/middle slash anchoring,**in all positions, and pattern scoping for nested.gitignorefiles. Includes a test that validates againstgit check-ignoredirectly.Tested against
ericcornelissen/ades@14ab252which has a thorough deny-by-default.gitignore. Previously broken, now shows "No dependency changes" as expected.Ref #98