Skip to content

fix(web): handle file/directory path collision when opening PR diff - #80

Closed
macodev00 wants to merge 1 commit into
mainfrom
cursor/pr-diff-path-collision-6571
Closed

macodev00 wants to merge 1 commit into
mainfrom
cursor/pr-diff-path-collision-6571

Conversation

@macodev00

Copy link
Copy Markdown
Owner

Problem

Opening a PR diff crashes when git replaces a file or symlink with a directory of the same name, or the reverse. Pierre's file tree is one filesystem, so office plus office/config.ts throws Path collides with an existing file while creating directory "office" while the sidebar calls resetPaths or batch. The diff never opens. The same sidebar is the PR Code tab and the regular Diff panel on web and desktop.

Fixes pingdotgg#12887.

Change

diffFileTreeModel detects a path that is a slash-bounded prefix of another path and gives that file a distinct tree path. The row label stays the file name. Selection, reveal, and git status translate back to the diff path. Ordinary diffs keep the original path array, so their tree is unchanged.

A later PR slice that introduces the collision rebuilds the tree, because Pierre cannot rename the existing file into a directory in place. A refresh of the same set still updates in place and keeps folders the reader collapsed.

Scope and approval

pingdotgg#12887 is an accepted bug. The crash and the office segment are confirmed on the issue. This stays in the shared diff file tree. Mobile review does not use it. No contract or server change.

Verification

Node v24.13.1. vp is Vite+ from node_modules/.bin/vp. Commands from the repo root, with Node 24 first on PATH.

vp test run apps/web/src/components/diffs/diffFileTree.logic.test.ts apps/web/src/components/diffs/DiffFileTree.test.tsx

Exit 0.

Test Files  2 passed (2)
     Tests  30 passed (30)
  Duration  2.73s

That includes the raw ["office", "office/config.ts"] list throwing inside Pierre, the rewritten list loading, the reverse order, a nested path, a chain of prefixes (a, a/b, a/b/c), a later slice applied with batch, a refresh that rebuilds with resetPaths, and React selection of both files returning the real diff paths. A shared string prefix (office and officer.ts) is left unchanged.

vp fmt --check apps/web/src/components/diffs/diffFileTree.logic.ts apps/web/src/components/diffs/diffFileTree.logic.test.ts apps/web/src/components/diffs/DiffFileTree.tsx apps/web/src/components/diffs/DiffFileTree.test.tsx

Exit 0. All matched files use the correct format.

vp lint --report-unused-disable-directives apps/web/src/components/diffs/diffFileTree.logic.ts apps/web/src/components/diffs/diffFileTree.logic.test.ts apps/web/src/components/diffs/DiffFileTree.tsx apps/web/src/components/diffs/DiffFileTree.test.tsx

Exit 0. No findings.

vp run --filter @t3tools/web typecheck

Exit 0. tsc --noEmit in apps/web.

Limitations

No client screenshot. Ordinary diffs are the same tree. The colliding case stays in that tree instead of a new list, and both paths select the real diff file in the component test. I did not open the PR Code tab or Diff panel in a running app, and I did not use the original unnamed pull request. The regression pair is office and office/config.ts.

Grok 4.7, Cursor cloud agent.

Open in Web Open in Cursor 

Git can delete a file and add a directory of the same name in one diff.
Pierre's tree throws if both paths are inserted. Give that file a distinct
tree path and translate selection back to the diff path.

Fixes pingdotgg#12887.
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L labels Oct 2, 2026
@macodev00

Copy link
Copy Markdown
Owner Author

Opened upstream.

@macodev00 macodev00 closed this Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Opening PR diff crashes with file/directory path collision

1 participant