Repository navigation
fix(server): projects no longer show another repo's Git state when T3 starts inside a Git command - #28795
fix(server): projects no longer show another repo's Git state when T3 starts inside a Git command#28795only21mil wants to merge 5 commits into
Conversation
…rited A T3 server started from a Git hook or `git rebase --exec` in a linked worktree inherits GIT_DIR and GIT_INDEX_FILE, and every project's Git commands then read and write that worktree instead of the project. gitProcessEnv builds the Git child environment at the three Git spawn sites (GitVcsDriverCore, VcsProcess, RepositoryIdentityResolver): it unsets inherited repository selectors, then applies the caller's env, so deliberate private-index and bare-repository overrides still win. The nested-repository probe from pingdotgg#12181 no longer needs an env of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ApprovabilityVerdict: Approved at Macroscope's review found this PR approvable — Git commands now ignore inherited repository selectors so each project uses its own repository rather than the server’s launch context. Explicit command overrides and existing bare-repository safeguards are preserved. You can add or adjust custom eligibility rules. Learn more. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the
Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
Note Written by Merged current main into this branch again without rebasing (
No other behavior changes. The diff against main is still seven files. Blacksmith Earlier history: merged main once before ( |
# Conflicts: # apps/server/src/vcs/GitVcsDriver.test.ts # apps/server/src/vcs/GitVcsDriver.ts # apps/server/src/vcs/GitVcsDriverCore.ts
Git child processes keep main's LANGUAGE=C for git commands in VcsProcess, now passed through gitProcessEnv alongside the caller's env. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Note 🤖 Opus 5.5 replying on behalf of Victor. Merged current
The three "ignores repository selectors inherited by the server" tests still fail with main's server files and pass on the merge. Fresh captures from the merged code, with the server started under another repository's
|








Problem
When T3 Code starts inside a Git command, every project's Git commands can run against the wrong repository. In a linked worktree, Git hooks and
git rebase --execexport an absoluteGIT_DIR(commit hooks also exportGIT_INDEX_FILE). A T3 server started from there passes those variables to all of its Git subprocesses. Every project then shows that worktree's branch, status and repository identity, and checkpoints are written into it.Reproduction: make two repositories,
demo-projectonfeature/demo-projectandinherited-otheronwrong-repository-branch. Start the server withGIT_DIR=<inherited-other>/.git, then adddemo-project. The sidebar labels itexample/inherited-otherand the branch picker showswrong-repository-branch.Change
gitProcessEnvinVcsProcess.tsbuilds the environment for a Git child process. It first unsets the repository selectors the server inherited (GIT_DIR,GIT_WORK_TREE,GIT_COMMON_DIR,GIT_INDEX_FILE,GIT_OBJECT_DIRECTORY,GIT_ALTERNATE_OBJECT_DIRECTORIES, the same list #12181 clears, plusGIT_CEILING_DIRECTORIES), then applies the caller's env, then the existingsafe.bareRepository=explicitconfig from #20440. Selectors a caller sets on purpose still win, such as a checkpoint's privateGIT_INDEX_FILEor worktree removal's boundGIT_DIR.It is used at the three places that spawn Git and already added the bare-repository config:
GitVcsDriverCore,VcsProcess(checkpoints, file listing, source-control CLIs) andRepositoryIdentityResolver.The checkpoint commit env no longer spreads
process.envitself, because that spread re-added the inherited selectors as if the caller had set them. #12181's nested-repository probe no longer needs its own cleared env, so that block is removed.Other
GIT_*variables are left alone, including config, auth, SSH and locale. Provider CLIs and terminals still inherit the server's environment unchanged.Scope and approval
This is a small, focused fix for an obvious bug: Git commands for one project run against a different repository. It uses the CONTRIBUTING exception for obvious bugs, with no issue or discussion. It extends the narrow fix in #12181 to the shared Git spawn paths and clears only the variables #12181 clears.
Maintainers to confirm: the scope covers Git subprocesses only. Provider and terminal environments are unchanged.
Verification
Tests, on macOS with git 2.56. Each fails on
mainand passes on this branch:GitVcsDriverCore.test.ts"ignores repository selectors inherited by the server". Onmain, status reports the other repo's branch:expected 'other-repository' to equal 'main'. It also covers a privateGIT_INDEX_FILEcommit context and an explicit bareGIT_DIR.GitVcsDriver.test.ts"checkpoint capture ignores repository selectors inherited by the server" extends the fix(server): checkpoint workspaces with empty nested repositories #12181 test. The inheritedGIT_DIR,GIT_WORK_TREEandGIT_INDEX_FILEnow point at a second repository. Onmain, the checkpoint ref is written there instead. It also checks the second repository is untouched, the fix(server): checkpoint workspaces with empty nested repositories #12181 nested-HEAD exclusion still holds, and an explicit bareGIT_DIRstill works on this path.RepositoryIdentityResolver.test.ts"ignores repository selectors inherited by the server". Onmainit fails withexpected 'github.com/t3tools/other' to be 'github.com/t3tools/t3code'.Runs:
vp run check:changed 1d626d02d95f9a2343553f6498037ee82290d304: format, lint, knip and typecheck pass. Tests: 321 passed, 4 failed.vp test runonsrc/vcs,src/sourceControl,src/workspace,src/checkpointingand the resolver test: 460 passed, 4 failed.mainon this machine. Three come from a globalurl.insteadOfrewrite in this machine's Git config, and one from macOS/varvs/private/vartemp paths. WithGIT_CONFIG_GLOBAL=/dev/nulland a resolvedTMPDIR, they pass.Which Git contexts set these, checked with a hook that prints them (git 2.56): in a linked worktree,
pre-commit,post-commit,post-checkoutandgit rebase --execexport an absoluteGIT_DIR, and commit hooks an absoluteGIT_INDEX_FILE. In a primary checkout, commit hooks export only a relativeGIT_INDEX_FILE.UI, on each client. I ran the dev server with
GIT_DIRset to the second repository and a fresh, isolated database, once onmainand once on this branch. Every client shows the same syntheticdemo-project(a free replay turn). Machine names are blanked out.Web, before on
main: the sidebar and thread details show the other repository's name and branch.Web, after on this branch: the project shows its own name and
feature/demo-project.Desktop, iOS and Android, with the same server runs:
main)Not checked
gitConfigEnv, but it was not run on Windows.Prior PRs
Generated with Claude Opus 5.5 and GPT-6.1 Terra and GPT-6.1 Sol in T3 Code Nightly