Skip to content

[Bug] "Modified Files" panel does not clear after git commit #11856

Closed

Description

@taetaetae

Description

After committing files with git commit, the "Modified Files" panel in the sidebar still shows those files as modified. Users expect committed files to be removed from this list.

Steps to Reproduce

  1. Start OpenCode in a git repository
  2. Make changes to files using OpenCode (AI edits)
  3. Observe "Modified Files" panel shows the changed files
  4. Run git add . && git commit -m "commit message" (either via OpenCode bash tool or external terminal)
  5. Observe "Modified Files" panel still shows the same files

Expected Behavior

Files that have been committed should be removed from the "Modified Files" list, since they are no longer "modified" from git's perspective.

Actual Behavior

Committed files remain in the "Modified Files" list until the session ends or OpenCode is restarted.

Root Cause Analysis

After investigating the codebase, I found that:

  1. session_diff is computed from OpenCode's internal snapshot system, not the user's git repository

    • Internal snapshots are stored in ~/.local/share/opencode/snapshot/{project-id}/
    • SessionSummary.summarize() computes diff between step-start and step-finish snapshot hashes
  2. No git commit event detection exists

    • FileWatcher only watches .git/HEAD for branch changes (packages/opencode/src/file/watcher.ts)
    • Vcs namespace only handles BranchUpdated events (packages/opencode/src/project/vcs.ts)
    • There is no handler that detects when a git commit happens
  3. session_diff is never refreshed after external git operations

    • Once computed, session_diff persists until session ends
    • User's git commit does not trigger any recalculation

Relevant Code

packages/opencode/src/session/summary.ts:

async function summarizeSession(input: { sessionID: string; messages: MessageV2.WithParts[] }) {
  const diffs = await computeDiff({ messages: input.messages })
  // ...
  await Storage.write(["session_diff", input.sessionID], diffs)
  Bus.publish(Session.Event.Diff, { sessionID: input.sessionID, diff: diffs })
}

packages/opencode/src/project/vcs.ts:

// Only watches for branch changes, not commits
const unsubscribe = Bus.subscribe(FileWatcher.Event.Updated, async (evt) => {
  if (evt.properties.file.endsWith("HEAD")) return
  // ... only handles branch changes
})

Proposed Solution

Option A: Detect git commit and filter session_diff

  1. Watch for .git/index or .git/refs/heads/* changes in FileWatcher
  2. On commit detection, filter session_diff to only include files that are still uncommitted
  3. Publish updated diff to UI

Option B: Periodically refresh session_diff

  1. After bash tool executions that might be git commands, refresh session_diff
  2. Compare against current git diff --name-only HEAD to filter committed files

Environment

  • OS: macOS
  • OpenCode version: latest from dev branch
  • Commit: 7b3c82d95c10e7ec364d8b970209dadfdb43e4dc

Related Issues

Activity

  1. github-actions commented on Feb 2, 2026

    @github-actions
    Contributor

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

    Feel free to ignore if these don't address your specific case.

  2. taetaetae commented on Feb 2, 2026

    @taetaetae
    Author

    Thanks for the duplicate check!

    I reviewed #10920 and it describes the same symptom (changes tab not updating after commit), but from the Desktop/Web perspective.

    This issue provides:

    • Root cause analysis with specific code references (session/summary.ts, project/vcs.ts, snapshot/index.ts)
    • Two proposed solutions (Option A: git commit detection, Option B: periodic refresh)
    • TUI-specific context (though the underlying issue affects both Desktop and TUI)

    The root cause is the same: session_diff is computed from OpenCode's internal snapshot system and never refreshed after external git operations.

    I'm happy to work on a PR if the maintainers agree with one of the proposed approaches. The fix would likely benefit both #10920 (Desktop) and this issue (TUI) since they share the same backend code.

    cc @adamdotdevin @rekram1-node

  3. azkore commented on Feb 19, 2026

    @azkore

    For anyone who doesn't want to wait for a proper fix and would like to clean up the sidebar right now — here's a workaround script (AI-assisted) that I've been using:

    https://gist.github.com/azkore/807e5736aad043ad5d442acb686140cd

    How it works: As described in the issue, the sidebar is driven by snapshot tree hashes stored in step-start/step-finish parts, not by actual git state. The script clears those stale snapshot references and injects a fresh baseline (HEAD tree → current working tree) that computeDiff treats as native. After running it, the sidebar reflects real uncommitted changes — and stays correct through subsequent prompts because the injected step-start anchors from to HEAD.

    Heads up: This directly mutates the OpenCode DB and snapshot data. Works great for me but please back up your DB (~/.local/share/opencode/opencode.db) before trying it. Best run while the session is idle.

    Usage: oc-refresh-diff <session-id>

  4. github-actions commented on Apr 21, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions