snapshot

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package snapshot captures workspace file checkpoints into a shadow git repository and restores them on demand, powering /undo.

The approach follows opencode's shadow-repo model: a standalone git --git-dir (outside the user's project) with the workspace as its --work-tree. Snapshots are full-workspace tree objects (git write-tree), so they capture changes from any source — write/edit tools, bash (sed -i), even manual edits — and never touch the user's own .git state. git's content addressing dedups unchanged blobs across snapshots.

Index

Constants

This section is empty.

Variables

View Source
var ErrSnapshotExpired = errors.New("snapshot expired or unavailable")

ErrSnapshotExpired means the popped snapshot's tree object is gone — the background gc pruned it (objects older than the prune window are unreachable and get collected). The undo point is unrecoverable; callers report it and move on. The expired hash is already dropped from the stack.

View Source
var ErrTrackerClosed = errors.New("snapshot tracker closed")

ErrTrackerClosed means a snapshot operation was attempted after Close.

Functions

This section is empty.

Types

type Tracker

type Tracker struct {
	// contains filtered or unexported fields
}

Tracker snapshots the workspace into a shadow git repo and reverts to those snapshots. Snapshots are turn-scoped: the session calls Track at each turn boundary, pushing the pre-turn tree hash onto stack (turns that change nothing are skipped — identical content yields an identical write-tree hash). Undo pops the top hash and reverts the workspace to it, undoing the most recent turn's file changes.

func New

func New(gitDir, workTree, statePath string) *Tracker

New returns a Tracker writing snapshots to gitDir for the given workspace. statePath persists the undo stack so it survives a restart/resume; pass "" to keep the stack in memory only. An existing statePath is loaded immediately.

func (*Tracker) Close

func (t *Tracker) Close()

Close waits for the tracker's background maintenance to finish.

Snapshot operations are otherwise synchronous, but ensureInit starts a best-effort git gc in the background. Tests and runtime shutdown call Close so temp-dir cleanup and process teardown never race that git process.

func (*Tracker) DiffTop

func (t *Tracker) DiffTop() (string, error)

DiffTop returns a numstat diff of the top undo snapshot against the current workspace — what /undo would roll back. Empty when the stack is empty. Stages the workspace first so untracked (newly created) files appear in the diff.

func (*Tracker) Rebind

func (t *Tracker) Rebind(statePath string)

Rebind repoints the tracker at a new session's sidecar: it drops the current in-memory stack and loads whatever was persisted for statePath (empty when that session has none yet). Called on session switch/new, where the prior session's undo points no longer apply. Shadow objects stay on disk.

func (*Tracker) RebindWorkspace added in v0.3.0

func (t *Tracker) RebindWorkspace(gitDir, workTree, statePath string)

RebindWorkspace repoints the tracker at a different workspace — both the shadow gitDir and the workTree — along with its sidecar, then reloads the persisted stack. Unlike Rebind (which only swaps statePath for a same-cwd session switch), this is for worktree enter/exit where the whole workspace moves. The instance is reused so callers needn't juggle Close on the old one; initialized is cleared so the next Track lazily inits the new shadow repo. The new shadow repo is not background-gc'd (gcOnce already fired) — worktree shadow repos are short-lived and removed with the worktree, so that's fine.

func (*Tracker) Redo

func (t *Tracker) Redo() (changed []string, ok bool, err error)

Redo re-applies the most recently undone change, returning the workspace to the state captured just before that Undo. ok=false when there is nothing to redo (no prior Undo, or a new edit invalidated the redo branch). The redo stack is memory-only, so its hashes are recent and never gc-pruned mid-life.

func (*Tracker) Track

func (t *Tracker) Track() (bool, error)

Track snapshots the current workspace as the start point of the next turn. Returns changed=false when the workspace is byte-identical to the last snapshot (no new undo point recorded). Best-effort by contract: callers ignore the error so a snapshot failure never blocks a turn.

func (*Tracker) Undo

func (t *Tracker) Undo() (changed []string, ok bool, err error)

Undo reverts the workspace to the most recent turn-start snapshot. ok=false means there is nothing to undo. changed lists the restored/removed paths.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL