libfossil

package module
v0.6.3 Latest Latest
Warning

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

Go to latest
Published: May 13, 2026 License: MIT Imports: 27 Imported by: 0

README

libfossil

Docs Go Reference Go Report Card Tests License Go

Pure-Go library and CLI for Fossil repositories. Drop-in compatible with Fossil's .fossil SQLite format, with no CGo and no upstream fossil binary required.

Why libfossil

  • Pure Go, no CGo. Static binaries, trivial cross-compilation, works under GOOS=wasip1 GOARCH=wasm.
  • Drop-in compatible. Repositories produced by upstream Fossil are readable, and vice versa — it's the same SQLite schema.
  • Embeddable. Use the full Repo API directly in your Go service. No subprocess calls, no temp files.
  • Instrumented. Sync and checkout observer interfaces make OpenTelemetry (or your own metrics) a few lines of code.
  • Deterministically testable. Deterministic simulation testing (DST) with BUGGIFY fault injection.

Installation

CLI
go install github.com/danmestas/libfossil/cmd/libfossil@latest

The binary is named libfossil to avoid $PATH collisions with upstream fossil.

Library
go get github.com/danmestas/libfossil

CLI quick start

libfossil repo new my.fossil
libfossil -R my.fossil repo ci -m "first commit" hello.txt
libfossil -R my.fossil repo timeline
libfossil -R my.fossil repo ls
libfossil -R my.fossil repo annotate hello.txt
libfossil -R my.fossil repo verify

Full command list: libfossil --help. See docs/migration-from-fossil.md for a command-by-command comparison with upstream Fossil.

Library quick start

package main

import (
    "log"

    libfossil "github.com/danmestas/libfossil"
    _ "github.com/danmestas/libfossil/db/driver/modernc"
)

