Compare commits

...

6 Commits

Author SHA1 Message Date
A.K.M. Adib 3369da59b3 fix(core): resolve build and lint failures in worktreeService
- Fix incorrect 'fs.promises' usage
- Provide missing 'projectRoot' to 'isGeminiWorktree'
- Replace 'any' with specific types and type guards to satisfy ESLint
- Update tests to match implementation changes
2026-05-04 16:00:41 -04:00
Adib234 7f19202892 Update packages/core/src/services/worktreeService.test.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-04 15:48:03 -04:00
Adib234 e5982253fe Update packages/core/src/services/worktreeService.test.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-04 15:47:56 -04:00
Adib234 e3dcd2a193 Update packages/core/src/services/worktreeService.test.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-04 15:47:48 -04:00
Adib234 333344c5f0 Update packages/core/src/services/worktreeService.ts
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2026-05-04 15:47:39 -04:00
A.K.M. Adib d4bd0e0f61 feat(core): allow reusing existing worktrees with --worktree flag 2026-05-04 15:21:50 -04:00
3 changed files with 54 additions and 3 deletions
+17 -2
View File
@@ -80,8 +80,23 @@ manually remove the worktree if you no longer need it.
## Resuming work in a Git worktree
To resume a session in a worktree, navigate to the worktree directory and start
Gemini CLI with the `--resume` flag and the session ID:
To resume a session in an existing worktree, you can simply run Gemini with the
same `--worktree` (`-w`) name:
```bash
gemini --worktree feature-search
```
Alternatively, you can navigate to the worktree directory and start Gemini
directly:
```bash
cd .gemini/worktrees/feature-search
gemini
```
To resume a specific previous chat session within that worktree, use the
`--resume` flag and the session ID:
```bash
cd .gemini/worktrees/feature-search
@@ -85,7 +85,8 @@ describe('worktree utilities', () => {
});
describe('createWorktree', () => {
it('should execute git worktree add with correct branch and path', async () => {
it('should execute git worktree add with correct branch and path if it does not exist', async () => {
vi.mocked(fs.stat).mockRejectedValue({ code: 'ENOENT' });
vi.mocked(execa).mockResolvedValue({ stdout: '' } as never);
const resultPath = await createWorktree(projectRoot, worktreeName);
@@ -98,7 +99,19 @@ describe('worktree utilities', () => {
);
});
it('should return existing path and not call git if it already exists', async () => {
vi.mocked(fs.stat).mockResolvedValue({
isDirectory: () => true,
} as never);
const resultPath = await createWorktree(projectRoot, worktreeName);
expect(resultPath).toBe(expectedPath);
expect(execa).not.toHaveBeenCalled();
});
it('should throw an error if git worktree add fails', async () => {
vi.mocked(fs.stat).mockRejectedValue({ code: 'ENOENT' });
vi.mocked(execa).mockRejectedValue(new Error('git failed'));
await expect(createWorktree(projectRoot, worktreeName)).rejects.toThrow(
@@ -120,6 +120,29 @@ export async function createWorktree(
name: string,
): Promise<string> {
const worktreePath = getWorktreePath(projectRoot, name);
const worktreesBaseDir = path.join(projectRoot, '.gemini', 'worktrees');
const relative = path.relative(worktreesBaseDir, worktreePath);
if (relative.startsWith('..') || path.isAbsolute(relative)) {
throw new Error('Invalid worktree name');
}
try {
const stats = await fs.stat(worktreePath);
if (stats.isDirectory() && isGeminiWorktree(worktreePath, projectRoot)) {
return worktreePath;
}
} catch (err: unknown) {
if (
err &&
typeof err === 'object' &&
'code' in err &&
err.code !== 'ENOENT'
) {
throw err;
}
}
const branchName = `worktree-${name}`;
await execa('git', ['worktree', 'add', worktreePath, '-b', branchName], {