Help us shape the future of Go! Take the 2026 Go Developer Survey

filediff

package
v0.39.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 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