filediff

package
v0.21.1 Latest Latest
Warning

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

Go to latest
Published: Aug 26, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package filediff produces unified-diff text for files changed by an agent turn, using `git diff` against the workspace PVC's HEAD commit.

US-65.3 (opencode adapter) prototype — resolves design/0049 §10 open question: opencode's `session.diff` SSE event carries only the list of file paths (`properties.files: [...]`), not diff hunks. Producing the `Patch string` payload that pkg/session.FileDiff requires means running `git diff` against the changed paths in the workspace git repo.

Prerequisite: /workspace MUST be a git repo. Workspaces today start with whatever is on the PVC (possibly empty); a separate US-65.3 follow-up initializes /workspace as a git repo on workspace creation and commits after each agent turn so the next turn's diff has a base.

This package is the thin pure-Go shell around `git diff` — it does not own the commit cadence, the repo initialization, or the translation to pkg/session.FileDiff. Those are the adapter's job.

Index

Constants

View Source
const MaxDiffBytes = 1 << 20 // 1 MiB

MaxDiffBytes bounds the size of one file's unified-diff output. A 1 MiB cap covers realistic source-file changes (a 10k-line file fully rewritten is ~600 KB of diff) while preventing a runaway tool that rewrites node_modules from blowing up the event stream. Files whose diff exceeds this are returned with Patch="" and Truncated=true (signaled by git diff's exit code 0 + output containing the ".../.../... file too large" marker — see ResolveLargeFiles).

Variables

This section is empty.

Functions

This section is empty.

Types

type Diff

type Diff struct {
	Path  string
	Patch string
}

Diff is the unified-diff text for one file's changes against HEAD. Path is repo-relative (e.g. "src/foo.go"); Patch is the unified-diff text (empty if the file is binary, missing, or exceeded MaxDiffBytes).

type Producer

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

Producer runs `git diff` against a workspace PVC git repo. Construct once per workspace; safe for concurrent use (git is invoked via exec.CommandContext which is goroutine-safe).

func NewProducer

func NewProducer(workspaceRoot string) (*Producer, error)

NewProducer constructs a Producer for the workspace at workspaceRoot. Returns an error if workspaceRoot is not absolute (git -C requires absolute or root-relative paths and relative paths invite CWD races).

func (*Producer) DiffFiles

func (p *Producer) DiffFiles(ctx context.Context, files []string) ([]Diff, error)

DiffFiles produces unified-diff text for each path in files against HEAD. Returns one Diff per path that has a measurable change; paths that did not change (e.g. opencode reported them but git sees no diff vs HEAD) are omitted from the result.

files MUST be repo-relative paths (e.g. "src/foo.go", not "/workspace/src/foo.go"). The Producer does not rewrite them; git interprets pathspecs relative to the repo root regardless of -C.

Empty files slice returns (nil, nil) — no work to do.

New (untracked) files in `files` are normalized via `git add -N` (intent-to-add) before diffing. Without this, `git diff HEAD -- new.txt` returns empty for untracked files — git treats them as outside the index. `git add -N` records the path in the index with no content, so `git diff HEAD` correctly shows the addition vs /dev/null. The intent-to-add marker is local to the index; it does not stage the file's content for commit.

On git binary missing or repo corruption, returns a non-nil error. A truncated diff for one large file does NOT fail the call; that file's Diff has Truncated semantics via Patch="..." (truncation is per-file, not per-call).

Jump to

Keyboard shortcuts

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