From 5bcb6b619dcafaab25bd2f03dca7da989ee44718 Mon Sep 17 00:00:00 2001 From: "MD. MOHIBUR RAHMAN" <35300157+mrpmohiburrahman@users.noreply.github.com> Date: Thu, 9 Apr 2026 23:24:04 +0600 Subject: [PATCH] fix(core): add explicit git identity env vars to prevent sandbox checkpointing error (#19775) Co-authored-by: David Pierce --- packages/core/src/services/gitService.test.ts | 13 ++++++++++--- packages/core/src/services/gitService.ts | 13 +++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/core/src/services/gitService.test.ts b/packages/core/src/services/gitService.test.ts index 095b8bc56f..f5213ac6ea 100644 --- a/packages/core/src/services/gitService.test.ts +++ b/packages/core/src/services/gitService.test.ts @@ -13,7 +13,11 @@ import { afterEach, type Mock, } from 'vitest'; -import { GitService } from './gitService.js'; +import { + GitService, + SHADOW_REPO_AUTHOR_NAME, + SHADOW_REPO_AUTHOR_EMAIL, +} from './gitService.js'; import { Storage } from '../config/storage.js'; import * as path from 'node:path'; import * as fs from 'node:fs/promises'; @@ -192,8 +196,7 @@ describe('GitService', () => { const service = new GitService(projectRoot, storage); await service.setupShadowGitRepository(); - const expectedConfigContent = - '[user]\n name = Gemini CLI\n email = gemini-cli@google.com\n[commit]\n gpgsign = false\n'; + const expectedConfigContent = `[user]\n name = ${SHADOW_REPO_AUTHOR_NAME}\n email = ${SHADOW_REPO_AUTHOR_EMAIL}\n[commit]\n gpgsign = false\n`; const actualConfigContent = await fs.readFile(gitConfigPath, 'utf-8'); expect(actualConfigContent).toBe(expectedConfigContent); }); @@ -288,6 +291,10 @@ describe('GitService', () => { expect.objectContaining({ GIT_CONFIG_GLOBAL: gitConfigPath, GIT_CONFIG_SYSTEM: path.join(repoDir, '.gitconfig_system_empty'), + GIT_AUTHOR_NAME: SHADOW_REPO_AUTHOR_NAME, + GIT_AUTHOR_EMAIL: SHADOW_REPO_AUTHOR_EMAIL, + GIT_COMMITTER_NAME: SHADOW_REPO_AUTHOR_NAME, + GIT_COMMITTER_EMAIL: SHADOW_REPO_AUTHOR_EMAIL, }), ); diff --git a/packages/core/src/services/gitService.ts b/packages/core/src/services/gitService.ts index 3c6252196d..f923dc6164 100644 --- a/packages/core/src/services/gitService.ts +++ b/packages/core/src/services/gitService.ts @@ -12,6 +12,9 @@ import { simpleGit, CheckRepoActions, type SimpleGit } from 'simple-git'; import type { Storage } from '../config/storage.js'; import { debugLogger } from '../utils/debugLogger.js'; +export const SHADOW_REPO_AUTHOR_NAME = 'Gemini CLI'; +export const SHADOW_REPO_AUTHOR_EMAIL = 'gemini-cli@google.com'; + export class GitService { private projectRoot: string; private storage: Storage; @@ -58,6 +61,13 @@ export class GitService { // Prevent git from using the user's global git config. GIT_CONFIG_GLOBAL: gitConfigPath, GIT_CONFIG_SYSTEM: systemConfigPath, + // Explicitly provide identity to prevent "Author identity unknown" errors + // inside sandboxed environments like Docker where the gitconfig might not + // be picked up properly. + GIT_AUTHOR_NAME: SHADOW_REPO_AUTHOR_NAME, + GIT_AUTHOR_EMAIL: SHADOW_REPO_AUTHOR_EMAIL, + GIT_COMMITTER_NAME: SHADOW_REPO_AUTHOR_NAME, + GIT_COMMITTER_EMAIL: SHADOW_REPO_AUTHOR_EMAIL, }; } @@ -73,8 +83,7 @@ export class GitService { // We don't want to inherit the user's name, email, or gpg signing // preferences for the shadow repository, so we create a dedicated gitconfig. - const gitConfigContent = - '[user]\n name = Gemini CLI\n email = gemini-cli@google.com\n[commit]\n gpgsign = false\n'; + const gitConfigContent = `[user]\n name = ${SHADOW_REPO_AUTHOR_NAME}\n email = ${SHADOW_REPO_AUTHOR_EMAIL}\n[commit]\n gpgsign = false\n`; await fs.writeFile(gitConfigPath, gitConfigContent); const shadowRepoEnv = this.getShadowRepoEnv(repoDir);