Opencode session management & git sync

/home/jm/data/code/opencode · 4 messages · 17 parts · $0.0262 · 20,243 tokens
Created Feb 13, 02:58:59 AM · Updated Feb 13, 08:05:43 AM · 1 syncs
userFeb 13, 02:58:59 AM

Give me a description of how the session management in the opencode project @packages/opencode/ syncs the git repositories with session events in order to roll back changes if nessecary.
How does this handle multiple session in the same repoository making changes?
Are they using worktrees? Are they rolling their own repository management with git libraries or similar?

Called the list tool with the following input: {"path":"/home/jm/data/code/opencode/packages/opencode/"}

/home/jm/data/code/opencode/packages/opencode/
migration/
20260127222353_familiar_lady_ursula/
migration.sql
snapshot.json
20260211171708_add_project_commands/
migration.sql
snapshot.json
20260212005636_add_session_agent_model/
migration.sql
snapshot.json
src/
bun/
index.ts
registry.ts
bus/
bus-event.ts
global.ts
index.ts
test/
acp/
agent-interface.test.ts
event-subscription.test.ts
agent/
agent.test.ts
cli/
tui/
transcript.test.ts
github-action.test.ts
github-remote.test.ts
import.test.ts
config/
fixtures/
empty-frontmatter.md
frontmatter.md
markdown-header.md
no-frontmatter.md
weird-model-id.md
agent-color.test.ts
config.test.ts
markdown.test.ts
file/
ignore.test.ts
path-traversal.test.ts
ripgrep.test.ts
fixture/
lsp/
fake-lsp-server.js
fixture.ts
ide/
ide.test.ts
lsp/
client.test.ts
mcp/
headers.test.ts
oauth-browser.test.ts
memory/
abort-leak.test.ts
patch/
patch.test.ts
permission/
arity.test.ts
next.test.ts
plugin/
auth-override.test.ts
codex.test.ts
project/
project.test.ts
provider/
copilot/
convert-to-copilot-messages.test.ts
copilot-chat-model.test.ts
amazon-bedrock.test.ts
gitlab-duo.test.ts
provider.test.ts
transform.test.ts
question/
question.test.ts
server/
session-list.test.ts
session-select.test.ts
session/
compaction.test.ts
instruction.test.ts
llm.test.ts
message-v2.test.ts
prompt-missing-file.test.ts
prompt-special-chars.test.ts
prompt-variant.test.ts
retry.test.ts
revert-compact.test.ts
session-agent-model.test.ts
session.test.ts
skill/
discovery.test.ts
skill.test.ts
snapshot/
snapshot.test.ts
storage/
json-migration.test.ts
tool/
snapshots/
tool.test.ts.snap
fixtures/
large-image.png
models-api.json
apply_patch.test.ts
bash.test.ts
external-directory.test.ts
grep.test.ts
question.test.ts
read.test.ts
registry.test.ts
skill.test.ts
truncation.test.ts
util/
filesystem.test.ts
format.test.ts
iife.test.ts
lazy.test.ts
lock.test.ts
timeout.test.ts
wildcard.test.ts
bun.test.ts
keybind.test.ts
permission-task.test.ts
preload.ts
scheduler.test.ts
.gitignore
AGENTS.md
Dockerfile
README.md
bunfig.toml
drizzle.config.ts
package.json
parsers-config.ts
sst-env.d.ts
tsconfig.json

userFeb 13, 02:59:21 AM

Give me a description of how the session management in the opencode project @packages/opencode/ syncs the git repositories with session events in order to roll back changes if nessecary.
How does this handle multiple session in the same repoository making changes?
Are they using worktrees? Are they rolling their own repository management with git libraries or similar?

Called the list tool with the following input: {"path":"/home/jm/data/code/opencode/packages/opencode/"}

