Skip to content

[BUG] Snapshot module ignores 'watcher.ignore' config, causing excessive disk usage and performance degradation #8887

Closed

Description

@vianb

Description

The Snapshot module (packages/opencode/src/snapshot/index.ts), which is responsible for tracking file changes and generating session diffs, completely ignores the watcher.ignore configuration settings.

When Snapshot.track() is called, it executes:

await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`...

This command blindly adds all files in the workspace to the internal snapshot repository, regardless of whether they are listed in watcher.ignore or standard ignore patterns.

Impact

  1. Disk Space Exhaustion: If a project contains large ignored directories (e.g., data/, venv/, build artifacts), OpenCode tracks them internally. This leads to massive files accumulating in ~/.local/share/opencode/storage/session_diff/ and ~/.local/share/opencode/snapshot/.
  2. Performance degradation: High CPU and I/O usage during every agent step as git add processes large ignored files.
  3. Privacy/Security: Files explicitly ignored by the user (potentially containing sensitive data) are inadvertently tracked in the internal snapshot history.

Reproduction

  1. Create a project with a large directory (e.g., data/ with 1GB+ files).
  2. Configure opencode.json to ignore it:
    { "watcher": { "ignore": ["data/**"] } }
  3. Start a session and make the agent perform a task.
  4. Observe ~/.local/share/opencode/snapshot/ growing and git processes consuming CPU, despite the ignore rule.

Code Location

packages/opencode/src/snapshot/index.ts

Proposed Fix (Patch)

The following patch ensures that Snapshot.track() respects both standard ignore patterns and user-defined watcher.ignore rules by updating the internal git repository's info/exclude and cleaning the index.

--- packages/opencode/src/snapshot/index.ts.orig
+++ packages/opencode/src/snapshot/index.ts
@@ -6,6 +6,7 @@
 import z from "zod"
 import { Config } from "../config/config"
 import { Instance } from "../project/instance"
+import { FileIgnore } from "../file/ignore"
 
 export namespace Snapshot {
   const log = Log.create({ service: "snapshot" })
@@ -28,6 +29,31 @@
       await $`git --git-dir ${git} config core.autocrlf false`.quiet().nothrow()
       log.info("initialized")
     }
+
+    const ignores = [...FileIgnore.PATTERNS, ...(cfg.watcher?.ignore ?? [])]
+    const infoDir = path.join(git, "info")
+    await fs.mkdir(infoDir, { recursive: true })
+    await Bun.write(path.join(infoDir, "exclude"), ignores.join("\n"))
+
+    const ignoredFiles = await $`git --git-dir ${git} --work-tree ${Instance.worktree} ls-files -i --exclude-standard`
+      .quiet()
+      .cwd(Instance.directory)
+      .nothrow()
+      .text()
+
+    if (ignoredFiles.trim()) {
+      await $`git --git-dir ${git} --work-tree ${Instance.worktree} ls-files -i --exclude-standard -z`
+        .quiet()
+        .cwd(Instance.directory)
+        .nothrow()
+        .pipe(
+          $`xargs -0 git --git-dir ${git} --work-tree ${Instance.worktree} rm --cached -r --ignore-unmatch`
+            .quiet()
+            .cwd(Instance.directory)
+            .nothrow(),
+        )
+    }
+
     await $`git --git-dir ${git} --work-tree ${Instance.worktree} add .`.quiet().cwd(Instance.directory).nothrow()
     const hash = await $`git --git-dir ${git} --work-tree ${Instance.worktree} write-tree`
       .quiet()

Activity

  1. added
    perfIndicates a performance issue or need for optimization
    on Jan 16, 2026
  2. github-actions commented on Jan 16, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    • What is the point of watcher.ignore #6740: What is the point of watcher.ignore - User reports that files in watcher.ignore are still being accessed and tracked despite the configuration, showing console output with files marked as 'should have ignored'
  3. thdxr commented on Mar 25, 2026

    @thdxr
    Member

    This should be fixed by commit 0a80ef4 which adds a 2MB file size limit for snapshotting. Large files are now automatically excluded from snapshots, addressing the performance issues with large files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

perfIndicates a performance issue or need for optimization

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions