Repository navigation
Conversation
`git rev-parse --show-toplevel` answers with the repository's real path, while the caller asks about the cwd it was given: `/tmp` and `/var/folders/…` are links on macOS, so the two spell the same folder differently. Every path git reported was then resolved against the real root and kept only if it matched the caller's cwd as a string, which never happens through a link — a project reached that way had an empty changed-file list: no changed badge, no line counts, no entries at all. - `resolveExistingPath()` (`lib/paths.ts`) resolves the nearest existing ancestor and keeps the remainder as written, so a deleted file works too. `samePath()` stays lexical and says so; this is the resolving half. - `getGitStatus()` rebases every reported path onto the cwd it was asked about, and takes its line-stat pathspec from the resolved cwd. - `getGitFileDiff()` compares and derives its pathspec from the resolved pair, so a path named through a link still resolves to the file Git means, and a path that leaves the repository stays refused.
Contributor
Author
|
The first run's The |
This branch has not been deployed
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.
What it does
A project reached through a symlink had an empty changed-file list: no changed badge, no line counts, no entries at all.
resolveExistingPath()(lib/paths.ts): resolves the nearest existing ancestor and keeps the remainder as written, so a deleted file still works.samePath()stays lexical and says so; this is the resolving half.getGitStatus()(lib/git-changes.ts): rebases every path git reports onto the cwd the caller asked about, and takes the line-stat pathspec from the resolved cwd.getGitFileDiff()(lib/git-changes.ts): compares and derives its pathspec from the resolved pair, so a path named through a link still resolves to the file git means — and a path that resolves outside the repository stays refused.A folder that is not in a repository keeps answering
isGitRepository: falsewith nothing listed, and that is now pinned by a test.Why it matters (the broken behaviour)
On the base commit,
lib/git-changes.ts:getGitStatus(cwd)asks git for the repository root withgit rev-parse --show-toplevel(findRepositoryRoot,lib/git-changes.ts:30-32). That answer is the repository's real path.path.resolve(repositoryRoot, entry.path)and keeps it only ifisWithinPath(cwd, filePath)— a string comparison against the cwd the caller passed (lib/git-changes.ts:123-124).readTrackedLineStats,lib/git-changes.ts:61-66, called with the caller's cwd atlib/git-changes.ts:120).getGitFileDiff()compares the file against the repository root as strings (lib/git-changes.ts:207-209).On macOS those two never match when the project is behind a link: git says
/private/var/folders/…/project(the real path), the caller says/var/folders/…/project.path.resolvedoes not resolve symlinks, so every file is filtered out andfilescomes back empty — and the diff lookup answerssupported: false. The same is true for/tmp(a link to/private/tmp) and for any project the operator opened through a link of their own.How to reproduce (on main, before the fix)
Make a repository and modify a tracked file in it:
Link to it and open Pi Web on the link:
Open
/tmp/pi-web-repro/linkin Pi Web.Before the fix the Git panel is empty — no changed badge on
a.txt, no line counts, no entries — although the file is modified. The same happens for any project reached through/tmpor~/Library/Caches, which are links on macOS. After the fix the file is listed asMwith its line counts.Testing
Node 26.7.0 (
source ~/.nvm/nvm.sh && nvm use 26.7.0), in the worktree.npm test— pass:tests 2874 / suites 16 / pass 2873 / fail 0 / skipped 1(the one skip is the pre-existing Windows-only junction test inapp/api/git/diff/route.test.mjs).node_modules/.bin/tsc --noEmit— clean, no output.npm run lint— clean, no output.The new test fails on the untouched base commit and passes with the fix. On the base commit (
git checkout origin/main -- lib/git-changes.ts lib/paths.ts, tests kept):With the fix:
The test builds a repository in a temporary folder, makes a symlink of its own to it (so it works on any POSIX system, without relying on
/tmpbeing a link) and is skipped on Windows.Provenance
Ported by hand from the Bun-running fork https://github.com/brynne8/pi-web-bun, commit
478d5178("fix(files): name a changed file by the path the tree was given"). The fork's commit also touchedlib/git-revert.ts— a write path — which has the same cause (it derives the checkout's path from the unresolved pair). That part is deliberately not part of this PR and should be done separately.Notes
getGitFileDiffdrops any candidate path that leaves the repository, and the routes' allowed-root rules are unchanged).