/home/jm/data/code/opencode/packages/opencode/
migration/
20260127222353_familiar_lady_ursula/
migration.sql
snapshot.json
20260211171708_add_project_commands/
migration.sql
snapshot.json
20260212005636_add_session_agent_model/
migration.sql
snapshot.json
src/
skill/
index.ts
skill.ts
worktree/
index.ts
index.ts
sql.d.ts
test/
acp/
agent-interface.test.ts
event-subscription.test.ts
agent/
agent.test.ts
cli/
tui/
transcript.test.ts
github-action.test.ts
github-remote.test.ts
import.test.ts
config/
fixtures/
empty-frontmatter.md
frontmatter.md
markdown-header.md
no-frontmatter.md
weird-model-id.md
agent-color.test.ts
config.test.ts
markdown.test.ts
file/
ignore.test.ts
path-traversal.test.ts
ripgrep.test.ts
fixture/
lsp/
fake-lsp-server.js
fixture.ts
ide/
ide.test.ts
lsp/
client.test.ts
mcp/
headers.test.ts
oauth-browser.test.ts
memory/
abort-leak.test.ts
patch/
patch.test.ts
permission/
arity.test.ts
next.test.ts
plugin/
auth-override.test.ts
codex.test.ts
project/
project.test.ts
provider/
copilot/
convert-to-copilot-messages.test.ts
copilot-chat-model.test.ts
amazon-bedrock.test.ts
gitlab-duo.test.ts
provider.test.ts
transform.test.ts
question/
question.test.ts
server/
session-list.test.ts
session-select.test.ts
session/
compaction.test.ts
instruction.test.ts
llm.test.ts
message-v2.test.ts
prompt-missing-file.test.ts
prompt-special-chars.test.ts
prompt-variant.test.ts
retry.test.ts
revert-compact.test.ts
session-agent-model.test.ts
session.test.ts
skill/
discovery.test.ts
skill.test.ts
snapshot/
snapshot.test.ts
storage/
json-migration.test.ts
tool/
snapshots/
tool.test.ts.snap
fixtures/
large-image.png
models-api.json
apply_patch.test.ts
bash.test.ts
external-directory.test.ts
grep.test.ts
question.test.ts
read.test.ts
registry.test.ts
skill.test.ts
truncation.test.ts
util/
filesystem.test.ts
format.test.ts
iife.test.ts
lazy.test.ts
lock.test.ts
timeout.test.ts
wildcard.test.ts
bun.test.ts
keybind.test.ts
permission-task.test.ts
preload.ts
scheduler.test.ts
.gitignore
AGENTS.md
Dockerfile
README.md
bunfig.toml
drizzle.config.ts
package.json
parsers-config.ts
sst-env.d.ts
tsconfig.json

assistantFeb 13, 02:59:21 AM
z-ai/glm-5 · openrouter$0.0164
The user wants to understand how session management in the opencode project syncs git repositories with session events for rollback purposes. They're specifically asking about: 1. How git repositories are synced with session events for rollback 2. How multiple sessions in the same repository making changes are handled 3. Whether they use worktrees 4. Whether they're using git libraries or rolling their own repository management I see there's a `worktree/` directory in the source, which suggests they might be using git worktrees. Let me explore the codebase to understand the session management and git integration. I should delegate this to the analyzer agent to investigate the codebase thoroughly.

I'll delegate this analysis to the analyzer agent to investigate the session management and git repository synchronization in the opencode project.

taskcompleted
Analyze session git sync
Output
task_id: ses_3ab0f8f2cffeCyb3Un2qYTyOio (for resuming to continue this task if needed)

<task_result>
Based on my comprehensive analysis of the OpenCode project, here's a detailed report on how session management syncs with git repositories for rollback purposes:

---

# OpenCode Session Management & Git Sync Architecture

## Architecture Overview

OpenCode uses a sophisticated multi-layer architecture for session management and git synchronization:

### Core Components
1. **Session System** (`src/session/`) - Manages conversation sessions, messages, and parts
2. **Snapshot System** (`src/snapshot/`) - Git-based state tracking for rollback
3. **Worktree Module** (`src/worktree/`) - Git worktree management for isolation
4. **Project Instance** (`src/project/instance.ts`) - Context provider for session operations
5. **Event Bus** (`src/bus/`) - Event-driven communication between components

---

## 1. Session Management & Git Sync

### Snapshot-Based Rollback System

The snapshot system is the heart of the rollback mechanism. It creates a **separate git repository** for tracking file states:

```typescript
// src/snapshot/index.ts - gitdir() function
function gitdir() {
  const project = Instance.project
  return path.join(Global.Path.data, "snapshot", project.id)
}
```

**Location:** `~/.opencode/data/snapshot/<project-id>/`

### Key Snapshot Operations

| Operation | Git Command Used | Purpose |
|-----------|------------------|---------|
| `track()` | `git write-tree` | Creates a git tree object representing current state |
| `patch(hash)` | `git diff --name-only` | Gets files modified since snapshot |
| `revert(patches)` | `git checkout <hash> -- <file>` | Restores individual files to snapshot state |
| `restore(snapshot)` | `git read-tree && git checkout-index` | Full restoration to snapshot state |
| `diffFull(from, to)` | `git diff` + `git show` | Computes detailed file diffs between snapshots |

### Session Event Tracking

Sessions track changes through **messa...
14,268in / 470out / 184reasoning$0.0164
assistantFeb 13, 03:02:33 AM
z-ai/glm-5 · openrouter$0.0098
The analyzer has provided a comprehensive report. Let me summarize the key findings for the user in a clear and concise way.

Summary: OpenCode Session Management & Git Sync

Based on the analyzer's comprehensive investigation, here's how the system works:

1. Git Sync for Rollback - Separate Snapshot Repository

OpenCode uses a clever dual-repository approach:

  • User's Git: The normal .git directory for version control
  • Snapshot Git: A hidden repository at ~/.opencode/data/snapshot/<project-id>/ for tracking file states

The snapshot system uses git tree objects (not commits) to track state:

  • git write-tree - Creates a tree hash representing current file state
  • git checkout <hash> -- <file> - Restores individual files
  • git read-tree + git checkout-index - Full restoration

Session messages contain step-start and step-finish parts with snapshot hashes, plus patch parts listing modified files. Rollback collects patches after the revert point and restores files using git checkout.

2. Multiple Sessions - No Worktree Isolation

Sessions do NOT use worktrees for isolation. Instead, they share the same working directory with:

  • Per-session read time tracking (src/file/time.ts) - Tracks when each session last read each file
  • Per-file write locks - Serializes concurrent writes via chained promises
  • Session busy state - Prevents concurrent operations on the same session

This is optimistic concurrency control - they rely on file modification time checks and write serialization rather than git-level locking.

3. Worktrees - For Parallel Development, Not Sessions

The src/worktree/ module creates separate git worktrees for isolated development environments (like testing branches), stored at ~/.opencode/data/worktree/<project-id>/<name>/. These are not used for session rollback - they're for creating parallel development sandboxes.

4. Git Implementation - Native Commands via Bun Shell

They use native git commands through Bun's shell syntax ($), not a JavaScript library:

// Example: Creating a snapshot
const hash = await $`git --git-dir ${git} --work-tree ${Instance.worktree} write-tree`

// Example: Restoring a file
await $`git --git-dir ${git} --work-tree ${Instance.worktree} checkout ${hash} -- ${file}`

Key Architecture Decisions

Aspect Approach
Rollback tracking Separate git repo with tree objects
Session isolation File-level locks + read time tracking
Worktrees For dev sandboxes, not sessions
Git operations Native commands via Bun shell
Event coordination Bus system for cross-component sync

The design is elegant: using git's tree objects avoids needing branches/commits in the snapshot repo, and native git commands are simpler and more reliable than JavaScript git libraries.

4,869in / 636out / 31reasoning$0.0098