fix: improve checkpoint initialization for large repositories

- Add --ignore-errors flag to git add command to handle permission issues
- Remove timeout for initial checkpoint service initialization
- Keep timeout only for subsequent calls when service is already initializing

This fixes issue #7843 where checkpoints would fail to initialize in large
repositories due to the 15-second timeout being too short for git add operations.
This commit is contained in:
Roo Code 2025-09-10 08:04:20 +00:00
parent 7cd6520302
commit 17f19a5870
3 changed files with 18 additions and 10 deletions

View file

@ -18,7 +18,11 @@ import { CheckpointServiceOptions, RepoPerTaskCheckpointService } from "../../se
export async function getCheckpointService(
task: Task,
{ interval = 250, timeout = 15_000 }: { interval?: number; timeout?: number } = {},
{
interval = 250,
timeout = 15_000,
isInitialCall = false,
}: { interval?: number; timeout?: number; isInitialCall?: boolean } = {},
) {
if (!task.enableCheckpoints) {
return undefined
@ -67,13 +71,14 @@ export async function getCheckpointService(
}
if (task.checkpointServiceInitializing) {
await pWaitFor(
() => {
console.log("[Task#getCheckpointService] waiting for service to initialize")
return !!task.checkpointService && !!task?.checkpointService?.isInitialized
},
{ interval, timeout },
)
// If this is the initial call from initiateTaskLoop, don't apply a timeout
// to allow large repositories to complete initialization
const waitOptions = isInitialCall ? { interval } : { interval, timeout }
await pWaitFor(() => {
console.log("[Task#getCheckpointService] waiting for service to initialize")
return !!task.checkpointService && !!task?.checkpointService?.isInitialized
}, waitOptions)
if (!task?.checkpointService) {
task.enableCheckpoints = false
return undefined

View file

@ -1661,7 +1661,8 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
private async initiateTaskLoop(userContent: Anthropic.Messages.ContentBlockParam[]): Promise<void> {
// Kicks off the checkpoints initialization process in the background.
getCheckpointService(this)
// Pass isInitialCall=true to avoid timeout for large repositories
getCheckpointService(this, { isInitialCall: true })
let nextUserContent = userContent
let includeFileDetails = true

View file

@ -145,7 +145,9 @@ export abstract class ShadowCheckpointService extends EventEmitter {
private async stageAll(git: SimpleGit) {
try {
await git.add(".")
// Use --ignore-errors to continue even if some files can't be added (e.g., permission issues)
// This prevents the operation from failing in large repositories with problematic files
await git.add([".", "--ignore-errors"])
} catch (error) {
this.log(
`[${this.constructor.name}#stageAll] failed to add files to git: ${error instanceof Error ? error.message : String(error)}`,