func main() {
    r, err := libfossil.Create("my.fossil", libfossil.CreateOpts{User: "admin"})
    if err != nil {
        log.Fatal(err)
    }
    defer r.Close()

    rid, uuid, err := r.Commit(libfossil.CommitOpts{
        Files:   []libfossil.FileToCommit{{Name: "hello.txt", Content: []byte("hello")}},
        Comment: "initial commit",
        User:    "admin",
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("committed rid=%d uuid=%s", rid, uuid[:12])

    entries, err := r.Timeline(libfossil.LogOpts{Limit: 10})
    if err != nil {
        log.Fatal(err)
    }
    for _, e := range entries {
        log.Printf("  %s  %s", e.UUID[:12], e.Comment)
    }
}

Working example: examples/embed-repo-api/.

Sync

// Sync with a remote Fossil server.
result, err := r.Sync(ctx,
    libfossil.NewHTTPTransport("http://host/repo"),
    libfossil.SyncOpts{Push: true, Pull: true},
)

// Serve the sync protocol (e.g. for leaf agents, bridges, mirrors).
http.Handle("/", r.XferHandler())

The Transport interface is pluggable — swap HTTP for NATS, WebSocket, libp2p, or anything that delivers bytes round-trip.

Embedding the CLI

cli/ exposes Kong command structs you can mount inside your own CLI:

import (
    "github.com/alecthomas/kong"
    "github.com/danmestas/libfossil/cli"
    _ "github.com/danmestas/libfossil/db/driver/modernc"
)

type MyCLI struct {
    cli.Globals
    Repo cli.RepoCmd `cmd:"" help:"Fossil repo operations"`
    // Add your own commands here.
}

func main() {
    var c MyCLI
    ctx := kong.Parse(&c)
    ctx.FatalIfErrorf(ctx.Run(&c.Globals))
}

Project layout

Package Purpose
root (libfossil) Repo handle, Transport, SyncObserver, CheckoutObserver
cli/ Embeddable Kong command structs for the repo subcommands
cmd/libfossil/ Standalone CLI binary
db/ SQLite abstraction with pluggable drivers
db/driver/modernc Pure-Go SQLite driver (default)
db/driver/ncruces wasm-capable SQLite driver
observer/otel/ Optional OpenTelemetry observer (separate submodule)
dst/ Deterministic simulation tests + BUGGIFY harness
simio/ Clock, Rand, Storage interfaces for deterministic testing
testutil/ Shared test helpers

Deep dive: docs/architecture.md.

SQLite drivers

Driver Import When to use
modernc (default) _ "github.com/danmestas/libfossil/db/driver/modernc" Default for any server, CLI, or desktop use
ncruces _ "github.com/danmestas/libfossil/db/driver/ncruces" wasm targets (GOOS=wasip1 or browser/OPFS)

Driver selection happens via blank import at link time. See docs/extension-points.md for the registration contract.

Observers

// Built-in, zero dependencies.
libfossil.NopSyncObserver()     // silent
libfossil.StdoutSyncObserver()  // human-readable stderr

// Optional OpenTelemetry (separate submodule — no OTel deps in core).
import "github.com/danmestas/libfossil/observer/otel"
obs := otel.NewSyncObserver()

Both SyncObserver and CheckoutObserver are small interfaces you can implement directly. Details: docs/extension-points.md.

WASI / wasm

libfossil compiles to a generic WASI Preview 1 module via the ncruces driver:

GOOS=wasip1 GOARCH=wasm go build -o libfossil.wasm ./examples/wasm/

See examples/wasm/ for a runnable demo and current runtime caveats (the non-js ncruces driver variant has a known locking-mode quirk under wasmtime).

Testing

  • make test — unit tests with the default modernc driver
  • make test-drivers — unit tests against both modernc and ncruces
  • make test-otel — OTel submodule tests (runs with GOWORK=off)
  • make test-all — everything, including the binary build
  • make setup-hooks — install the pre-commit hook (~45s/commit)

Test strategy — unit tests, dual-driver matrix, and deterministic simulation (DST) with BUGGIFY fault injection: docs/testing.md.

Documentation

Full documentation: https://libfossil-docs.daniel-mestas.workers.dev.

Local preview: make docs-serve, then visit http://localhost:1313/.

Markdown sources: docs/site/content/.

Doc Audience
docs/architecture.md Contributors learning the codebase
docs/testing.md Contributors writing or debugging tests
docs/extension-points.md Consumers adding observers or custom drivers
docs/migration-from-fossil.md Users coming from upstream fossil
CONTRIBUTING.md Anyone submitting a PR
CHANGELOG.md Release notes

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Documentation

Index

Constants

View Source
const (
	CheckpointPassive  = db.CheckpointPassive
	CheckpointFull     = db.CheckpointFull
	CheckpointRestart  = db.CheckpointRestart
	CheckpointTruncate = db.CheckpointTruncate
)
View Source
const (
	PhantomSize         FslSize = fsltype.PhantomSize
	FossilApplicationID int32   = fsltype.FossilApplicationID
)

Variables

View Source
var ErrAmbiguousVersion = errors.New("libfossil: ambiguous version prefix")

ErrAmbiguousVersion is returned by ResolveVersion when a UUID prefix matches more than one artifact (collision). Callers can match with errors.Is.

View Source
var ErrArtifactNotFound = errors.New("libfossil: artifact not found")

ErrArtifactNotFound is returned by UUIDFromRID when the given RID does not correspond to any artifact in the repository's blob table. Callers can match with errors.Is.

View Source
var ErrFileNotFound = errors.New("libfossil: file not found in checkin")

ErrFileNotFound is returned by ReadFile when the requested filePath is not tracked in the given checkin. Callers can match with errors.Is.

View Source
var ErrMergeConflict = errors.New("libfossil: merge has conflicts")

ErrMergeConflict is returned (wrapped in a MergeConflictError) when Merge detects any unresolved three-way conflicts. Callers can check with errors.Is(err, ErrMergeConflict) without caring about the file list.

View Source
var ErrVersionNotFound = errors.New("libfossil: version not found")

ErrVersionNotFound is returned by ResolveVersion when the requested version string does not match any artifact in the repository. Callers can match with errors.Is.

Functions

func Clone

func Clone(ctx context.Context, path string, t Transport, opts CloneOpts) (*Repo, *CloneResult, error)

Clone performs a full repository clone from a remote Fossil server. It creates a new repository at the given path, runs the clone protocol until convergence, and returns the opened Repo handle and a result summary. On error, the partially-created repo file is removed.

func JulianToTime

func JulianToTime(j float64) time.Time

JulianToTime converts a Fossil Julian day number to time.Time.

func TimeToJulian

func TimeToJulian(t time.Time) float64

TimeToJulian converts a time.Time to a Fossil Julian day number.

Types

type AnnotateOpts

type AnnotateOpts struct {
	FilePath string
	StartRID int64
}

AnnotateOpts configures an annotate operation.

type AnnotatedLine

type AnnotatedLine struct {
	Text string
	UUID string
	User string
	Date time.Time
}

AnnotatedLine is a single line of blame/annotate output.

type BisectSession

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

BisectSession holds state for a binary-search bisect operation.

type BuggifyChecker

type BuggifyChecker interface {
	Check(site string, probability float64) bool
}

BuggifyChecker controls fault injection for deterministic simulation testing.

type Checkout

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

Checkout represents a working directory linked to a Fossil repository. A Checkout is not safe for concurrent use. Callers must serialize access to a single Checkout instance.

func (*Checkout) Add

func (c *Checkout) Add(patterns []string) (int, error)

Add adds files to version tracking. Returns the number of files added. Files already tracked are silently skipped.

func (*Checkout) Checkin

func (c *Checkout) Checkin(opts CheckoutCommitOpts) (int64, string, error)

Checkin creates a new checkin from the checkout working directory. Returns the RID and UUID of the new checkin manifest.

func (*Checkout) Close

func (c *Checkout) Close() error

Close closes the checkout database. Does NOT close the repo.

func (*Checkout) Dir

func (c *Checkout) Dir() string

Dir returns the checkout directory path.

func (*Checkout) Extract

func (c *Checkout) Extract(rid int64, opts ExtractOpts) error

Extract writes files from the specified checkin to the working directory.

func (*Checkout) HasChanges

func (c *Checkout) HasChanges() (bool, error)

HasChanges returns true if the checkout has any modified, deleted, or renamed files. This is a DB-only check; call Extract or scan first to detect on-disk modifications.

func (*Checkout) Remove

func (c *Checkout) Remove(patterns []string) error

Remove removes files from version tracking. Newly added files are deleted from vfile; committed files are marked as deleted.

func (*Checkout) Rename

func (c *Checkout) Rename(oldName, newName string) error

Rename marks a tracked file as renamed and moves it on disk.

func (*Checkout) Revert

func (c *Checkout) Revert(opts RevertOpts) error

Revert restores files to their checkout version state. If opts.Files is empty, reverts all changed files.

func (*Checkout) Status

func (c *Checkout) Status() ([]CheckoutChange, error)

Status scans the working directory for changes and returns a list of changed files. Wraps ScanChanges + VisitChanges.

func (*Checkout) Update

func (c *Checkout) Update(opts UpdateOpts) error

Update updates the checkout to a new version, performing 3-way merge where needed to preserve local modifications.

func (*Checkout) Version

func (c *Checkout) Version() (int64, string, error)

Version returns the current checkout version (RID and UUID).

func (*Checkout) WouldFork

func (c *Checkout) WouldFork() (bool, error)

WouldFork reports whether committing on the current branch would create a fork. Returns true when another leaf exists on the same branch.

type CheckoutChange

type CheckoutChange struct {
	Name   string
	Change string // "added", "modified", "deleted", "renamed", "missing"
}

CheckoutChange describes a single file change in the checkout.

type CheckoutCommitOpts

type CheckoutCommitOpts struct {
	Message string
	User    string
	Branch  string   // empty = current branch
	Tags    []string // additional tag names
	Delta   bool
}

CommitOpts configures creating a checkin from the checkout. (This type is distinct from the existing libfossil.CommitOpts which takes explicit file content for direct repo commits without a checkout.)

type CheckoutCreateOpts

type CheckoutCreateOpts struct {
	Env      *simio.Env       // nil = real env
	Observer CheckoutObserver // nil = nop
}

CheckoutCreateOpts configures creating a new checkout.

type CheckoutObserver

type CheckoutObserver interface {
	ExtractStarted(info ExtractStart)
	ExtractFileCompleted(name string, change UpdateChange)
	ExtractCompleted(info ExtractEnd)
	ScanStarted(dir string)
	ScanCompleted(info ScanEnd)
	CommitStarted(info CommitStart)
	CommitCompleted(info CommitEnd)
	Error(err error)
}

CheckoutObserver receives lifecycle callbacks during checkout/commit operations. Use NopCheckoutObserver() for a silent no-op, or StdoutCheckoutObserver() for stderr logging.

func NopCheckoutObserver

func NopCheckoutObserver() CheckoutObserver

NopCheckoutObserver returns a CheckoutObserver that silently discards all events.

func StdoutCheckoutObserver

func StdoutCheckoutObserver() CheckoutObserver

StdoutCheckoutObserver returns a CheckoutObserver that logs events to stderr.

type CheckoutOpenOpts

type CheckoutOpenOpts struct {
	SearchParents bool       // search parent dirs for .fslckout
	Env           *simio.Env // nil = real env
	Observer      CheckoutObserver
}

CheckoutOpenOpts configures opening an existing checkout.

type CheckoutOpts

type CheckoutOpts struct {
	Dir   string
	Force bool
}

CheckoutOpts configures a checkout extraction.

type CheckpointMode added in v0.6.0

type CheckpointMode = db.CheckpointMode

CheckpointMode mirrors SQLite's PRAGMA wal_checkpoint(<mode>) argument.

type CloneOpts

type CloneOpts struct {
	User        string
	Password    string
	ProjectCode string
	ServerCode  string
	Observer    SyncObserver
	Buggify     BuggifyChecker // fault injection for DST (nil = no faults)
}

CloneOpts configures a clone operation.

type CloneResult

type CloneResult struct {
	Rounds          int
	BlobsRecvd      int
	ArtifactsLinked int
	ProjectCode     string
	ServerCode      string
	Messages        []string
}

CloneResult reports what happened during a clone.

type CommitEnd

type CommitEnd struct {
	UUID string
	RID  int64
}

CommitEnd describes the completion of a commit operation.

type CommitOpts

type CommitOpts struct {
	// Files is the caller-supplied subset of the new commit's tree. When
	// ParentID is non-zero, Files is MERGED with the parent's tracked files:
	// any name in Files overrides the parent's entry, and any file tracked
	// at the parent but not in Files is carried forward into the new manifest.
	// This matches `fossil ci`'s full-tree semantics — supplying just the
	// changed files does not erase the rest of the tree.
	Files    []FileToCommit
	Comment  string
	User     string
	Tags     []TagSpec
	Time     time.Time
	ParentID int64
	// MergeParents lists additional parents for a merge commit. The resulting
	// manifest's P-card is [ParentID, MergeParents...]; ParentID is the primary
	// parent (branch tip being committed onto), and each MergeParent contributes
	// a secondary plink row (isprim=0).
	MergeParents []int64
	Delta        bool
	// PartialManifest, when true, skips the parent-file merge: the resulting
	// manifest contains only Files. This is the legacy pre-fix behavior and
	// effectively erases every file tracked at the parent that is not in
	// Files. Default false matches `fossil ci`. Set true only when the
	// caller intentionally wants omission-to-mean-deletion (e.g., tests for
	// the diff/deletion path); a dedicated deletion API may replace this
	// escape hatch later.
	PartialManifest bool
}

CommitOpts configures a commit operation.

type CommitStart

type CommitStart struct {
	Comment string
	User    string
	Files   int
}

CommitStart describes the beginning of a commit operation.

type CreateOpts

type CreateOpts struct {
	User string
	// ProjectCode optionally sets the repo's project-code. Empty
	// generates a fresh one (current behavior). When non-empty, must
	// be 40-char lowercase hex (^[0-9a-f]{40}$) — matching the format
	// of generated project-codes. Invalid values return an error
	// before any file is written.
	ProjectCode string
	// Rand provides random bytes for project-code and server-code generation.
	// Nil defaults to crypto/rand (production). Set to simio.NewSeededRand
	// for deterministic simulation testing.
	Rand simio.Rand
}

CreateOpts configures repository creation.

type DiffEntry

type DiffEntry struct {
	Name    string
	Unified string
}

DiffEntry describes a unified diff for a single file.

type ExtractEnd

type ExtractEnd struct {
	FilesWritten int
}

ExtractEnd describes the completion of a checkout extraction.

type ExtractOpts

type ExtractOpts struct {
	Force bool // overwrite uncommitted changes
}

ExtractOpts configures file extraction from a checkin.

type ExtractStart

type ExtractStart struct {
	RID int64
	Dir string
}

ExtractStart describes the beginning of a checkout extraction.

type FileEntry

type FileEntry struct {
	Name string
	UUID string
	Perm string
}

FileEntry describes a file in a manifest.

type FileToCommit

type FileToCommit struct {
	Name    string
	Content []byte
	Perm    string
}

FileToCommit describes a file to include in a commit.

type Fork

type Fork struct {
	Ancestor  int64
	LocalTip  int64
	RemoteTip int64
}

Fork describes a divergence point between two branches.

type FslError

type FslError struct {
	Code  RC
	Msg   string
	Cause error
}

func (*FslError) Error

func (e *FslError) Error() string

func (*FslError) Unwrap

func (e *FslError) Unwrap() error

type FslID

type FslID = fsltype.FslID

FslID is a row-id in the blob table (content-addressed artifacts).

type FslSize

type FslSize = fsltype.FslSize

FslSize represents a blob size; negative values indicate phantom blobs.

type HTTPOption

type HTTPOption func(*httpTransport)

HTTPOption configures an HTTP transport.

func WithHTTPClient

func WithHTTPClient(c *http.Client) HTTPOption

WithHTTPClient sets a custom http.Client for the transport.

type HandleEnd

type HandleEnd struct {
	FilesSent, FilesRecvd int
}

HandleEnd describes the completion of a server-side sync handle.

type HandleOpts

type HandleOpts struct {
	Observer SyncObserver
	Buggify  BuggifyChecker
}

HandleOpts configures server-side sync handling.

type HandleStart

type HandleStart struct {
	RemoteAddr string
}

HandleStart describes the beginning of a server-side sync handle.

type LogEntry

type LogEntry struct {
	RID     int64
	UUID    string
	Comment string
	User    string
	Time    time.Time
	Parents []string
}

LogEntry represents a single checkin in the timeline.

type LogOpts

type LogOpts struct {
	Start int64
	Limit int
}

LogOpts configures a log/timeline query.

type MergeConflict

type MergeConflict struct {
	Name      string
	StartLine int
	EndLine   int
}

MergeConflict describes a conflict region in a file.

type MergeConflictError added in v0.2.0

type MergeConflictError struct {
	Files []string
}

MergeConflictError reports which files had unresolved merge conflicts. Files is sorted alphabetically for deterministic output.

func (*MergeConflictError) Error added in v0.2.0

func (e *MergeConflictError) Error() string

func (*MergeConflictError) Is added in v0.2.0

func (e *MergeConflictError) Is(target error) bool

type MergeOpts

type MergeOpts struct {
	Strategy string
	Dir      string
}

MergeOpts configures a merge operation.

type MergeResult

type MergeResult struct {
	Clean     bool
	Conflicts []MergeConflict
}

MergeResult describes the outcome of a merge.

type MockTransport

type MockTransport struct {
	Handler func(req []byte) []byte
}

MockTransport is a test double that delegates to a handler function.

func (*MockTransport) RoundTrip

func (t *MockTransport) RoundTrip(_ context.Context, payload []byte) ([]byte, error)

RoundTrip calls the Handler function if set, otherwise returns empty bytes.

type PullOpts added in v0.4.0

type PullOpts struct {
	// ProjectCode optionally pins the expected server project code. Empty
	// accepts whatever the peer advertises (matches existing Sync semantics).
	ProjectCode string

	// MaxSend caps the bytes the client will send per round (mostly clones
	// of clients with UV files). Zero leaves the existing default in place.
	MaxSend int

	// Observer receives sync-progress events. nil disables observation.
	Observer SyncObserver
}

PullOpts configures a pull-only sync. Fields are a subset of SyncOpts; Pull is hard-coded true and Push is hard-coded false to keep the API surface honest about what Pull does.

type RC

type RC int
const (
	RCOK               RC = 0
	RCError            RC = 100
	RCNYI              RC = 101
	RCOOM              RC = 102
	RCMisuse           RC = 103
	RCRange            RC = 104
	RCAccess           RC = 105
	RCIO               RC = 106
	RCNotFound         RC = 107
	RCAlreadyExists    RC = 108
	RCConsistency      RC = 109
	RCRepoNeedsRebuild RC = 110
	RCNotARepo         RC = 111
	RCRepoVersion      RC = 112
	RCDB               RC = 113
	RCBreak            RC = 114
	RCStepRow          RC = 115
	RCStepDone         RC = 116
	RCStepError        RC = 117
	RCType             RC = 118
	RCNotACkout        RC = 119
	RCRepoMismatch     RC = 120
	RCChecksumMismatch RC = 121
	RCLocked           RC = 122
	RCConflict         RC = 123
	RCSizeMismatch     RC = 124
	RCPhantom          RC = 125
	RCUnsupported      RC = 126
)

func (RC) String

func (rc RC) String() string

type Repo

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

Repo is an opaque handle to a Fossil repository.

func Create

func Create(path string, opts CreateOpts) (*Repo, error)

Create creates a new Fossil repository at the given path.

func Open

func Open(path string) (*Repo, error)

Open opens an existing Fossil repository.

func (*Repo) Annotate

func (r *Repo) Annotate(opts AnnotateOpts) ([]AnnotatedLine, error)

Annotate attributes each line of a file to the commit that last changed it.

func (*Repo) BranchTip added in v0.2.0

func (r *Repo) BranchTip(name string) (int64, error)

BranchTip returns the RID of the most recent checkin on the named branch. Resolves via the 'branch' propagating tag: the tip is the checkin with the latest event.mtime whose tagxref still has that branch value active. Returns an error if no such branch exists in the repository.

func (*Repo) Checkpoint added in v0.6.0

func (r *Repo) Checkpoint(mode CheckpointMode) error

Checkpoint runs PRAGMA wal_checkpoint(<mode>) against the repository. Safe to call on a live repo. CheckpointPassive is non-blocking and appropriate for periodic background checkpoints. CheckpointTruncate produces a maximally compact on-disk file readable by external fossil tooling without a subsequent Close.

func (*Repo) Close

func (r *Repo) Close() error

Close closes the repository and releases resources. As part of close, a WAL TRUNCATE checkpoint is run so the on-disk repo file is readable by external fossil/SQLite tooling.

func (*Repo) Commit

func (r *Repo) Commit(opts CommitOpts) (int64, string, error)

Commit creates a new checkin manifest with the given files and returns the RID (row ID) and UUID of the newly created artifact. When ParentID is non-zero, files tracked at the parent but absent from opts.Files are carried forward into the new manifest (full-tree semantics — see the CommitOpts.Files doc).

func (*Repo) Config

func (r *Repo) Config(key string) (string, error)

Config reads a configuration value from the repo's config table.

func (*Repo) CreateCheckout

func (r *Repo) CreateCheckout(dir string, opts CheckoutCreateOpts) (*Checkout, error)

CreateCheckout creates a new checkout directory linked to this repository. The directory is created if it does not exist. The checkout is initialized to the tip checkin.

func (*Repo) CreateUser

func (r *Repo) CreateUser(opts UserOpts) error

CreateUser creates a new user in the repository.

func (*Repo) DB

func (r *Repo) DB() *db.DB

DB returns the underlying database handle for raw SQL queries. Use this when the high-level Repo methods don't cover your use case.

func (*Repo) DeleteUser

func (r *Repo) DeleteUser(login string) error

DeleteUser removes a user from the repository.

func (*Repo) DetectForks

func (r *Repo) DetectForks() ([]Fork, error)

DetectForks finds divergent branches in the repository.

func (*Repo) Diff

func (r *Repo) Diff(ridA, ridB int64, filePath string) ([]DiffEntry, error)

Diff returns the unified diff(s) between ridA and ridB.

When filePath is non-empty, returns 0 or 1 entries for that single file: the file is treated as empty bytes on any side where it is absent, so additions and deletions render as pure insert/delete hunks. An empty slice is returned when both sides are byte-identical.

When filePath is empty, returns one entry per file that changed between the two checkins (the union of files across both sides where the content UUID differs or the file exists on only one side). Entries are sorted by Name for deterministic ordering. An empty slice is returned when the two checkins have identical file sets and content.

Whole-checkin enumeration is currently name-keyed: a rename with no content change surfaces as a delete of the old name plus an add of the new name, and permission-only changes are not reflected. Proper rename and perm-change detection (via the underlying mlink table) is tracked as a follow-up; per-file diff behaviour for an explicitly named file is unchanged.

func (*Repo) FindCommonAncestor

func (r *Repo) FindCommonAncestor(ridA, ridB int64) (int64, error)

FindCommonAncestor finds the nearest common ancestor of two checkins.

func (*Repo) GetUser

func (r *Repo) GetUser(login string) (User, error)

GetUser returns information about a user.

func (*Repo) HandleSync

func (r *Repo) HandleSync(ctx context.Context, payload []byte) ([]byte, error)

HandleSync processes an incoming xfer request (server-side). The payload is a raw xfer-encoded byte slice; the response is also raw bytes.

func (*Repo) HandleSyncWithOpts

func (r *Repo) HandleSyncWithOpts(ctx context.Context, payload []byte, opts HandleOpts) ([]byte, error)

HandleSyncWithOpts processes an incoming xfer request with optional configuration.

func (*Repo) Inner

func (r *Repo) Inner() *repo.Repo

Inner returns the underlying internal repo handle. This is exported for use by in-module packages (e.g., cli/) that need direct access to the repo DB for raw SQL or internal package calls.

func (*Repo) ListConflictForks

func (r *Repo) ListConflictForks() ([]string, error)

ListConflictForks returns filenames with unresolved conflict-fork entries.

func (*Repo) ListFiles

func (r *Repo) ListFiles(rid int64) ([]FileEntry, error)

ListFiles returns the files in a manifest identified by blob row-id.

func (*Repo) ListUsers

func (r *Repo) ListUsers() ([]User, error)

ListUsers returns all users in the repository.

func (*Repo) Merge added in v0.2.0

func (r *Repo) Merge(srcBranch, dstBranch, message, user string) (int64, string, error)

Merge performs a three-way merge of srcBranch into dstBranch and creates a merge commit whose primary parent is dstBranch's tip and whose secondary parent is srcBranch's tip. Returns (rid, uuid) of the new commit on success.

Conflict policy: any unresolved conflict in any file aborts the whole operation with a *MergeConflictError — no commit is written. Callers should check errors.Is(err, ErrMergeConflict) to detect this case.

File handling:

  • Present on both sides: three-way merge against the common ancestor.
  • Present on only one side (new file): kept as-is.
  • In ancestor, missing on one side, unchanged on the other: agreed deletion.
  • In ancestor, missing on one side, modified on the other: modify/delete conflict.

func (*Repo) OpenCheckout

func (r *Repo) OpenCheckout(dir string, opts CheckoutOpenOpts) (*Checkout, error)

OpenCheckout opens an existing checkout directory linked to this repository.

func (*Repo) Path

func (r *Repo) Path() string

Path returns the filesystem path to the repository file.

func (*Repo) Pull added in v0.4.0

func (r *Repo) Pull(ctx context.Context, url string, opts PullOpts) (*SyncResult, error)

Pull fetches commits and ancillary objects from a Fossil HTTP peer and applies them to this repo. It is a strict pull — nothing is sent.

Tiger Style: hostile inputs panic via assert at the boundary; transport failures return wrapped errors. Idempotent on a repo already at peer's tip (returns a SyncResult with Rounds=0–1 and FilesRecvd=0).

func (*Repo) ReadFile added in v0.3.0

func (r *Repo) ReadFile(rid int64, filePath string) ([]byte, error)

ReadFile returns the bytes of filePath as they existed in checkin rid. Returns ErrFileNotFound (wrapped) if the file is not tracked in that checkin. A file that exists but is empty returns ([]byte{}, nil).

func (*Repo) ReadFileAt added in v0.4.3

func (r *Repo) ReadFileAt(version string, filePath string) ([]byte, error)

ReadFileAt reads filePath from the checkin identified by a symbolic version name (e.g. "tip", "trunk", a branch name, a UUID, or a UUID prefix). It calls ResolveVersion to obtain the RID, then delegates to ReadFile. Use ReadFile directly when you already have a numeric RID.

func (*Repo) Redo

func (r *Repo) Redo(dir string) error

Redo re-applies the last undone operation. Requires a checkout database; not yet wired.

func (*Repo) ResolveConflictFork

func (r *Repo) ResolveConflictFork(filename string) error

ResolveConflictFork marks a conflict-fork entry as resolved.

func (*Repo) ResolveVersion added in v0.4.3

func (r *Repo) ResolveVersion(name string) (int64, error)

ResolveVersion resolves a symbolic version name to a repository artifact RID.

Resolution order:

  1. "" or "tip" — newest checkin by mtime from the event table.
  2. "trunk" — tip of the trunk branch via tagxref/tag; falls back to "tip" if the repository has no trunk tag.
  3. Named branch — tag lookup for "sym-<name>" in tagxref/tag (e.g. "feature-x" resolves via sym-feature-x).
  4. Full UUID (≥40 chars) — exact match against blob.uuid.
  5. UUID prefix (4–39 chars) — unique-prefix match; returns ErrAmbiguousVersion if more than one artifact matches.

An empty result or no match returns ErrVersionNotFound (wrapped). An ambiguous prefix returns ErrAmbiguousVersion (wrapped).

func (*Repo) ServeHTTP

func (r *Repo) ServeHTTP(ctx context.Context, addr string) error

ServeHTTP starts an HTTP server that accepts Fossil xfer requests. Blocks until ctx is cancelled.

func (*Repo) SetCaps

func (r *Repo) SetCaps(login, caps string) error

SetCaps updates a user's capability string.

func (*Repo) SetConfig

func (r *Repo) SetConfig(key, value string) error

SetConfig writes a configuration value to the repo's config table.

func (*Repo) SetPassword

func (r *Repo) SetPassword(login, password string) error

SetPassword updates a user's password.

func (*Repo) StashApply

func (r *Repo) StashApply(dir string, id int64) error

StashApply restores a stash entry by ID without removing it.

func (*Repo) StashClear

func (r *Repo) StashClear() error

StashClear removes all stash entries.

func (*Repo) StashDrop

func (r *Repo) StashDrop(id int64) error

StashDrop removes a stash entry by ID.

func (*Repo) StashList

func (r *Repo) StashList() ([]StashEntry, error)

StashList returns all stash entries.

func (*Repo) StashPop

func (r *Repo) StashPop(dir string) error

StashPop restores the most recent stash entry and removes it.

func (*Repo) StashSave

func (r *Repo) StashSave(dir, comment string) error

StashSave saves working-tree changes to the stash. Requires a checkout database; not yet wired (Repo only wraps the repo DB).

func (*Repo) Sync

func (r *Repo) Sync(ctx context.Context, t Transport, opts SyncOpts) (*SyncResult, error)

Sync runs a sync session against the given transport.

func (*Repo) Tag

func (r *Repo) Tag(opts TagOpts) (int64, error)

Tag creates a control artifact that adds a tag to a target checkin. Returns the UUID of the tag control artifact.

func (*Repo) Timeline

func (r *Repo) Timeline(opts LogOpts) ([]LogEntry, error)

Timeline returns checkin log entries starting from the given RID.

func (*Repo) UUIDFromRID added in v0.5.0

func (r *Repo) UUIDFromRID(rid int64) (string, error)

UUIDFromRID returns the UUID (manifest hash) of the artifact identified by rid. The UUID is the stable, content-addressed identifier for the artifact; the rid is a repository-local integer that may differ across clones.

Returns ErrArtifactNotFound (wrapped) if no artifact with the given rid exists in the repository. The wrapped error message includes the offending rid. Other errors surface as-is.

func (*Repo) UVDelete

func (r *Repo) UVDelete(name string, mtime time.Time) error

UVDelete marks an unversioned file as deleted (tombstone).

func (*Repo) UVList

func (r *Repo) UVList() ([]UVEntry, error)

UVList returns all unversioned file entries.

func (*Repo) UVRead

func (r *Repo) UVRead(name string) ([]byte, int64, string, error)

UVRead reads an unversioned file from the repository. Returns the content, mtime (unix seconds), and content hash.

func (*Repo) UVWrite

func (r *Repo) UVWrite(name string, content []byte, mtime time.Time) error

UVWrite writes an unversioned file to the repository.

func (*Repo) Undo

func (r *Repo) Undo(dir string) error

Undo reverts the last commit or merge. Requires a checkout database; not yet wired.

func (*Repo) Verify

func (r *Repo) Verify() error

Verify checks repository integrity (blob checksums, delta chains).

func (*Repo) WithTx

func (r *Repo) WithTx(fn func(tx *db.Tx) error) error

WithTx executes fn within a database transaction.

func (*Repo) XferHandler

func (r *Repo) XferHandler() http.HandlerFunc

XferHandler returns an http.HandlerFunc that decodes Fossil xfer requests, dispatches to HandleSync, and encodes the response. Use this to compose a custom mux alongside operational endpoints (e.g., /healthz).

type RevertOpts

type RevertOpts struct {
	Files []string // empty = revert all
}

RevertOpts configures reverting file changes.

type RoundStats

type RoundStats struct {
	FilesSent, FilesRecvd, BytesSent, BytesRecvd, Gimmes, IGots int
}

RoundStats describes the outcome of a single sync round.

type ScanEnd

type ScanEnd struct {
	FilesScanned int
}

ScanEnd describes the completion of a working-tree scan.

type SessionEnd

type SessionEnd struct {
	Rounds, FilesSent, FilesRecvd int
}

SessionEnd describes the completion of a sync session.

type SessionStart

type SessionStart struct {
	ProjectCode    string
	Push, Pull, UV bool
}

SessionStart describes the beginning of a sync session.

type StashEntry

type StashEntry struct {
	ID      int64
	Comment string
	Time    string
}

StashEntry describes a saved stash.

type StatusEntry

type StatusEntry struct {
	Name   string
	Change string
}

StatusEntry describes a changed file in the working tree.

type StatusOpts

type StatusOpts struct {
	Dir string
}

StatusOpts configures a working-tree status query.

type SyncObserver

type SyncObserver interface {
	Started(info SessionStart)
	RoundStarted(round int)
	RoundCompleted(round int, stats RoundStats)
	Completed(info SessionEnd)
	Error(err error)
	HandleStarted(info HandleStart)
	HandleCompleted(info HandleEnd)
	TableSyncStarted(info TableSyncStart)
	TableSyncCompleted(info TableSyncEnd)
}

SyncObserver receives lifecycle callbacks during sync operations. Use NopSyncObserver() for a silent no-op, or StdoutSyncObserver() for stderr logging.

func NopSyncObserver

func NopSyncObserver() SyncObserver

NopSyncObserver returns a SyncObserver that silently discards all events.

func StdoutSyncObserver

func StdoutSyncObserver() SyncObserver

StdoutSyncObserver returns a SyncObserver that logs events to stderr.

type SyncOpts

type SyncOpts struct {
	Push        bool
	Pull        bool
	UV          bool
	ProjectCode string
	ServerCode  string
	User        string
	Password    string
	PeerID      string // identifies this leaf agent instance
	MaxSend     int
	XTableSync  bool // enable extension table sync (peer_registry, etc.)
	Private     bool // enable private artifact sync
	Observer    SyncObserver
	Buggify     BuggifyChecker
}

SyncOpts configures a sync operation.

type SyncResult

type SyncResult struct {
	Rounds       int
	FilesSent    int
	FilesRecvd   int
	UVFilesSent  int
	UVFilesRecvd int
	UVGimmesSent int
	BytesSent    int64
	BytesRecvd   int64
	Errors       []string
}

SyncResult describes the outcome of a sync session.

type TableSyncEnd

type TableSyncEnd struct {
	Table               string
	RowsSent, RowsRecvd int
}

TableSyncEnd describes the completion of a config table sync.

type TableSyncStart

type TableSyncStart struct {
	Table string
}

TableSyncStart describes the beginning of a config table sync.

type TagOpts

type TagOpts struct {
	Name     string
	TargetID int64
	Value    string
	User     string
	Time     time.Time
}

TagOpts configures a tag operation.

type TagSpec

type TagSpec struct {
	Name  string
	Value string
}

TagSpec describes a tag to attach to an artifact.

type Transport

type Transport interface {
	RoundTrip(ctx context.Context, payload []byte) ([]byte, error)
}

Transport delivers sync payloads between peers. Implementations handle the network layer (HTTP, NATS, etc.). Payloads are opaque zlib-compressed xfer card streams.

func NewHTTPTransport

func NewHTTPTransport(url string, opts ...HTTPOption) Transport

NewHTTPTransport creates a Transport that speaks Fossil's HTTP /xfer protocol.

type TransportFunc

type TransportFunc func(ctx context.Context, payload []byte) ([]byte, error)

TransportFunc adapts a plain function to the Transport interface. This is the Transport equivalent of http.HandlerFunc.

func (TransportFunc) RoundTrip

func (f TransportFunc) RoundTrip(ctx context.Context, payload []byte) ([]byte, error)

RoundTrip calls the function.

type UVEntry

type UVEntry struct {
	Name  string
	Size  int64
	Mtime time.Time
	Hash  string
}

UVEntry describes an unversioned file.

type UpdateChange

type UpdateChange string

UpdateChange classifies how a file changed.

const (
	ChangeAdded    UpdateChange = "added"
	ChangeModified UpdateChange = "modified"
	ChangeDeleted  UpdateChange = "deleted"
)

type UpdateOpts

type UpdateOpts struct {
	TargetRID int64 // 0 = tip
	Force     bool
}

UpdateOpts configures updating to a new version with merge.

type User

type User struct {
	Login string
	Caps  string
}

User describes a Fossil user.

type UserOpts

type UserOpts struct {
	Login    string
	Password string
	Caps     string
}

UserOpts configures a user creation or update.

Directories

Path Synopsis
cmd
libfossil command
db
Package db provides a SQLite database layer with pluggable drivers.
Package db provides a SQLite database layer with pluggable drivers.
examples
embed-repo-api command
Example: embed libfossil as a library in a Go application.
Example: embed libfossil as a library in a Go application.
wasm command
Example: build libfossil for a generic WASI Preview 1 wasm target.
Example: build libfossil for a generic WASI Preview 1 wasm target.
internal
bisect
Package bisect implements binary search through Fossil commit history.
Package bisect implements binary search through Fossil commit history.
blob
Package blob handles content-addressed blob storage in Fossil repository databases.
Package blob handles content-addressed blob storage in Fossil repository databases.
checkout
Package checkout provides working directory management for Fossil repositories.
Package checkout provides working directory management for Fossil repositories.
content
Package content reconstructs full artifact content from Fossil's delta-chain storage.
Package content reconstructs full artifact content from Fossil's delta-chain storage.
diff
Package diff produces unified diff output from two byte slices using the Myers diff algorithm.
Package diff produces unified diff output from two byte slices using the Myers diff algorithm.
fsltype
Package fsltype defines shared types used across internal packages.
Package fsltype defines shared types used across internal packages.
merge
Package merge provides three-way merge with pluggable strategies.
Package merge provides three-way merge with pluggable strategies.
repo
Package repo manages Fossil repository database files.
Package repo manages Fossil repository database files.
stash
Package stash saves and restores working directory changes, storing deltas against baseline blobs in the checkout database (.fslckout).
Package stash saves and restores working directory changes, storing deltas against baseline blobs in the checkout database (.fslckout).
sync
Package sync implements Fossil's multi-round sync and clone protocol.
Package sync implements Fossil's multi-round sync and clone protocol.
tag
undo
Package undo saves, restores, and redoes checkout state in a Fossil .fslckout database.
Package undo saves, restores, and redoes checkout state in a Fossil .fslckout database.
uv
verify
Package verify provides comprehensive repository verification and rebuild.
Package verify provides comprehensive repository verification and rebuild.
xfer
Package xfer implements Fossil's sync protocol card codec.
Package xfer implements Fossil's sync protocol card codec.
observer
otel module

Jump to

Keyboard shortcuts

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