Skip to content

Commit 5bcb6b6

Browse files
fix(core): add explicit git identity env vars to prevent sandbox checkpointing error (#19775)
Co-authored-by: David Pierce <davidapierce@google.com>
1 parent b238a45 commit 5bcb6b6

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

packages/core/src/services/gitService.test.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import {
1313
afterEach,
1414
type Mock,
1515
} from 'vitest';
16-
import { GitService } from './gitService.js';
16+
import {
17+
GitService,
18+
SHADOW_REPO_AUTHOR_NAME,
19+
SHADOW_REPO_AUTHOR_EMAIL,
20+
} from './gitService.js';
1721
import { Storage } from '../config/storage.js';
1822
import * as path from 'node:path';
1923
import * as fs from 'node:fs/promises';
@@ -192,8 +196,7 @@ describe('GitService', () => {
192196
const service = new GitService(projectRoot, storage);
193197
await service.setupShadowGitRepository();
194198

195-
const expectedConfigContent =
196-
'[user]\n name = Gemini CLI\n email = gemini-cli@google.com\n[commit]\n gpgsign = false\n';
199+
const expectedConfigContent = `[user]\n name = ${SHADOW_REPO_AUTHOR_NAME}\n email = ${SHADOW_REPO_AUTHOR_EMAIL}\n[commit]\n gpgsign = false\n`;
197200
const actualConfigContent = await fs.readFile(gitConfigPath, 'utf-8');
198201
expect(actualConfigContent).toBe(expectedConfigContent);
199202
});
@@ -288,6 +291,10 @@ describe('GitService', () => {
288291
expect.objectContaining({
289292
GIT_CONFIG_GLOBAL: gitConfigPath,
290293
GIT_CONFIG_SYSTEM: path.join(repoDir, '.gitconfig_system_empty'),
294+
GIT_AUTHOR_NAME: SHADOW_REPO_AUTHOR_NAME,
295+
GIT_AUTHOR_EMAIL: SHADOW_REPO_AUTHOR_EMAIL,
296+
GIT_COMMITTER_NAME: SHADOW_REPO_AUTHOR_NAME,
297+
GIT_COMMITTER_EMAIL: SHADOW_REPO_AUTHOR_EMAIL,
291298
}),
292299
);
293300

packages/core/src/services/gitService.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import { simpleGit, CheckRepoActions, type SimpleGit } from 'simple-git';
1212
import type { Storage } from '../config/storage.js';
1313
import { debugLogger } from '../utils/debugLogger.js';
1414

15+
export const SHADOW_REPO_AUTHOR_NAME = 'Gemini CLI';
16+
export const SHADOW_REPO_AUTHOR_EMAIL = 'gemini-cli@google.com';
17+
1518
export class GitService {
1619
private projectRoot: string;
1720
private storage: Storage;
@@ -58,6 +61,13 @@ export class GitService {
5861
// Prevent git from using the user's global git config.
5962
GIT_CONFIG_GLOBAL: gitConfigPath,
6063
GIT_CONFIG_SYSTEM: systemConfigPath,
64+
// Explicitly provide identity to prevent "Author identity unknown" errors
65+
// inside sandboxed environments like Docker where the gitconfig might not
66+
// be picked up properly.
67+
GIT_AUTHOR_NAME: SHADOW_REPO_AUTHOR_NAME,
68+
GIT_AUTHOR_EMAIL: SHADOW_REPO_AUTHOR_EMAIL,
69+
GIT_COMMITTER_NAME: SHADOW_REPO_AUTHOR_NAME,
70+
GIT_COMMITTER_EMAIL: SHADOW_REPO_AUTHOR_EMAIL,
6171
};
6272
}
6373

@@ -73,8 +83,7 @@ export class GitService {
7383

7484
// We don't want to inherit the user's name, email, or gpg signing
7585
// preferences for the shadow repository, so we create a dedicated gitconfig.
76-
const gitConfigContent =
77-
'[user]\n name = Gemini CLI\n email = gemini-cli@google.com\n[commit]\n gpgsign = false\n';
86+
const gitConfigContent = `[user]\n name = ${SHADOW_REPO_AUTHOR_NAME}\n email = ${SHADOW_REPO_AUTHOR_EMAIL}\n[commit]\n gpgsign = false\n`;
7887
await fs.writeFile(gitConfigPath, gitConfigContent);
7988

8089
const shadowRepoEnv = this.getShadowRepoEnv(repoDir);

0 commit comments

Comments
 (0)