Skip to content

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

@taetaetae

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions