Skip to content
go-libfossil Artifact [6aa8d34455]
Login

Artifact [6aa8d34455]

Artifact 6aa8d34455669f502128a81a9161715535414c90b2200e5906394ecc90872b2b:



title: libfossil

<!-- Code generated by gomarkdoc. DO NOT EDIT -->

libfossil

import "github.com/danmestas/go-libfossil"

Index

Constants

const (
    CheckpointPassive  = db.CheckpointPassive
    CheckpointFull     = db.CheckpointFull
    CheckpointRestart  = db.CheckpointRestart
    CheckpointTruncate = db.CheckpointTruncate
)

const (
    PhantomSize         FslSize = fsltype.PhantomSize
    FossilApplicationID int32   = fsltype.FossilApplicationID
)

SettingClearsign names the boolean repository setting, read as fossil reads one, that signs every check-in a commit or a branch creation stores, as fossil and zit sign them. Off by default. It signs no horizon seed: see SettingHorizonSeedCommand. The signed text is the artifact, so a signed check-in's name is the hash of the signed bytes; a signer that fails abandons the commit. CommitOpts.NoSign and CheckoutCommitOpts.NoSign store one check-in unsigned, as fossil's --nosign does, and fossil's legacy omitsign setting turns signing off.

const SettingClearsign = clearsign.SettingClearsign

SettingHorizonHistoryURL names the repository setting an origin appends to pragma horizon-served as the interface, outside the sync protocol, at which history below a horizon can be queried (draft-fossil-horizon-00 §6.2.5). It must be one http or https URL with a host, no white space and no credentials; SetConfig refuses any other value, and an empty one names none. Horizon clients report it as CloneResult.HorizonHistoryURL and SyncResult.HorizonHistoryURL.

const SettingHorizonHistoryURL = repo.SettingHorizonHistoryURL

SettingHorizonSeedCommand names the command an origin signs the structural horizon seeds it mints with (draft-fossil-horizon-00 §5.2.4), configured apart from SettingClearsign and SettingPGPCommand: unset or off, seeds go out unsigned even when check-ins are signed. It follows pgp-command's contract, and an SSH signer must sign in the namespace fossil-horizon-seed, never fossilscm, so that a check-in's signature cannot stand in for a seed's:

ssh-keygen -q -Y sign -n fossil-horizon-seed -f ~/.ssh/id_ed25519

An origin whose command signs in another namespace serves no seed: the request fails.

const SettingHorizonSeedCommand = clearsign.SettingSeedCommand

SettingHorizonSeedKey names the setting holding the public key a clone verifies its origin's structural horizon seeds with (draft-fossil-horizon-00 §5.2.4): an SSH public key line, verified in process, or the fingerprint of an OpenPGP key in the user's gpg keyring, verified by gpg. With a key set, a seed that is unsigned or not signed by that key is discarded and the clone falls back to the content horizon; unset, an unsigned seed is accepted. An SSH signature must carry the namespace fossil-horizon-seed. CloneOpts.SeedKey sets it when the clone is made. It is the clone's own: an origin never sends it.

SSH signatures are verified only in a program that imports package github.com/danmestas/go-libfossil/sshverify; without it, a seed under an SSH key is refused with ErrSSHVerifierUnavailable.

const SettingHorizonSeedKey = clearsign.SettingSeedKey

SettingPGPCommand names the signing command, as fossil names it. Unset, it is fossil's default, "gpg --clearsign -o ", run as COMMAND OUTFILE INFILE. A command whose name starts with "ssh" is run as COMMAND INFILE and writes a detached INFILE.sig, which is wrapped in fossil's SSH envelope; to sign with an SSH key, set it to

ssh-keygen -q -Y sign -n fossilscm -f ~/.ssh/id_ed25519

The namespace must be fossilscm for a clone to verify the signature. The command runs through the shell, so ~ and environment variables expand.

const SettingPGPCommand = clearsign.SettingPGPCommand

SettingPartialMirror names the boolean repository setting, read as fossil reads one ("on", "yes", "true" or a nonzero number), that lets a sparse store serve a clone its cone does not cover (draft-fossil-sparse-cone-00 §5.3). Unset, such a clone is refused with one error card and no content, since the clone would receive elided phantoms it must resolve elsewhere. It governs every serving surface: HandleSync, XferHandler and ServeHTTP.

const SettingPartialMirror = internalsync.SettingPartialMirror

Variables

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

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

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

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

ErrAttachmentNotFound is returned when a target has no current attachment by the name asked for: none was ever added, or the latest was deleted. Callers can match with errors.Is.

var ErrAttachmentNotFound = errors.New("libfossil: attachment not found")

ErrBelowHorizon is matched by the error of an operation that needs history below the store's structural horizon (draft-fossil-horizon-00 §5.5), such as a merge whose base lies there. The message names the horizon and the remedy, a deepen (Repo.DeepenHorizon).

var ErrBelowHorizon = content.ErrBelowHorizon

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

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

ErrHorizonCheckout is returned when a checkout is given a cone that carries a horizon. A content horizon (draft-fossil-horizon-00 §3.2) is a property of the repository's store, not of a checkout: set it on the store cone with Repo.SetStoreCone.

var ErrHorizonCheckout = errors.New("libfossil: a horizon is a property of the repository's store, not of a checkout")

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.

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

ErrNoStoreCone is returned by CompactStore on a dense store: with no cone on record nothing is elided, and compaction never guesses a policy.

var ErrNoStoreCone = errors.New("libfossil: the store has no cone")

ErrOutsideCone is wrapped by the refusal of a checkout operation that would act on a path its sparse cone does not cover: adding, removing, renaming, reverting or committing such a path, or a merge that would change one. The message names the path, the cone and the member that excluded it.

var ErrOutsideCone = checkout.ErrOutsideCone

ErrSSHVerifierUnavailable is the error, wrapped, of an operation that had to verify an SSH signature in a program that does not link the verifier: a sync or rebuild of a store whose SettingHorizonSeedKey is an SSH key fails with it, and the seed is neither accepted nor discarded. Import package github.com/danmestas/go-libfossil/sshverify for its side effect to verify SSH signatures; the library leaves that cryptography out of programs that never verify one.

var ErrSSHVerifierUnavailable = clearsign.ErrSSHVerifierUnavailable

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

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

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. Artifacts the clone rounds leave missing stay phantoms unless opts.PullPhantoms is set.

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.

type AnnotateOpts

AnnotateOpts configures an annotate operation.

type AnnotateOpts struct {
    FilePath string
    StartRID int64
}

type AnnotatedLine

AnnotatedLine is a single line of blame/annotate output.

BelowHorizon marks a line whose origin lies at or below the store's horizon C (draft-fossil-horizon-00 §5.5), which the store does not hold the history to attribute: UUID, User and Date then describe C itself, at which the line is reported as originating, not the check-in that added it. A deepen (repo cone deepen) brings the history that attributes it; on a content-horizon store AnnotateContext fetches it.

Such a result is partial, and the marks are its only signal: Annotate returns it with no error, as does an AnnotateContext that reached its demand-fetch limit or whose peer could not supply a version.

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

type Attachment

Attachment is one current attachment: the latest artifact for its name on its target, when that artifact adds a file rather than deleting it.

type Attachment struct {
    // Artifact is the hash of the control artifact that attached the file.
    Artifact string `json:"artifact"`
    // Target is the full ticket id, wiki page name or tech note id.
    Target string `json:"target"`
    Name   string `json:"name"`
    // Source is the hash of the blob the A card names: the file itself, or
    // the stub when External is set.
    Source  string    `json:"source"`
    Comment string    `json:"comment"`
    User    string    `json:"user"`
    Time    time.Time `json:"time"`
    // Size is the file's length in bytes: the blob's, or External.Size. It
    // is -1 when the blob has not arrived in this repository.
    Size int64 `json:"size"`
    // External, when not nil, says the bytes live outside the repository:
    // Source is a stub, and AttachmentRead returns no content.
    External *ExternalRef `json:"external,omitempty"`
}

type AttachmentOpts

AttachmentOpts is who makes an attachment change, when, and why.

type AttachmentOpts struct {
    // User is the change's author, its U card.
    User string
    // Comment is the attachment's description, its C card. Fossil writes
    // none on a deletion, so AttachmentDelete refuses one.
    Comment string
    // Time is the change's D card; zero means now.
    Time time.Time
}

type BisectSession

BisectSession holds state for a binary-search bisect operation.

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

type BuggifyChecker

BuggifyChecker controls fault injection for deterministic simulation testing.

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

type Checkout

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.

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

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) (rid int64, uuid string, err error)

Checkin creates a new checkin from the checkout working directory: every change, or only opts.Files (a directory names every tracked file under it). Pending merges become merge parents. Like fossil's commit, it refuses a name it does not track, a commit with nothing changed and no merge pending (unless opts.AllowEmpty), files that still hold merge conflict markers (unless opts.AllowConflict), and committing only some files of a pending merge. Returns the RID and UUID of the new checkin manifest.

func (*Checkout) CheckinContext

func (c *Checkout) CheckinContext(ctx context.Context, opts CheckoutCommitOpts, required RequiredContentOpts) (int64, string, error)

CheckinContext recovers necessary parent structure from an explicit peer, outside checkout locks and repository transactions. It then gathers checkout changes afresh; no stale file list is replayed after network I/O.

func (*Checkout) Close

func (c *Checkout) Close() error

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

func (*Checkout) Cone

func (c *Checkout) Cone() *Cone

Cone returns the checkout's cone, or nil when the checkout is dense.

func (*Checkout) Conflicts

func (c *Checkout) Conflicts() ([]string, error)

Conflicts lists the files, sorted, that hold merge conflict markers: the files a merge or update left in conflict and nobody has resolved yet.

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 and makes it the checkout's current version. Unless opts.Force is set it refuses, changing nothing, when the checkout has unsaved changes or when an untracked file sits where the checkin would write different content.

func (*Checkout) HasChanges

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

HasChanges reports whether the checkout has any added, removed, renamed or modified files. It reads only the checkout database, so an edit on disk counts once Status (or an Extract or Commit) has scanned it; adds, removals and renames always count. Missing files need the disk; Status reports them.

func (*Checkout) Merge

func (c *Checkout) Merge(opts CheckoutMergeOpts) (CheckoutMergeResult, error)

Merge merges another checkin into the checkout, as fossil's merge command does, leaving the result for the next Checkin to commit with the merged-in checkin as a merge parent. A file both sides changed is merged by its strategy; when the strategy cannot reconcile the changes, fossil's conflict markers are written into the file, and the file is in conflict until they are edited out (see Conflicts). A conflicted merge is not an error.

Merge refuses, changing nothing, when the repository lacks content it needs or an added file would overwrite an untracked one. A file edited here but deleted in the merged-in version is kept and reported. Renames are followed as fossil's merge follows them: a change made under one name is merged into the file under another, and a file the merged-in checkin renamed is renamed here too (CheckoutMergeFile.RenamedTo); Merge refuses to rename one onto a file the checkout keeps or an untracked file. Merging the checkout's own version or one of its ancestors does nothing. The common ancestor is the one fossil's merge diffs against: the most recent common ancestor of the merged-in checkin and the checkout's version with every checkin already merged into it.

Under a structural horizon Merge refuses, with an error matching ErrBelowHorizon, a merge whose base it does not hold or whose sides' ancestry crosses the horizon (draft-fossil-horizon-00 §5.5): only the origin can name that base, and MergeContext with a Peer asks it.

func (*Checkout) MergeContext

func (c *Checkout) MergeContext(ctx context.Context, opts CheckoutMergeOpts, required RequiredContentOpts) (CheckoutMergeResult, error)

MergeContext is Merge with the remedy of draft-fossil-horizon-00 §5.5. Under a structural horizon, when Peer is given and the ancestry of either side crosses the horizon, it asks the origin for the base (§6.2.4) even when the store's own walk finds one, since over part of the graph the common ancestor found need not be the nearest. It deepens the horizon to the base the origin names when the store does not hold it (Repo.DeepenHorizon) and merges over that base. When the origin does not answer, or without a Peer, it is Merge, which refuses a merge whose ancestry crosses the horizon; when nothing crosses it is Merge. A merge never runs against a base the store does not hold.

The query names the merged-in version over the checkout's version and each plain merge pending in it. It carries at most two such secondaries, so a merge that must ask with two merges already pending is refused: asking without them would name a base Fossil's merge would not choose.

func (*Checkout) Redo

func (c *Checkout) Redo() (UndoResult, error)

Redo reverses the last Undo, reporting the files it changed as Undo does.

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) ResolveVersion

func (c *Checkout) ResolveVersion(name string) (int64, error)

ResolveVersion resolves name as Repo.ResolveVersion does and also resolves the names relative to this checkout (repo-state-00 Section 8.3), tried after "tip" and before every other form, as fossil's symbolic_name_to_rid does (src/name.c):

"current"            the checkout's version
"prev", "previous"   its primary parent
"next"               a child: a primary child first, then the newest link

A keyword that names nothing, such as "prev" at a root, falls through to the other forms, as in fossil. The forms that take a name, such as "root:current", resolve it the same way. "ckout" is an ordinary name here: it is a keyword only in the checkout-inclusive request, ResolveWorking.

func (*Checkout) ResolveWorking

func (c *Checkout) ResolveWorking(name string) (WorkingVersion, error)

ResolveWorking is fossil's checkout-inclusive request ("ci+", symbolic_name_to_rid in src/name.c): while the checkout has a version, "ckout" names its working files, reported as Working. Every other name, and "ckout" in a checkout with no version, resolves as ResolveVersion does, except that only check-ins can answer: the request is a check-in request, so a technote or wiki page carrying the tag does not.

As repo-state-00 Section 8.3 says, only "ci+" has the keyword, so ResolveVersion and Repo.ResolveBranchStart read "ckout" as an ordinary name. It is a keyword only as the whole name: in "root:ckout" or "ckout." the inner name is resolved as a plain check-in request, as in fossil.

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. A renamed file goes back to its committed name, whatever holds that name now. Each file it writes or deletes is saved for undo first, so Undo brings it back.

func (*Checkout) SetCone

func (c *Checkout) SetCone(next *Cone) (ConeChange, error)

SetCone replaces the checkout's cone; nil makes it dense. Files of the checked-out version that the new cone covers and the old one did not are written; files it no longer covers are removed from the working directory (the repository keeps them). It refuses, changing nothing, when a file leaving the cone has local changes or a file entering it would overwrite an untracked file. A cone with a horizon is refused with ErrHorizonCheckout.

func (*Checkout) SetConeContext

func (c *Checkout) SetConeContext(ctx context.Context, next *Cone, required RequiredContentOpts) (ConeChange, error)

SetConeContext recovers only structure needed to enumerate next and payloads newly entering the checkout. Explicit widening durably extends store coverage; an attempted fetch retains that intent even on failure. No-peer refusal does not change policy. Planning and local checks repeat before files move. A cone with a horizon is refused with ErrHorizonCheckout before anything moves.

func (*Checkout) Status

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

Status scans the working directory and returns the changed files, each classified as added, deleted, missing, renamed or modified, the way fossil's changes command classifies them. Wraps ScanChanges + VisitChanges.

func (*Checkout) Undo

func (c *Checkout) Undo() (UndoResult, error)

Undo reverses the last operation that saved undo state, such as Update, as fossil's undo does: the files it changed come back, and the checkout's file list and version are as they were before it. Fossil's undo reads the same state, so either tool can undo the other's update.

func (*Checkout) Update

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

Update moves the checkout to a new version as fossil's update does, carrying uncommitted changes into it: a locally edited file is merged three ways (the checkout's version as base, the working file as local, the target as other), one the target deletes is kept untracked, and pending adds and removals stay pending. See UpdateResult for how to distinguish a clean update from one that wrote conflict markers into working-tree files.

func (*Checkout) UpdateContext

func (c *Checkout) UpdateContext(ctx context.Context, opts UpdateOpts, required RequiredContentOpts) (UpdateResult, error)

UpdateContext recovers necessary structure and selected update payloads from an explicit peer before checkout mutation. An implicit target is resolved once; after recovery the local update replans against fresh working files.

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 checkout's version would create a fork: the version already has a child on its own branch (for example after a pull), so the commit would become a second leaf. This is fossil's "Would fork" commit refusal; run Update first, or commit to a new branch. Another open leaf elsewhere on the branch does not count.

type CheckoutChange

CheckoutChange describes a single file change in the checkout.

Change is "added", "modified", "deleted", "renamed" or "missing", or one of the mode changes fossil's changes command reports: "executable" (became executable), "symlink" (became a symlink), "unexec" (lost the executable bit) or "unlink" (was a symlink, now is not).

type CheckoutChange struct {
    Name   string
    Change string
}

type CheckoutCommitOpts

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 CheckoutCommitOpts struct {
    Message string
    User    string
    Branch  string   // empty = current branch
    Tags    []string // additional tag names
    Delta   bool
    // Files limits the commit to these checkout-relative paths; empty
    // commits every change.
    Files []string
    // AllowConflict commits files that still hold merge conflict markers,
    // which Checkin otherwise refuses, as fossil's commit does.
    AllowConflict bool
    // AllowEmpty commits even when nothing changed, which Checkin otherwise
    // refuses, as fossil's commit does.
    AllowEmpty bool
    // NoSign stores the check-in unsigned even when the repository's
    // clearsign setting is on (SettingClearsign): fossil's commit --nosign.
    NoSign bool
}

type CheckoutCreateOpts

CheckoutCreateOpts configures creating a new checkout.

type CheckoutCreateOpts struct {
    Env      *simio.Env       // nil = real env
    Observer CheckoutObserver // nil = nop
    // Cone makes the checkout sparse: Extract, Update and Status work only on
    // the files it covers, and Checkin carries the others from the parent
    // unchanged. nil is dense. A cone with a horizon is refused with
    // ErrHorizonCheckout. See Cone and Checkout.SetCone.
    Cone *Cone
}

type CheckoutMergeFile

CheckoutMergeFile reports what a merge did to one file. Action is one of:

"updated"  - only the merged-in version changed it; its content was taken
"merged"   - both sides changed it and the strategy combined them cleanly
"conflict" - merged with conflict markers written into the file
"kept"     - could not be merged; the checkout's copy is unchanged (see Reason)
"forked"   - the conflict-fork strategy recorded every version for later
"added"    - new in the merged-in version
"deleted"  - deleted in the merged-in version, unchanged here
"mode"     - only the merged-in version changed its executable bit; taken
"renamed"  - only renamed: the merged-in version renamed it, this checkout did not

Name is the file's name in the checkout before the merge. RenamedTo is set when the merge also renamed it, as fossil's merge does a file the merged-in version renamed and the checkout did not.

type CheckoutMergeFile struct {
    Name      string
    Action    string
    Strategy  string // the strategy that merged it, when one ran
    Reason    string // why the file was kept, for "kept"
    RenamedTo string // its new name, when the merge renamed it
}

type CheckoutMergeOpts

CheckoutMergeOpts configures Checkout.Merge.

type CheckoutMergeOpts struct {
    Version  int64  // rid of the checkin to merge in; required
    Strategy string // strategy for every file; "" picks one per file
    DryRun   bool   // report what the merge would do, changing nothing
}

type CheckoutMergeResult

CheckoutMergeResult reports a merge.

type CheckoutMergeResult struct {
    Ancestor int64               // the common ancestor the merge diffed against
    Files    []CheckoutMergeFile // sorted by name; empty when there was nothing to merge
}

type CheckoutObserver

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

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)
}

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

CheckoutOpenOpts configures opening an existing checkout.

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

type CheckpointMode

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

type CheckpointMode = db.CheckpointMode

type CloneOpts

CloneOpts configures a clone operation.

type CloneOpts struct {
    User     string
    Password string
    Observer SyncObserver
    Buggify  BuggifyChecker // fault injection for DST (nil = no faults)
    // PullPhantoms, when set, makes Clone fetch the artifacts the clone
    // rounds left missing with a follow-up pull session, and fail with an
    // error if any are still missing after it. That pull departs from
    // Section 8.2 of the sync draft, which sends no clone, pull or push card
    // after clone_seqno 0, so it is off by default: like fossil(1)'s clone,
    // Clone then succeeds with those artifacts left as phantoms.
    PullPhantoms bool
    // StoreCone, when non-nil, clones straight into a sparse store: only the
    // artifacts the cone covers are fetched, and the cone becomes the store's
    // policy. With a horizon (NewHorizonCone) it clones a content-horizon
    // store, eliding the blobs below the horizon; CloneResult.HorizonServed
    // counts the replies whose server cut at the horizon, the others being
    // classified locally. A server that will not serve a sparse clone
    // refuses it (SettingPartialMirror).
    StoreCone *Cone
    // SeedKey, when set, is the origin's public key, kept as the clone's
    // SettingHorizonSeedKey: every structural horizon seed is verified against
    // it, in this clone and every later pull and rebuild.
    SeedKey string
    // Horizon, when set, is the horizon to clone at, its Checkin a full hash
    // or a name: "tip", a branch or tag. HorizonDepth steps it back that
    // many check-ins along primary parents. A name, or any depth, is
    // resolved by the origin (draft-fossil-horizon-00 §6.2.7); against one
    // that does not, the clone resolves it over what it received at the
    // content horizon and says so in CloneResult. Only the resolved check-in
    // is stored. StoreCone then gives the path members alone: a horizon on
    // both is an error, as is a depth without a Horizon.
    Horizon      *Horizon
    HorizonDepth int
}

type CloneResult

CloneResult reports what happened during a clone.

type CloneResult struct {
    Rounds          int
    BlobsRecvd      int
    ArtifactsLinked int
    ProjectCode     string
    ServerCode      string
    Messages        []string
    // Elided counts the artifacts left absent under the store cone, and
    // ConeServed the replies whose server acknowledged applying it (pragma
    // cone-served, draft-fossil-sparse-cone-00 §6.3). Both are zero for a
    // dense clone.
    Elided, ConeServed int
    // HorizonServed counts the replies whose server served the store's
    // horizon (pragma horizon-served, draft-fossil-horizon-00 §6.2.5); the
    // other rounds were classified locally. StructuralServed counts those
    // served at the structural level, and HorizonFallback reports a
    // structural clone that kept the content horizon instead (§6.3).
    HorizonServed    int
    StructuralServed int
    HorizonFallback  bool
    // HorizonHistoryURL is the interface outside the sync protocol at which
    // the origin says history below a horizon can be queried (pragma
    // horizon-served URL, draft-fossil-horizon-00 §6.2.5), the last a reply
    // named; "" when none did. An origin names it with
    // SettingHorizonHistoryURL.
    HorizonHistoryURL string
    // HorizonResolved is the check-in CloneOpts.Horizon named resolved to and
    // HorizonSteps the steps back it took, fewer than HorizonDepth when
    // history ran out; HorizonResolvedLocally reports that the origin did
    // not resolve the name and the clone did, at the content horizon.
    HorizonResolved        string
    HorizonSteps           int
    HorizonResolvedLocally bool
}

type CommitEnd

CommitEnd describes the completion of a commit operation.

type CommitEnd struct {
    UUID string
    RID  int64
}

type CommitOpts

CommitOpts configures a commit operation.

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
    // NoSign stores the check-in unsigned even when the repository's
    // clearsign setting is on (SettingClearsign): fossil's commit --nosign.
    NoSign bool
}

type CommitStart

CommitStart describes the beginning of a commit operation.

type CommitStart struct {
    Comment string
    User    string
    Files   int
}

type Cone

Cone is a sparse checkout's cone (draft-fossil-sparse-cone-00 §3): a set of repository paths, each a directory subtree or a single file, included or excluded. The longest member covering a path decides whether the cone covers it, so an exclusion carves a part out of an inclusion, and a deeper inclusion re-includes part of an exclusion. Members are literal prefixes, never patterns. A Cone is immutable; With and Without return new ones.

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

func NewCone

func NewCone(include, exclude []string) (*Cone, error)

NewCone builds a cone from inclusion and exclusion members. Members are validated as tracked paths, sorted, and reduced to the minimal set with the same coverage, so input order never matters. It refuses an empty inclusion list, more than 255 members, an exclusion no inclusion covers, and a path given with both polarities.

func NewHorizonCone

func NewHorizonCone(include, exclude []string, h Horizon) (*Cone, error)

NewHorizonCone builds a cone with a horizon and optional path members. With no include members the cone is horizon-only: it covers every path and only the horizon narrows what is held. Checkin is normalized to lower case.

func (*Cone) Covers

func (c *Cone) Covers(path string) bool

Covers reports whether the cone covers path.

func (*Cone) Decide

func (c *Cone) Decide(path string) (covered bool, member string)

Decide reports whether the cone covers path and the member that decided: the longest member covering it, of either polarity, or "" when none does. Under longest match the deciding member is often not the first one listed, so naming it is what explains a verdict.

func (*Cone) Digest

func (c *Cone) Digest() string

Digest is the SHA3-256 of the cone's canonical serialization, in hex: equal for equal coverage, and the same value zit computes.

func (*Cone) Exclude

func (c *Cone) Exclude() []string

Exclude returns the exclusion members, sorted.

func (*Cone) Horizon

func (c *Cone) Horizon() (Horizon, bool)

Horizon returns the cone's horizon, if it has one.

func (*Cone) Include

func (c *Cone) Include() []string

Include returns the inclusion members, sorted.

func (*Cone) String

func (c *Cone) String() string

String lists the members in sorted order, an exclusion marked with '!'. A horizon leads, as "horizon <check-in> <rule> content".

func (*Cone) With

func (c *Cone) With(include, exclude []string) (*Cone, error)

With returns the cone with more members: the incremental form of widening (or, with exclusions, of narrowing).

func (*Cone) WithHorizon

func (c *Cone) WithHorizon(h *Horizon) (*Cone, error)

WithHorizon returns the cone with its horizon replaced by h, keeping the path members; nil drops the horizon. Dropping the horizon of a horizon-only cone is an error, since nothing is left: make the store dense with Repo.SetStoreCone(nil).

func (*Cone) Without

func (c *Cone) Without(paths []string) (*Cone, error)

Without returns the cone with every member equal to one of paths removed, of either polarity. A path that is not a member removes nothing.

type ConeChange

ConeChange reports what Checkout.SetCone did to the working directory.

type ConeChange struct {
    Materialized   []string // newly covered files written, sorted
    Dematerialized []string // newly uncovered files removed, sorted
}

type CreateOpts

CreateOpts configures repository creation.

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
}

type Cursor

Cursor is an opaque pagination token for Timeline. Obtain one from a returned TimelineEntry's Cursor field and pass it back as the next TimelineOpts.After to resume enumeration immediately after that entry. The zero Cursor means "start from the newest event".

Cursor's representation is deliberately hidden: it cannot be constructed from a timestamp and a rid by calling code, only obtained from a TimelineEntry the library already produced. See fsltype.Cursor's doc comment for why — a hand-built cursor derived from a rounded time.Time is not guaranteed to match the row it claims to follow exactly, which is what silently reintroduces skipped or duplicated rows at a page boundary. LogEntry, Ancestry's result type, has no Cursor field at all: Ancestry's pagination is by Start/Limit, so there is no valid cursor to obtain from it, and the type reflects that instead of documenting it as a hazard.

type Cursor = fsltype.Cursor

type DiffEntry

DiffEntry describes a unified diff for a single file.

type DiffEntry struct {
    Name    string
    Unified string
}

type EventKind

EventKind is the type discriminator on a Timeline entry: one of the single-letter codes fossil assigns per event.type row. The zero value means "all kinds" — the default Timeline uses when no Type is given.

type EventKind = fsltype.EventKind

const (
    // EventKindCheckin is a check-in ('ci').
    EventKindCheckin EventKind = fsltype.EventKindCheckin
    // EventKindTechnote is a technote / event artifact ('e').
    EventKindTechnote EventKind = fsltype.EventKindTechnote
    // EventKindForum is a forum post ('f').
    EventKindForum EventKind = fsltype.EventKindForum
    // EventKindTag is a tag/control artifact ('g').
    EventKindTag EventKind = fsltype.EventKindTag
    // EventKindTicket is a ticket change ('t').
    EventKindTicket EventKind = fsltype.EventKindTicket
    // EventKindWiki is a wiki page edit ('w').
    EventKindWiki EventKind = fsltype.EventKindWiki
)

type ExternalRef

ExternalRef names an attachment's bytes held outside the repository, in a bucket the host binds and keys attachments/<SHA256> (Quarry RFC 0016). The repository holds only a stub naming them; this library never reads or writes the bytes themselves.

type ExternalRef struct {
    // SHA256 is the bytes' SHA-256, 64 lowercase hex digits.
    SHA256 string `json:"sha256"`
    // Size is the bytes' length.
    Size int64 `json:"size"`
    // Type is the declared mimetype.
    Type string `json:"type"`
    // Name is the file's name, a bare name with no directory.
    Name string `json:"name"`
}

type ExtractEnd

ExtractEnd describes the completion of a checkout extraction.

type ExtractEnd struct {
    FilesWritten int
}

type ExtractOpts

ExtractOpts configures file extraction from a checkin.

type ExtractOpts struct {
    Force bool // overwrite uncommitted changes
    // Warn receives what fossil's checkout warns about and proceeds past:
    // a present R card that disagrees with the files the check-in names,
    // checked over every file, whatever the cone. nil discards warnings.
    Warn func(message string)
}

type ExtractStart

ExtractStart describes the beginning of a checkout extraction.

type ExtractStart struct {
    RID int64
    Dir string
}

type FileEntry

FileEntry describes a file in a manifest.

type FileEntry struct {
    Name string
    UUID string
    Perm string
}

type FileToCommit

FileToCommit describes a file to include in a commit. OldName, when set, records that the file was renamed from that name in the parent, as fossil's commit records a rename (the F card's old-name field).

UUID, when set, carries an artifact the repository already holds into the check-in by its name: the F card names it verbatim and nothing is read or stored, so a caller that knows a file's hash from ListFiles can carry it forward without its content. Content must be nil when UUID is set, and UUID must be a lowercase SHA1 or SHA3-256 hash. The artifact must be held, except under a store cone that elides it (draft-fossil-sparse-cone-00 §5.3); an unknown or phantom UUID fails the commit. This is what PartialManifest callers use to name the unchanged part of a tree without reading it.

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

type Fork

Fork describes a divergence point between two branches.

type Fork struct {
    Ancestor  int64
    LocalTip  int64
    RemoteTip int64
}

type FramedTransport

FramedTransport is an optional interface a Transport may also implement when it can report the framing signal — such as an HTTP Content-Type header — that accompanied a reply. Sync uses that signal to select the reply's §4 framing instead of assuming the §4.1 compressed container, which matters when the peer is a different Fossil-protocol implementation that legitimately replies with the uncompressed plain-card framing (e.g. a real Fossil server's clone reply).

It is optional in the same way http.Flusher is optional on an http.ResponseWriter: a Transport whose framing is fixed by convention (both ends always emit the compressed container) need not implement it, and sync falls back to assuming the compressed framing for such a Transport. Callers type-assert a Transport to FramedTransport and use RoundTripFramed when it is available. Reporting the signal as a return value keeps it per-call, with no shared mutable state to make a reused Transport unsafe across concurrent calls.

type FramedTransport interface {
    Transport
    // RoundTripFramed behaves like RoundTrip but also returns the framing
    // signal (e.g. the reply's Content-Type) the wire carried for this reply,
    // or "" when the transport observed none.
    RoundTripFramed(ctx context.Context, payload []byte) (resp []byte, contentType string, err error)
}

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

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

type FslID = fsltype.FslID

type FslSize

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

type FslSize = fsltype.FslSize

type HTTPOption

HTTPOption configures an HTTP transport.

type HTTPOption func(*httpTransport)

func WithHTTPClient

func WithHTTPClient(c *http.Client) HTTPOption

WithHTTPClient sets a custom http.Client for the transport.

type HandleEnd

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

type HandleEnd struct {
    FilesSent, FilesRecvd int
}

type HandleOpts

HandleOpts configures server-side sync handling.

type HandleOpts struct {
    Observer SyncObserver
    Buggify  BuggifyChecker
    // LoginCookie is the value of the request's x-f-l-c cookie, which
    // carries the login card once the client has seen a server-version
    // that reads it (§6.5). This server announces such a release, so fossil
    // and go-libfossil clients move their login there after the first
    // round: an embedder that serves HandleSyncWithOpts over HTTP must pass
    // the cookie through, or those rounds arrive as nobody. XferHandler and
    // ServeHTTP read it themselves.
    LoginCookie string
    // RemoteAddr is the address the request came from, recorded in the
    // rcvfrom row of whatever it pushes, as fossil records REMOTE_ADDR.
    // XferHandler and ServeHTTP fill it themselves.
    RemoteAddr string
    // MaxStoredBytes, when positive, is the most bytes one pushed artifact
    // may occupy as this repository stores it (compressed, and as a delta
    // when pushed as one). Set it when the host's storage caps a single
    // value: a push carrying a bigger artifact is refused whole with an
    // error naming the artifact, its stored size and the limit, and the
    // file and check-in when this repository already holds a check-in
    // listing it, so nothing from that request is stored, and
    // HandleSyncWithOpts returns a *RefusedError with that reply. 0, the
    // default, stores any size. Clones and pulls served from the repository
    // are not limited. XferHandler and ServeHTTP serve without a budget: a
    // host that needs one serves HandleSyncWithOpts itself.
    MaxStoredBytes int
}

type HandleStart

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

type HandleStart struct {
    RemoteAddr string
}

type Horizon

Horizon is the temporal member of a store cone (draft-fossil-horizon-00 §3.1): blobs only check-ins outside the held set name are elided. The zero value of Structural is the content horizon (§4), which keeps every manifest.

type Horizon struct {
    // Checkin is the check-in's full artifact hash, 40 or 64 hex digits; as
    // CloneOpts.Horizon it may also be a name the origin resolves.
    Checkin string
    Rule    HorizonRule
    // Structural takes the structural cut (§5): the manifests below the
    // check-in are elided too, and a seed the origin mints stands in for the
    // branch and tag state they carried. A clone or pull whose origin does
    // not serve it falls back to the content horizon and reports so.
    Structural bool
}

type HorizonRule

HorizonRule is the held-set rule a horizon names (draft-fossil-horizon-00 §3.1).

type HorizonRule int

const (
    // HorizonDescendants holds the check-in and every descendant of it. It is
    // the zero value.
    HorizonDescendants HorizonRule = iota
    // HorizonLeaves holds the descendants plus every open leaf's ancestry back
    // to its nearest common ancestor with the check-in. Choose it knowingly
    // (§3.1): it is what lets a client merge across live branches offline, and
    // it holds every descendant of where each childless check-in's history
    // meets the check-in's. On a repository with old unmerged branches that is
    // nearly the whole history: 20,907 of 21,008 check-ins of fossil-scm.org's.
    HorizonLeaves
)

func (HorizonRule) String

func (r HorizonRule) String() string

String names the rule as the operator spells it.

type HorizonRuleCost

HorizonRuleCost is what one rule would hold for a horizon at a check-in (draft-fossil-horizon-00 §3.4): the check-ins of the held set K and the blobs those check-ins' F cards name, the contents a clone at that horizon keeps.

type HorizonRuleCost struct {
    Rule          HorizonRule
    Checkins      int   // check-ins in K
    Blobs         int   // distinct blobs K's check-ins name, held here
    StoredBytes   int64 // what those blobs occupy in the repository, compressed and delta-encoded
    ExpandedBytes int64 // their sizes once expanded
}

type LogEntry

LogEntry represents a single event, as returned by Ancestry. Parents is populated for Kind == EventKindCheckin and empty for every other kind — plink, which Parents is derived from, only relates check-in artifacts, so that is correct, not a gap.

LogEntry carries no pagination cursor: Ancestry paginates by LogOpts.Start/Limit, not by cursor, so there would be nothing valid to put in one. See TimelineEntry, Timeline's result type, for the cursor-carrying counterpart — this split means an Ancestry entry's (necessarily invalid) cursor can no longer be obtained at all, let alone passed to Timeline by mistake.

type LogEntry struct {
    RID     int64
    UUID    string
    Comment string
    User    string
    Time    time.Time
    Kind    EventKind
    Parents []string
    // HorizonParents is the subset of Parents that the store's origin
    // labelled below its structural horizon: each is the horizon, not a
    // missing parent and not damage (draft-fossil-horizon-00 §5.4). Ancestry
    // ends at such a parent without an error.
    HorizonParents []string
}

type LogOpts

LogOpts configures an Ancestry query: a first-parent walk starting from a specific check-in.

type LogOpts struct {
    Start int64
    Limit int
}

type MergeConflict

MergeConflict describes a conflict region in a file.

type MergeConflict struct {
    Name      string
    StartLine int
    EndLine   int
}

type MergeConflictError

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

type MergeConflictError struct {
    Files []string
}

func (*MergeConflictError) Error

func (e *MergeConflictError) Error() string

func (*MergeConflictError) Is

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

type MergeResult

MergeResult describes the outcome of a merge.

type MergeResult struct {
    Clean     bool
    Conflicts []MergeConflict
}

type MockTransport

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

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

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 OriginNamer

OriginNamer is an optional interface a Transport may also implement to name the peer it addresses. Sync and Clone keep the horizon cursor of draft-fossil-horizon-00 §6.2.6 per origin under that name: "A client that converged records the cursor of the last reply together with the count of its own artifacts at the end of the exchange, per origin", and "A client holding a cursor for the origin it addresses sends it on every request, and MAY then announce nothing with igot on a pull-only request."

The name must identify the same peer across sessions and must carry no credential, since it is written into the repository's config table; the HTTP transport uses its URL with any password removed. A Transport that does not implement it, or returns "", keeps no cursor, and each of its pulls announces the client's whole holding with igot, which §6.2.6 allows.

type OriginNamer interface {
    Transport
    SyncOrigin() string
}

type PullOpts

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 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
}

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 RefusedError

RefusedError is the error HandleSyncWithOpts returns, beside the reply, when HandleOpts.MaxStoredBytes refused the request. Message is the text of the reply's one error card.

type RefusedError struct {
    Message string
}

func (*RefusedError) Error

func (e *RefusedError) Error() string

Error returns Message.

type Repo

Repo is an opaque handle to a Fossil repository.

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

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) Ancestry

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

Ancestry walks the primary-parent chain starting from opts.Start: it emits that check-in, follows plink where isprim=1 to its parent, and repeats until the chain ends or opts.Limit is reached. This only ever sees first-parent ancestors of opts.Start — a merge's second parent, a sibling branch head, or any check-in outside that one chain will never appear. Use Timeline for a repository-wide view.

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.

On a store whose cone has a horizon, lines the walk cannot attribute past the horizon are reported as originating at it, marked BelowHorizon; AnnotateContext fetches the history that attributes them on a content horizon store.

func (*Repo) AnnotateContext

func (r *Repo) AnnotateContext(ctx context.Context, opts AnnotateOpts, required RequiredContentOpts) ([]AnnotatedLine, error)

AnnotateContext is Annotate with a demand fetch: on a content-horizon store, each version of the file the walk reads below the horizon and the store does not hold is fetched from Peer as the walk reaches it, so only what the walk reads is fetched and lines are attributed to the check-ins below the horizon that added them. A walk needing more than one demand fetch's 200 payloads stops there and returns what it attributed, the rest marked BelowHorizon, as does a walk that crosses a structural horizon, since naming those check-ins is a deepen. A start check-in below the horizon is fetched as ReadFileContext fetches it.

func (*Repo) AttachmentAdd

func (r *Repo) AttachmentAdd(target, name string, content []byte, opts AttachmentOpts) (artifact string, err error)

AttachmentAdd attaches content to target under name, as `fossil attachment add` does, and returns the hash of the control artifact. content is stored as one ordinary blob; only name's final path component is kept. The attachment table and timeline reflect it when AttachmentAdd returns, and both artifacts are queued to sync. The attachment becomes the latest for name: a zero opts.Time stamps it after whatever is latest now, and an explicit one no later than that is refused.

target is a wiki page's exact name, or a ticket's or tech note's id or a unique prefix of it. Fossil is told the kind; here it is inferred, and a name more than one kind answers to is refused as ambiguous.

Content that is a well-formed external-attachment stub is refused, since it would read back as an external attachment rather than as the bytes given: use AttachmentAddExternal. Content that parses as a fossil artifact is compressed and its name gains ".gz", as fossil does.

func (*Repo) AttachmentAddExternal

func (r *Repo) AttachmentAddExternal(target string, ref ExternalRef, opts AttachmentOpts) (artifact string, err error)

AttachmentAddExternal attaches the file ref names without its bytes, and returns the hash of the control artifact. The blob stored is the stub Quarry writes, and the control artifact's N card carries ref.Type, so stock fossil shows a small text file under ref.Name. The host stores the bytes; this records only where they are found. target resolves as in AttachmentAdd.

func (*Repo) AttachmentDelete

func (r *Repo) AttachmentDelete(target, name string, opts AttachmentOpts) (artifact string, err error)

AttachmentDelete removes the current attachment name from target, as fossil's attachment page does: a new control artifact whose A card names no file. The bytes stay in history. It returns the artifact's hash, and ErrAttachmentNotFound when target has no current attachment by that name. opts.Time, when set, must be later than the attachment's; when zero, the deletion is stamped after it even if it lies in the future.

func (*Repo) AttachmentRead

func (r *Repo) AttachmentRead(target, name string) (a Attachment, content []byte, err error)

AttachmentRead returns target's current attachment name and its bytes. For an external attachment the bytes are not here: content is nil and a.External says where the host keeps them. It returns ErrAttachmentNotFound when there is no such current attachment.

func (*Repo) Attachments

func (r *Repo) Attachments(target string) ([]Attachment, error)

Attachments returns target's current attachments, the most recently attached first: one per name, leaving out deleted ones, as fossil lists them on the target's page. target resolves as in AttachmentAdd.

func (*Repo) BranchOpenLeaf

func (r *Repo) BranchOpenLeaf(name string) (rid int64, open bool, err error)

BranchOpenLeaf names one open leaf of the named branch (repo-state-00 Section 9): a check-in whose active branch tag is name, that is a leaf and that is not closed. When the branch has several, the one with the greatest event.mtime is returned, as the draft requires of any report that names a single open leaf. open is false, with a nil error, when the branch has no open leaf: it is not open. An empty name is an error, as in BranchTip; the main branch is named by CurrentTrunk and MainBranch.

Unlike BranchTip, which returns the branch's newest check-in whether or not it is a leaf or closed, this is fossil's `branch info` answer. fossil's query (branch_is_open, src/branch.c) takes whichever open leaf it meets first; this follows the draft's greatest-mtime rule.

func (*Repo) BranchTip

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

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) CommitContext

func (r *Repo) CommitContext(ctx context.Context, opts CommitOpts, required RequiredContentOpts) (int64, string, error)

CommitContext creates a commit, recovering required parent structure from Peer when necessary. Recovery runs without a write transaction and never broadens the store cone. The operation is retried once from the caller's original inputs after revalidating immutable parents and construction policy.

func (*Repo) CompactStore

func (r *Repo) CompactStore(ctx context.Context) (int, error)

CompactStore is the narrow-then-compact deletion (§5.4), the only one the sparse draft defines: it turns held blobs that only out-of-cone F cards name into elided phantoms and returns how many it dropped. Structural artifacts, sub-manifest nodes whose cards prove an elision, unsent or private content and the delta bases of retained artifacts stay held. A later widening fetches the dropped blobs again; it is not reversible locally.

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) CurrentTrunk

func (r *Repo) CurrentTrunk() (int64, error)

CurrentTrunk returns the current trunk (repo-state-00 Section 9): the check-in that the main-branch setting's name resolves to by ResolveVersion's procedure, "trunk" when the setting is unset. Only check-ins can answer, as in fossil's check-in request, so a technote tagged with the name does not. The setting is local and not synced, so two repositories holding the same artifacts can name different trunks. fossil resolves it the same way where it needs one: update outside a checkout (src/update.c, a "ci" request) and open with no version (src/db.c). A name that resolves to nothing returns ErrVersionNotFound (wrapped).

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) DeepenHorizon

func (r *Repo) DeepenHorizon(ctx context.Context, target string, required RequiredContentOpts) (*SyncResult, error)

DeepenHorizon moves the store cone's horizon to an ancestor C' of its C from which target is reachable, and synchronizes at C' through Peer (draft-fossil-horizon-00 §5.8): target itself when it is C's ancestor, else a common ancestor of the two, asked of the origin when the store cannot see one. The rule, the depth and the path members stay; nothing held is replaced. A structural store discards the seed for C before it takes the one for C', and a transfer that fails puts both back.

target is a full check-in hash, which may name a check-in the store does not hold, or any name ResolveVersion resolves. Deepening needs a Peer and a store cone with a horizon.

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) DiffContext

func (r *Repo) DiffContext(ctx context.Context, ridA, ridB int64, filePath string, required RequiredContentOpts) ([]DiffEntry, error)

DiffContext is Diff with ReadFileContext's demand fetch: what both sides lack below the horizon is fetched in one round.

func (*Repo) DisableSubmanifests

func (r *Repo) DisableSubmanifests() error

DisableSubmanifests turns tree manifest emission off: later commits are flat, and the pinned k is kept for a later EnableSubmanifests. Existing trees remain -- artifact names are immutable, so they cannot be retired -- and keep being served, though peers that do not announce sub-manifest support are still refused them. Unlike the CLI's disable, it returns no note saying so; an embedder that wants to tell its operator must do it itself.

func (*Repo) EnableSubmanifests

func (r *Repo) EnableSubmanifests(k int) (pinned int, warning string, err error)

EnableSubmanifests turns on tree manifest emission (draft-fossil-submanifests-00 §8.1): from the next commit, check-ins carry their file sets as sub-manifest trees. k is the partition parameter, 1 to 12, or 0 to select one. A valid pinned k is kept, and an explicit k that differs from it is refused: changing it is RetuneSubmanifests. A stored k outside 1..12 is no valid pin: an explicit k replaces it, and k = 0 is refused, naming the stored value. With no stored k, an explicit k is pinned, or one is selected as zit selects it: the §6.3 cost over one check-in's file set, refined by replaying recent history. The check-in analyzed is the current trunk (CurrentTrunk, the main-branch tip, which the next commit most plausibly descends from); when no check-in is on the main branch, it is the newest check-in by time, the highest rid breaking a tie. A request that cannot be met -- k outside 1..12, no check-in at all to select from, or a file set no k partitions -- changes neither setting. It returns the pinned k and the warning the operator must be shown: peers that do not announce sub-manifest support, every fossil among them, are refused trees, and trees cannot be retired.

func (*Repo) FindCommonAncestor

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

FindCommonAncestor finds the most recent common ancestor of two checkins, the merge base fossil's merge-base command names.

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.

When opts.MaxStoredBytes refuses the request, it returns both the encoded reply, which holds only the error card naming the artifact, and a *RefusedError carrying that card's text (match it with errors.As). The request was rolled back, so nothing from it is stored. A host serving the reply over HTTP sends it as usual, and the client prints the error; a host whose storage aborts the whole call on any rollback can report RefusedError.Message itself. Every other error returns a nil reply.

func (*Repo) HorizonCost

func (r *Repo) HorizonCost(checkin string) ([]HorizonRuleCost, error)

HorizonCost reports, for each rule in order (descendants, leaves), what a horizon at checkin would hold, so the choice of rule is made with its cost in view (§3.4). checkin is any name ResolveVersion accepts. The figures are read from this repository, which must hold the history: a blob it does not hold is left out of the byte counts, and a sub-manifest it lacks is an error.

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) ListFilesIn

func (r *Repo) ListFilesIn(rid int64, c *Cone) ([]FileEntry, error)

ListFilesIn is ListFiles narrowed to the files c covers; a nil cone lists every file. The cone is applied as a range predicate at the one enumeration seam every file set comes from (draft-fossil-sparse-cone-00 §4.1), so the result is ListFiles filtered by c.Covers, flat or tree, and a cone's horizon plays no part. On a tree manifest the walk skips every sub-manifest whose key range c cannot cover, so the cost follows the cone plus the spine rather than the whole tree (§4.5). Over a sparse store that makes it the listing that does not reach an elided out-of-cone node; a cone that reaches a node the store lacks still fails, naming it.

func (*Repo) ListUsers

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

ListUsers returns all users in the repository.

func (*Repo) Merge

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:

Files are matched across the three versions following renames, as fossil's merge matches them: a file srcBranch renamed and dstBranch did not takes srcBranch's name, and the commit records the rename; a file dstBranch renamed keeps its name.

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

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) ReadBlob

func (r *Repo) ReadBlob(uuid string) ([]byte, error)

ReadBlob returns the content of the artifact named uuid, a full SHA1 or SHA3-256 hash in lowercase hex, such as the UUID ListFiles reports for a file. An unknown hash returns ErrArtifactNotFound (wrapped). An artifact the store knows but does not hold, such as one elided below a horizon or outside a sparse cone, fails as ReadFile of a path naming it does.

func (*Repo) ReadFile

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

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) ReadFileAtContext

func (r *Repo) ReadFileAtContext(ctx context.Context, version string, filePath string, required RequiredContentOpts) ([]byte, error)

ReadFileAtContext is ReadFileAt with ReadFileContext's demand fetch. The version is resolved locally; a structural store resolves a check-in below its horizon by the full hash its phantom carries.

func (*Repo) ReadFileContext

func (r *Repo) ReadFileContext(ctx context.Context, rid int64, filePath string, required RequiredContentOpts) ([]byte, error)

ReadFileContext is ReadFile that, when the check-in's file lies below the store cone's horizon and the store does not hold it, fetches exactly the artifacts the read needs from Peer and reads again: the payload, and for a structural store first the check-in's manifest, baseline and nodes. This is the targeted demand fetch of draft-fossil-horizon-00 §4.4: the store cone and its horizon do not move, and what is fetched is held content a later CompactStore may drop. Without a Peer the read fails as ReadFile does, matching ErrBelowHorizon and naming the horizon. A read needing more than one demand fetch carries is refused; DeepenHorizon is its remedy.

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) ResolveBranchStart

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

ResolveBranchStart resolves name as ResolveVersion does, then returns the first check-in of the branch the result is on: fossil's branch-type ("br") request (repo-state-00 Section 8.3), the start of the branch rather than the check-in its name most recently points at. As Section 8.3 requires, the request is rewritten to a check-in request first: only check-ins can match, so a technote tagged with the branch name does not shadow the branch.

Section 8.3 walks back from the result of every form. fossil(1) walks only from a "tag:NAME" or plain-name result (symbolic_name_to_rid, src/name.c), so there a hash, "tip" or a date names the check-in itself; this follows the draft.

func (*Repo) ResolveConflictFork

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

ResolveConflictFork marks a conflict-fork entry as resolved.

func (*Repo) ResolveVersion

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

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

It follows fossil's symbolic_name_to_rid (src/name.c) for the forms go-libfossil supports, in fossil's order:

  1. "tip" — newest check-in by event.mtime. "" is treated as "tip".
  2. "rid:N" — the literal RID N, when that artifact exists.
  3. "tag:NAME" — the check-in carrying sym-NAME with the greatest event.mtime (forces a tag lookup even for a hex NAME).
  4. "root:BR" / "start:BR" / "merge-in:BR" — the origin, first check-in, or most recent merge-in of branch BR (BR itself resolved recursively).
  5. "NAME:TIMESTAMP" — the check-in carrying sym-NAME with the greatest event.mtime at or before TIMESTAMP (UTC).
  6. Artifact hash or 4–64 char hex prefix — unique match against blob.uuid, tried before a plain tag; more than one match is ambiguous.
  7. Plain symbolic name — the check-in carrying sym-NAME with the greatest event.mtime (resolves "trunk" and branch names).
  8. Trailing-punctuation retry — a name pasted from prose that ends in one or two punctuation characters is retried without them.

No match returns ErrVersionNotFound (wrapped); a hex prefix matching more than one artifact returns ErrAmbiguousVersion (wrapped).

The names relative to an open checkout ("current", "prev", "next") are ordinary names here, as in fossil outside a checkout; Checkout's ResolveVersion resolves them.

func (*Repo) RetuneSubmanifests

func (r *Repo) RetuneSubmanifests(k int) error

RetuneSubmanifests pins a new partition parameter k, 1 to 12, for the commits that follow (draft-fossil-submanifests-00 §6.4). It is forward only: existing check-ins are unchanged, and the next tree shares only the sub-manifests whose bytes are the same under both values.

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.

Requests are authorized against the user table: one without a login card gets nobody's capabilities, which in a new repository allow clone and pull but not push. Grant more with SetCaps. Like XferHandler it serves with default HandleOpts, so no HandleOpts.MaxStoredBytes budget applies.

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. A SettingHorizonSeedKey value that is neither an SSH public key nor an OpenPGP fingerprint is refused.

func (*Repo) SetContentCache

func (r *Repo) SetContentCache(bytes int64)

SetContentCache attaches a cache of expanded artifact content, bounded by bytes, that ReadFile, ReadFileAt, ReadBlob, ListFiles, ListFilesIn, Diff and Annotate share. It replaces any cache already attached; bytes <= 0 detaches it. The default is no cache. It is safe to call while other goroutines read.

The bound covers expanded content; the parses of the few check-in manifests read most recently are kept beside it. Any write through this Repo empties the cache. A write by another process, or through another Repo opened on the same file, does not: attach a cache only where this Repo is the store's one writer, or where no other writer purges, compacts or narrows it.

func (*Repo) SetHashPolicy

func (r *Repo) SetHashPolicy(name string) error

SetHashPolicy sets the repository's hash policy by name, as `fossil hash-policy NEW-POLICY` does. name must be exactly one of sha1, auto, sha3, sha3-only or shun-sha1: the match is case-sensitive, and any other string is an error that leaves the policy unchanged. Asking for auto in a repository that already holds a SHA3-named artifact sets sha3.

func (*Repo) SetPassword

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

SetPassword updates a user's password.

func (*Repo) SetStoreCone

func (r *Repo) SetStoreCone(c *Cone) error

SetStoreCone replaces the store cone; nil makes the store dense. It moves no content. Narrowing deletes nothing (§5.4). Widening makes the newly covered elided phantoms wanted again, and the next pull fetches them. While a cone is set, a commit carries no R card (§4.3).

A cone may carry a horizon (draft-fossil-horizon-00): setting one elides blobs only check-ins below it name, and SetStoreCone moves no content, as for any narrowing. Setting an older check-in, or nil, widens, and SetStoreConeContext fetches what the deeper horizon keeps.

func (*Repo) SetStoreConeContext

func (r *Repo) SetStoreConeContext(ctx context.Context, next *Cone, required RequiredContentOpts) (*SyncResult, error)

SetStoreConeContext is the policy form of demand fetch (draft-fossil-sparse-cone-00 §6.4): it replaces the store cone and, when that makes elided artifacts wanted again, pulls them from Peer through an ordinary cone-scoped synchronization. With artifacts to fetch and no Peer it refuses, naming the elided count and the missing peer, and leaves the cone unchanged. A transfer that fails after the cone is replaced keeps the wider policy, so the next ordinary pull heals it. Narrowing needs no peer.

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) StoreCone

func (r *Repo) StoreCone() (*Cone, error)

StoreCone returns the repository's store cone, or nil when the store is dense. A store cone (draft-fossil-sparse-cone-00 §5) is local policy: an artifact the cone leaves out may be deliberately absent, an elided phantom, which synchronization does not request and verification counts apart from damage. A cone this version cannot read is lost policy and reads as nil, so the store heals toward dense.

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 artifact. Returns the UUID of the tag control artifact.

As `fossil tag add` does, a name with a reserved prefix ("wiki-", "tkt-", "event-") is refused, and when the target is a check-in the name is placed in the symbolic namespace with a "sym-" prefix so it resolves as a tag in commands such as update and merge; other artifact types keep the name bare. Pass the raw name: fossil prefixes the raw name, so "x" becomes "sym-x" and "sym-x" becomes "sym-sym-x" on a check-in.

func (*Repo) TicketAdd

func (r *Repo) TicketAdd(opts TicketOpts) (ticketUUID, artifact string, err error)

TicketAdd creates a ticket, as `fossil ticket add` does, and returns its new id and the hash of the artifact that created it. The ticket table reflects it when TicketAdd returns, and the artifact is queued to sync.

func (*Repo) TicketChanges

func (r *Repo) TicketChanges(ticket string) ([]TicketChange, error)

TicketChanges returns the changes of the ticket whose id is or starts with ticket, oldest first: the order fossil applies them in, as `fossil ticket history` lists them.

func (*Repo) TicketList

func (r *Repo) TicketList() ([]Ticket, error)

TicketList returns every ticket, the most recently changed first.

func (*Repo) TicketSet

func (r *Repo) TicketSet(ticket string, opts TicketOpts) (artifact string, err error)

TicketSet changes the ticket whose id is or starts with ticket, as `fossil ticket set` does, and returns the hash of the change artifact.

func (*Repo) Timeline

func (r *Repo) Timeline(opts TimelineOpts) ([]TimelineEntry, error)

Timeline enumerates the repository's events newest-first: every row of the event table by default, or just the rows matching opts.Type when set (canonical `fossil timeline`'s -t/--type default: no filter unless one is given). Unlike Ancestry, this does not start from or require any particular check-in — it is a repository-wide view, not a walk.

Ordering is (mtime DESC, rid DESC), a total order with rid as a true tie-break at exact mtime equality — a deliberate improvement over canonical fossil, which orders by mtime DESC alone with no tie-break, and paginates with a bare-timestamp web cursor carrying a one-second slop, so rows at a page boundary there can repeat or be skipped. Do not "fix" this back to canonical: it is intentional. To page through the full result set, pass the last entry's Cursor back as the next call's TimelineOpts.After — never construct a cursor from a TimelineEntry's Time by hand; see Cursor's doc comment for why that round trip is lossy.

func (*Repo) TimelineSince

func (r *Repo) TimelineSince(hash string, kinds ...EventKind) ([]TimelineEntry, error)

TimelineSince returns the timeline entries whose artifacts arrived in this repository after the artifact with full hash hash: stored by a later receipt (a later push, pull or local write), or later within the same one. kinds, when given, keeps only entries of those kinds. The entries are in Timeline's order, newest first; an empty result is an empty slice, not nil. A hash the repository does not hold is an error.

Arrival, not timestamp, is what "after" means, because the question this answers is what a push brought in: an artifact made on a machine whose clock runs behind the given artifact's still arrived after it. Arrival order is this repository's own, so two clones can answer differently.

func (*Repo) UUIDFromRID

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) VerifySeed

func (r *Repo) VerifySeed(ctx context.Context, required RequiredContentOpts) (*SeedVerification, error)

VerifySeed verifies a structural store's seed by deepening (draft-fossil-horizon-00 §5.9): it fetches every manifest below the horizon from Peer, so the store holds the real tag artifacts and primary-parent chains, discards the seed, and compares what the store now derives at each entry with what the seed asserted. The price is that history, and the store stays a content-horizon store at the same C, which holds no seed; a failed transfer puts the structural cone and seed back.

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). It serves with default HandleOpts, so no HandleOpts.MaxStoredBytes budget applies.

type RequiredContentOpts

RequiredContentOpts authorizes read-only recovery from an explicit peer. Neither the peer nor credentials are saved. A nil Peer keeps the operation local. Sync accepts authentication, project/server identity, Pull and Private; push, unversioned, extension-table and link-sharing options are refused. Existing context-free operations never discover or contact a peer.

type RequiredContentOpts struct {
    Peer Transport
    Sync SyncOpts
}

type RevertOpts

RevertOpts configures reverting file changes.

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

type RoundStats

RoundStats describes the outcome of a single sync round.

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

type ScanEnd

ScanEnd describes the completion of a working-tree scan.

type ScanEnd struct {
    FilesScanned int
}

type SeedMismatch

SeedMismatch is one tag on which a seed and the derivation disagree at a check-in. Seeded and Derived spell the tag as a T card does, sign then value ("*red", "+"), and are "" where it is absent.

type SeedMismatch struct {
    Checkin, Tag, Seeded, Derived string
}

type SeedVerification

SeedVerification reports VerifySeed: how many of the seed's T cards were checked, and each tag at an entry of the held set where the seed and the derivation over real artifacts disagree.

type SeedVerification struct {
    Checked    int
    Mismatches []SeedMismatch
}

type SessionEnd

SessionEnd describes the completion of a sync session.

type SessionEnd struct {
    Rounds, FilesSent, FilesRecvd int
}

type SessionStart

SessionStart describes the beginning of a sync session.

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

type StashEntry

StashEntry describes a saved stash.

type StashEntry struct {
    ID      int64
    Comment string
    Time    string
}

type StatusEntry

StatusEntry describes a changed file in the working tree.

type StatusEntry struct {
    Name   string
    Change string
}

type SyncObserver

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

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)
}

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

SyncOpts configures a sync operation.

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
    // ShareLinks is fossil's --share-links mode (§9.5): a pulling session
    // asks the server for the URLs of other copies of the repository and
    // keeps each valid one as config link:URL. Off by default.
    ShareLinks bool
    Observer   SyncObserver
    Buggify    BuggifyChecker
}

type SyncResult

SyncResult describes the outcome of a sync session.

type SyncResult struct {
    Rounds       int
    FilesSent    int
    FilesRecvd   int
    UVFilesSent  int
    UVFilesRecvd int
    UVGimmesSent int
    BytesSent    int64
    BytesRecvd   int64
    Errors       []string
    // Elided counts the artifacts left absent under the store cone, and
    // ConeServed the replies whose peer acknowledged applying it (pragma
    // cone-served, draft-fossil-sparse-cone-00 §6.3); the rest of a sparse
    // store's rounds were served densely and filtered locally.
    Elided, ConeServed int
    // HorizonServed counts the replies whose peer served the store's
    // horizon (pragma horizon-served, draft-fossil-horizon-00 §6.2.5); the
    // other rounds were classified locally. StructuralServed counts those
    // served at the structural level, and HorizonFallback reports a
    // structural store that fell back to the content horizon for good (§6.3).
    HorizonServed    int
    StructuralServed int
    HorizonFallback  bool
    // HorizonHistoryURL is the interface outside the sync protocol at which
    // the origin says history below a horizon can be queried (pragma
    // horizon-served URL, draft-fossil-horizon-00 §6.2.5), the last a reply
    // named; "" when none did. An origin names it with
    // SettingHorizonHistoryURL.
    HorizonHistoryURL string
}

type TableSyncEnd

TableSyncEnd describes the completion of a config table sync.

type TableSyncEnd struct {
    Table               string
    RowsSent, RowsRecvd int
}

type TableSyncStart

TableSyncStart describes the beginning of a config table sync.

type TableSyncStart struct {
    Table string
}

type TagOpts

TagOpts configures a tag operation.

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

type TagSpec

TagSpec describes a tag to attach to an artifact.

type TagSpec struct {
    Name  string
    Value string
}

type Ticket

Ticket is one ticket as the ticket table holds it after every change.

type Ticket struct {
    UUID   string `json:"uuid"`
    Status string `json:"status"`
    // Changed is the time of the ticket's latest change.
    Changed time.Time `json:"changed"`
    // Fields holds every ticket-table field that has a value.
    Fields map[string]string `json:"fields"`
}

type TicketChange

TicketChange is one change artifact of a ticket.

type TicketChange struct {
    // Artifact is the change artifact's hash.
    Artifact string    `json:"artifact"`
    User     string    `json:"user"`
    Time     time.Time `json:"time"`
    // Comment is the remark the change added, or "".
    Comment string `json:"comment"`
    // Fields holds the change's fields exactly as written, the remark's
    // included: "+name" for an append.
    Fields map[string]string `json:"fields"`
}

type TicketOpts

TicketOpts is one change to a ticket.

type TicketOpts struct {
    // Fields maps a ticket field (a column of the repository's ticket
    // schema: title, status, type, resolution, comment, ...) to its new
    // value. A "+name" key appends the value to the field instead. A field
    // with an empty value is left out, as `fossil ticket` leaves it out.
    Fields map[string]string
    // User is the change's author, its U card.
    User string
    // Comment, when not empty, is a remark added with the change, stored as
    // the stock ticket forms store one: the icomment field, with login and
    // username set to User and mimetype text/plain.
    Comment string
    // Time is the change's D card; zero means now.
    Time time.Time
}

type TimelineEntry

TimelineEntry represents a single event as returned by Timeline. It extends LogEntry with Cursor, the pagination token for this row: pass it back as the next call's TimelineOpts.After to resume enumeration immediately after this entry. Cursor is always valid (Cursor.Valid() == true) on every TimelineEntry Timeline produces.

TimelineEntry values should come from Timeline, not be hand-assembled. A TimelineEntry built by embedding a LogEntry from Ancestry carries a zero-value Cursor, which Timeline treats as "start from newest" rather than as an error.

type TimelineEntry struct {
    LogEntry
    Cursor Cursor
}

type TimelineOpts

TimelineOpts configures a Timeline query: a repository-wide enumeration of the event table.

type TimelineOpts struct {
    // Type restricts the enumeration to a single event kind. The zero
    // value means "all kinds" — the canonical `fossil timeline` default.
    Type EventKind
    // After, when valid, resumes enumeration immediately following this
    // cursor — the next page after whatever TimelineEntry produced it. The
    // zero Cursor means "start from the newest event". See Repo.Timeline's
    // doc comment for the pagination contract this forms, and Cursor's doc
    // comment for why it must come from a TimelineEntry rather than be
    // built by hand.
    After Cursor
    // Limit caps the number of entries returned. Zero or negative means
    // unbounded.
    Limit int
}

type Transport

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

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

func NewHTTPTransport

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

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

type TransportFunc

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

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

func (TransportFunc) RoundTrip

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

RoundTrip calls the function.

type UVEntry

UVEntry describes an unversioned file.

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

type UndoResult

UndoResult reports the working files Undo or Redo changed, each list in the order they were changed, fossil's order. Fossil's undo prints them as UNDO (or REDO), NEW and DELETE lines; a caller shows them as it likes.

type UndoResult struct {
    FilesRestored []string // existing files given back their saved content
    FilesCreated  []string // files written that were not on disk
    FilesRemoved  []string // files deleted from the working tree
}

type UpdateChange

UpdateChange classifies how a file changed.

type UpdateChange string

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

type UpdateOpts

UpdateOpts configures updating to a new version with merge.

type UpdateOpts struct {
    // TargetRID is the check-in to update to. 0 picks it as fossil's update
    // does with no version named: the newest open leaf descended from the
    // checkout on its branch. Update fails when several such leaves remain.
    TargetRID int64
}

type UpdateResult

UpdateResult reports what Update actually did. Paths, not counts: a caller needs to know which files to show a user, not merely how many changed. All three slices are sorted (sort.Strings) before Update returns, so the order is deterministic — safe for golden-file tests or reflect.DeepEqual — rather than depending on Go's randomized map iteration order.

Outcome mapping (Update's error return is the other half of this):

clean       - err == nil, Conflicted empty
conflicted  - err == nil, Conflicted non-empty
failed      - err != nil, UpdateResult is the zero value

A non-empty Conflicted means three-way merge could not resolve those files cleanly and wrote "<<<<<<<"-style conflict markers directly into them on disk. That is NOT an error — Update still returns a nil error, because the update itself succeeded and the working tree is usable; it just isn't clean. A caller that only checks the returned error gets today's pre-conflict-detection behavior. A caller that needs to warn a user about marker text in their files must check Conflicted. Every path in Conflicted also appears in FilesWritten: the marker text is what was written there.

Unmerged lists files left for the caller to reconcile that hold no markers: a file edited locally that the target deletes (kept on disk, no longer tracked), a file added both locally and by the target (the local file kept, so it shows as edited), a binary file both sides changed (the target's content written, the working copy saved as NAME-original), and a file edited locally that the target renamed without changing it (left under its old name, untracked; the new name shows as missing, as in fossil). Like Conflicted, it is not an error.

type UpdateResult struct {
    FilesWritten []string // paths written (added, updated, or merged, clean or not); includes every Conflicted path
    FilesRemoved []string // paths deleted from the working tree
    Conflicted   []string // paths that now contain conflict markers — not an error; also present in FilesWritten
    Unmerged     []string // paths left to reconcile without markers — not an error
    // OutOfCone counts the changes a sparse checkout's update applied to files
    // outside its cone: recorded for the next checkin, never written to disk.
    OutOfCone int
}

type User

User describes a Fossil user.

type User struct {
    Login string
    Caps  string
}

type UserOpts

UserOpts configures a user creation or update.

type UserOpts struct {
    Login    string
    Password string
    Caps     string
}

type WorkingVersion

WorkingVersion is the answer of a checkout-inclusive request: a check-in, or the checkout's working files.

type WorkingVersion struct {
    // RID is the check-in the name resolves to. When Working is set it is
    // the checkout's version, the check-in the working files started from.
    RID int64
    // Working reports that the name was "ckout": the request asks for the
    // files on disk, edits included, rather than for any stored check-in.
    Working bool
}

Generated by gomarkdoc