mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: prevent shadow git from inheriting global init.templateDir
This commit is contained in:
parent
618aa6652b
commit
1ea52d3141
2 changed files with 54 additions and 2 deletions
|
|
@ -39,7 +39,8 @@ function createSanitizedGit(baseDir: string): SimpleGit {
|
|||
key === "GIT_INDEX_FILE" ||
|
||||
key === "GIT_OBJECT_DIRECTORY" ||
|
||||
key === "GIT_ALTERNATE_OBJECT_DIRECTORIES" ||
|
||||
key === "GIT_CEILING_DIRECTORIES"
|
||||
key === "GIT_CEILING_DIRECTORIES" ||
|
||||
key === "GIT_TEMPLATE_DIR"
|
||||
) {
|
||||
removedVars.push(`${key}=${value}`)
|
||||
continue
|
||||
|
|
@ -172,7 +173,9 @@ export abstract class ShadowCheckpointService extends EventEmitter {
|
|||
this.baseHash = await git.revparse(["HEAD"])
|
||||
} else {
|
||||
this.log(`[${this.constructor.name}#initShadowGit] creating shadow git repo at ${this.checkpointsDir}`)
|
||||
await git.init()
|
||||
// Use --template= to prevent inheriting user's global init.templateDir configuration
|
||||
// This ensures no unwanted hooks or templates are copied to the shadow repository
|
||||
await git.init(["--template="])
|
||||
await git.addConfig("core.worktree", this.workspaceDir) // Sets the working tree to the current workspace.
|
||||
await git.addConfig("commit.gpgSign", "false") // Disable commit signing for shadow repo.
|
||||
await git.addConfig("user.name", "Roo Code")
|
||||
|
|
|
|||
|
|
@ -824,6 +824,55 @@ describe.each([[RepoPerTaskCheckpointService, "RepoPerTaskCheckpointService"]])(
|
|||
expect(await fs.readFile(testFile, "utf-8")).toBe("Hello, world!")
|
||||
})
|
||||
|
||||
it("does not apply git templates when initializing shadow repo", async () => {
|
||||
// This test verifies that git init uses --template="" and GIT_TEMPLATE_DIR
|
||||
// is stripped, preventing system/user git hooks from leaking into the shadow repo.
|
||||
const templateDir = path.join(tmpDir, `git-template-${Date.now()}`)
|
||||
const hooksDir = path.join(templateDir, "hooks")
|
||||
await fs.mkdir(hooksDir, { recursive: true })
|
||||
await fs.writeFile(path.join(hooksDir, "pre-commit"), "#!/bin/sh\nexit 1", { mode: 0o755 })
|
||||
|
||||
const testShadowDir = path.join(tmpDir, `shadow-template-test-${Date.now()}`)
|
||||
const testWorkspaceDir = path.join(tmpDir, `workspace-template-test-${Date.now()}`)
|
||||
await initWorkspaceRepo({ workspaceDir: testWorkspaceDir })
|
||||
|
||||
const originalTemplateDir = process.env.GIT_TEMPLATE_DIR
|
||||
process.env.GIT_TEMPLATE_DIR = templateDir
|
||||
|
||||
try {
|
||||
const testService = await klass.create({
|
||||
taskId: `test-template-${Date.now()}`,
|
||||
shadowDir: testShadowDir,
|
||||
workspaceDir: testWorkspaceDir,
|
||||
log: () => {},
|
||||
})
|
||||
await testService.initShadowGit()
|
||||
|
||||
// Verify no hooks were copied from the template
|
||||
const shadowHooksDir = path.join(testShadowDir, ".git", "hooks")
|
||||
let hookFiles: string[] = []
|
||||
|
||||
try {
|
||||
hookFiles = await fs.readdir(shadowHooksDir)
|
||||
} catch {
|
||||
// hooks dir may not exist at all, which is fine
|
||||
}
|
||||
|
||||
// The pre-commit hook from the template should NOT be present
|
||||
expect(hookFiles).not.toContain("pre-commit")
|
||||
} finally {
|
||||
if (originalTemplateDir !== undefined) {
|
||||
process.env.GIT_TEMPLATE_DIR = originalTemplateDir
|
||||
} else {
|
||||
delete process.env.GIT_TEMPLATE_DIR
|
||||
}
|
||||
|
||||
await fs.rm(testShadowDir, { recursive: true, force: true })
|
||||
await fs.rm(testWorkspaceDir, { recursive: true, force: true })
|
||||
await fs.rm(templateDir, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it("isolates checkpoint operations from GIT_DIR environment variable", async () => {
|
||||
// This test verifies the fix for the issue where GIT_DIR environment variable
|
||||
// causes checkpoint commits to go to the wrong repository.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue