fix: resolve the checkout root correctly inside a git worktree - #218
Merged
Conversation
Edit URLs were wrong for anyone running Docfy from a linked git worktree. `getRepoEditUrl` computed `path.relative(getRepoInfo(root).root, root)`, and git-repo-info's own typings document that `root` "is the directory containing the original copy, not the worktree" — so the relative path picked up the worktree's location and produced links to paths that do not exist on the remote. This is not hypothetical. It is why four committed .gjs templates shipped with `.claude/worktrees/<branch>/` in their @editUrl values, fixed in #214, and it is the real reason the repo-info and generating-edit-url tests failed locally. I had been calling those failures environmental for most of this work; they were this bug. A worktree's metadata directory holds a `gitdir` file pointing at that worktree's `.git` file, whose parent is the top level we want. Outside a worktree `worktreeGitDir` equals `commonGitDir`, so there is nothing to correct — note that detecting a worktree requires comparing the two rather than checking `worktreeGitDir` for truthiness, since it is always populated. Adds a regression test that builds a real repository and worktree in a temp directory. CI runs in a normal checkout, so without it this fix could regress invisibly. Confirmed the test fails without the fix (`edit/linked/docs/` instead of `edit/main/docs/`) while its main-checkout counterpart still passes. @docfy/core's suite now passes fully in a worktree — 59/59 across 12 files, where 6 tests in 3 files used to fail. Building test-app-vite in a worktree no longer rewrites the committed templates either, which removes the manual path-stripping step that #215 needed three times. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Edit URLs are wrong for anyone running Docfy from a linked git worktree.
getRepoEditUrlcomputespath.relative(getRepoInfo(root).root, root). git-repo-info's own typings document the trap:So the relative path picks up the worktree's location and the URL points at a path that doesn't exist on the remote:
This already caused damage
Four committed
.gjstemplates shipped with.claude/worktrees/<branch>/baked into their@editUrlvalues — every "Edit this page" link on those demo pages 404'd until #214 fixed them by hand.It is also the real reason
repo-info.test.tsandgenerating-edit-url.test.tsfail locally. I spent most of the unified 11 work describing those as environmental noise and repeating that in PR descriptions. They were this bug, and treating them as noise is what let the bad templates through.The fix
A worktree's metadata directory holds a
gitdirfile pointing at that worktree's.gitfile, whose parent is the top level we want.One subtlety worth flagging for review: detecting a worktree requires comparing
worktreeGitDiragainstcommonGitDir, not checkingworktreeGitDirfor truthiness. It is always populated — outside a worktree it simply equalscommonGitDir. My first pass got this wrong and would have taken the correction path always.Regression test
CI runs in a normal checkout, so this fix could regress invisibly there. The new test builds a real repository and worktree in a temp directory and asserts both resolve identically.
I verified it actually catches the bug rather than just passing:
…/edit/main/docs/{filepath}…/edit/**linked**/docs/{filepath}❌…/edit/main/docs/{filepath}…/edit/main/docs/{filepath}The second row matters as much as the first — it shows the fix doesn't alter normal-checkout behaviour.
The test uses
fs.realpathSyncon the temp dir becauseos.tmpdir()is a symlink on macOS and git records the resolved path; comparing against the unresolved one would fail there but pass on Linux.Result
@docfy/corenow passes 59/59 across 12 files in a worktree, where 6 tests in 3 files used to fail. And buildingtest-app-vitefrom a worktree no longer rewrites the committed templates — removing the manual path-stripping step #215 needed three separate times.Also verified:
pnpm -r run compileclean,@docfy/ember-vite60/60,@docfy/plugin-with-prose2/2, both app builds succeed, lint and prettier clean.🤖 Generated with Claude Code