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 ¶
- Variables
- type Tracker
- func (t *Tracker) Close()
- func (t *Tracker) DiffTop() (string, error)
- func (t *Tracker) Rebind(statePath string)
- func (t *Tracker) RebindWorkspace(gitDir, workTree, statePath string)
- func (t *Tracker) Redo() (changed []string, ok bool, err error)
- func (t *Tracker) Track() (bool, error)
- func (t *Tracker) Undo() (changed []string, ok bool, err error)
Constants ¶
This section is empty.
Variables ¶
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.
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 ¶
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 ¶
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 ¶
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
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 ¶
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 ¶
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.