fix: normalize git patch prefixes for parser compatibility#106
fix: normalize git patch prefixes for parser compatibility#106benvinegar merged 1 commit intomodem-dev:mainfrom
Conversation
1be1fda to
55ad40c
Compare
Greptile SummaryThis PR fixes a parser-compatibility bug where users with non-standard git diff prefix settings would see an empty "No files match the current filter" changeset in hunk. The issue is that the upstream diff parser expects canonical prefixed headers, which certain git config options suppress. The fix is clean and correctly scoped: a Key changes:
Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant CLI as hunk CLI
participant Builder as buildGit*Args()
participant Normalizer as withNormalizedDiffPrefixes()
participant RunGit as runGitText()
participant Git as git process
CLI->>Builder: input (kind, staged, ref, pathspecs…)
Builder->>Builder: build subcommand args<br/>["diff"/"show"/"stash show", flags…]
Builder->>Normalizer: args
Normalizer->>Normalizer: prepend -c diff.noprefix=false<br/>-c diff.mnemonicPrefix=false<br/>-c diff.srcPrefix=a/<br/>-c diff.dstPrefix=b/
Normalizer-->>Builder: [-c …flags…, "diff"/"show"/"stash show", …]
Builder-->>CLI: normalized args
CLI->>RunGit: { input, args }
RunGit->>Git: spawnSync(["git", "-c", "diff.noprefix=false", …, "diff", …])
Git-->>RunGit: stdout patch with canonical a/ b/ prefixes
RunGit-->>CLI: patch text
Reviews (1): Last reviewed commit: "fix: normalize git patch prefixes for pa..." | Re-trigger Greptile |
| test("loads stash show output when diff.noprefix is enabled", async () => { | ||
| const dir = createTempRepo("hunk-stash-noprefix-"); | ||
|
|
||
| writeFileSync(join(dir, "alpha.ts"), "export const alpha = 1;\n"); | ||
| git(dir, "add", "alpha.ts"); | ||
| git(dir, "commit", "-m", "initial"); | ||
|
|
||
| git(dir, "config", "--local", "diff.noprefix", "true"); | ||
| writeFileSync(join(dir, "alpha.ts"), "export const alpha = 2;\n"); | ||
| git(dir, "stash", "push", "-m", "update alpha"); | ||
|
|
||
| const bootstrap = await loadFromRepo(dir, { | ||
| kind: "stash-show", | ||
| options: { mode: "auto" }, | ||
| }); | ||
|
|
||
| expect(bootstrap.changeset.files.map((file) => file.path)).toEqual(["alpha.ts"]); | ||
| }); |
There was a problem hiding this comment.
Missing test coverage for
hunk show with noprefix config
The PR adds regression tests for git diff (unstaged + staged) and stash show with diff.noprefix=true, but buildGitShowArgs (used by hunk show) applies the same withNormalizedDiffPrefixes call and has no corresponding test. A user with diff.noprefix=true reviewing a commit via hunk show would hit the same original bug, and there's no guard against a future regression there.
Consider adding a parallel test:
test("loads show output when diff.noprefix is enabled", async () => {
const dir = createTempRepo("hunk-show-noprefix-");
writeFileSync(join(dir, "alpha.ts"), "export const alpha = 1;\n");
git(dir, "add", "alpha.ts");
git(dir, "commit", "-m", "initial");
git(dir, "config", "--local", "diff.noprefix", "true");
writeFileSync(join(dir, "alpha.ts"), "export const alpha = 2;\n");
git(dir, "add", "alpha.ts");
git(dir, "commit", "-m", "update alpha");
const bootstrap = await loadFromRepo(dir, {
kind: "show",
options: { mode: "auto" },
});
expect(bootstrap.changeset.files.map((file) => file.path)).toEqual(["alpha.ts"]);
});|
@aliou Thanks for this excellent PR! I've reviewed the changes and they're solid. The only feedback from the review was adding a test for Commit: The test passes and all 5 related noprefix/mnemonicPrefix tests now pass together: To incorporate this change, you can cherry-pick the commit if you're tracking the upstream remote: git fetch origin
git cherry-pick a3fd1bdOr I can push it to your fork directly if you add me as a collaborator. Otherwise, feel free to add the test manually - it's identical to the other noprefix tests, just using All the existing tests and typecheck pass. Great work on this fix! |
|
^Ignore my agent slop. Actually I'll just merge this and do the followup. |
Hello!
I tried to use
hunkbut kept having theNo files match the current filtererror no matter what args I passed. After some digging, it is because mygitconfiguration includes the following:So that
git diffdoesn't include thea/andb/prefixes:Instead of
For context, this is to not have to remove the prefix when copying the filename from tmux or via double click/tap.
This PR forces the necessary option so that @pierre/diff doesn't struggle to parse the diff.
Let me know if you need some additional info/changes!
summary from gpt 5.3
Summary
a/andb/) for git-backed inputs by passing command-scoped git config in:hunk diffhunk showhunk stash showWhy
@pierre/diffscurrently expectsa//b/-style headers. Repos/environments with settings likediff.noprefix=trueordiff.mnemonicPrefix=truecan emit non-canonical prefixes and lead to empty changesets in the UI.Tests
bun run typecheckbun test test/loaders.test.ts -t "loads git working tree changes when diff.noprefix is enabled|loads git working tree changes when diff.mnemonicPrefix is enabled|loads staged-only git diffs when diff.noprefix is enabled|loads stash show output when diff.noprefix is enabled"Notes