[package-deps-hash] Fix build cache failures in git linked worktrees caused by GIT_DIR set by pre-commit hooks#5815
Open
istateside wants to merge 2 commits into
Conversation
7b20309 to
7bfddde
Compare
istateside
commented
Jun 3, 2026
Comment on lines
+36
to
+57
| 'CON', | ||
| 'PRN', | ||
| 'AUX', | ||
| 'NUL', | ||
| 'COM1', | ||
| 'COM2', | ||
| 'COM3', | ||
| 'COM4', | ||
| 'COM5', | ||
| 'COM6', | ||
| 'COM7', | ||
| 'COM8', | ||
| 'COM9', | ||
| 'LPT1', | ||
| 'LPT2', | ||
| 'LPT3', | ||
| 'LPT4', | ||
| 'LPT5', | ||
| 'LPT6', | ||
| 'LPT7', | ||
| 'LPT8', | ||
| 'LPT9' |
Author
There was a problem hiding this comment.
This change came from the pre-commit prettier script - not sure if my dev environment isn't set up correctly, but I can revert this specific change if needed.
Author
|
@microsoft-github-policy-service agree company="Squarespace" |
… calls to fix build cache in linked worktrees
When a git pre-commit hook runs in a linked worktree, git sets GIT_DIR to the
per-worktree metadata directory (.git/worktrees/{name}) without setting
GIT_WORK_TREE. With GIT_DIR set this way, `git rev-parse --show-toplevel`
returns the CWD (e.g. the rushJsonFolder subdirectory) instead of the actual
worktree root, causing all subsequent git calls to use the wrong root directory.
This makes `git status -u` miss the top-level .gitignore, surfacing node_modules
symlinks as untracked files, which then causes `git hash-object` to fail on
symlink-to-directory entries and ultimately breaks the build cache.
Fix: strip GIT_DIR and GIT_WORK_TREE from the environment in getRepoRoot,
spawnGitAsync, and getRepoChanges so git auto-discovers the correct repo root
from the working directory regardless of hook-injected env vars.
7bfddde to
ef318f0
Compare
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.
Summary
Fixes build cache failures when Rush commands that trigger incremental build analysis run inside a git linked worktree via a pre-commit hook.
Fixes #5479
When git invokes a pre-commit hook in a linked worktree, it sets
GIT_DIRto the per-worktree metadata directory (e.g..git/worktrees/{name}) but does not setGIT_WORK_TREE. Child processes inherit this environment.getRepoRoot()callsgit rev-parse --show-topleveland inherits thisGIT_DIR, causing git to return thecurrentWorkingDirectoryargument (e.g. therushJsonFoldersubdirectory) instead of the actual worktree root. All subsequent git calls use this wrong root, causinggit status -uto miss the top-level.gitignore, surfacingnode_modules/symlinks as untracked files, whichgit hash-objectcannot hash — ultimately reported as "Build cache is only supported if running in a Git repository."Details
The fix strips
GIT_DIRandGIT_WORK_TREEfrom the environment before spawning any git subprocess ingetRepoState.ts. This lets git auto-discover the correct repo root by scanning up fromcurrentWorkingDirectory, which correctly resolves to the linked worktree root regardless of the hook-injected environment. Three call sites are patched:getRepoRoot,spawnGitAsync(used bygetDetailedRepoStateAsyncandhashFilesAsync), andgetRepoChanges.This regression was introduced in #5500, which switched from
git ls-tree -r HEAD(reads committed objects, never surfacesnode_modules/) togit ls-files --cached+git status -u(scans the work tree, exposing the broken.gitignorecontext).The diff also includes prettier reformatting the
WINDOWS_RESERVED_BASENAMESarray from a compact multi-line form to one-entry-per-line — this is an unrelated side effect of the project's pre-commit hook. Happy to add a// prettier-ignorecomment to suppress it if preferred.How it was tested
Added a unit test to
getRepoDeps.test.tsthat setsGIT_DIRto a nonexistent path (simulating hook interference) and verifies thatgetRepoRootstill returns the correct repo root. Without the fix,git rev-parseexits 128 ("not a git repository") and the function throws; with the fix,GIT_DIRis stripped and git auto-discovers the root correctly.Also manually reproduced the original failure by running a Rush build command from within a git linked worktree via a pre-commit hook and confirmed the build cache error no longer occurs with this fix applied.
Reproduction
The bug can be reproduced with this shell script: https://gist.github.com/istateside/e8b0c5f694424a423ae29fe9203ec895
The script bootstraps a Rush monorepo with all of the requisite contributing factors to recreate the bug:
rush.jsonis not in the root directory of the git repo)In that environment, the bug is triggered if you are in a linked worktree and make a commit, to trigger the pre-commit rush command.