From ae00f6e0c2a024c2e4af7efefe0bc9b9d6ad127d Mon Sep 17 00:00:00 2001 From: Roo Code Date: Mon, 28 Jul 2025 15:03:34 +0000 Subject: [PATCH] fix: remove git clean and reset --hard from checkpoint restore - Removed dangerous git clean command that was deleting untracked files - Replaced git reset --hard with a safer approach that only restores tracked files - Preserves untracked files during checkpoint restoration to prevent data loss - Fixes #6209 --- .../checkpoints/ShadowCheckpointService.ts | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/services/checkpoints/ShadowCheckpointService.ts b/src/services/checkpoints/ShadowCheckpointService.ts index be2c86852a..2d7f3862a8 100644 --- a/src/services/checkpoints/ShadowCheckpointService.ts +++ b/src/services/checkpoints/ShadowCheckpointService.ts @@ -247,8 +247,31 @@ export abstract class ShadowCheckpointService extends EventEmitter { } const start = Date.now() - await this.git.clean("f", ["-d", "-f"]) - await this.git.reset(["--hard", commitHash]) + + // Get list of files in the target commit + const filesInCommit = await this.git.raw(["ls-tree", "-r", "--name-only", commitHash]) + const files = filesInCommit + .trim() + .split("\n") + .filter((f) => f.length > 0) + + if (files.length > 0) { + // If there are files in the commit, checkout only those files + // This restores tracked files without affecting untracked files + await this.git.checkout([commitHash, "--", ...files]) + } + + // Remove files that exist in working directory but not in the target commit + const currentFiles = await this.git.raw(["ls-files"]) + const currentFilesList = currentFiles + .trim() + .split("\n") + .filter((f) => f.length > 0) + const filesToRemove = currentFilesList.filter((f) => !files.includes(f)) + + if (filesToRemove.length > 0) { + await this.git.rm(filesToRemove) + } // Remove all checkpoints after the specified commitHash. const checkpointIndex = this._checkpoints.indexOf(commitHash)