lfs

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Mar 6, 2026 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package lfs provides a pure-HTTP client for the Git LFS Batch API. No git-lfs binary required. Uses the batch API for blob upload/download.

The client implements the Git LFS Batch API spec: https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ComputeOID

func ComputeOID(content []byte) string

ComputeOID computes the SHA256 hex digest of content (the LFS OID).

func DownloadObject

func DownloadObject(action *Action) ([]byte, error)

DownloadObject downloads a single blob using the action href.

func FormatPointer added in v0.3.0

func FormatPointer(oid string, size int64) string

FormatPointer returns canonical LFS pointer file content for the given OID and size. OID must include the "sha256:" prefix (matching FileRef.OID convention).

Per spec: version line first, then remaining keys in alphabetical order. "oid" < "size" lexicographically, so the ordering is: version, oid, size. Each line is "key SP value LF" with Unix line endings (\n, not \r\n).

func IsPointerFile added in v0.3.0

func IsPointerFile(path string) bool

IsPointerFile reports whether the file at path is an LFS pointer. Returns false for missing files, content files, or read errors. Detection is by content format (version + oid + size), not by filename or .gitattributes — matching how git-lfs itself identifies pointers.

func ParsePointer added in v0.3.0

func ParsePointer(content string) (oid string, size int64, err error)

ParsePointer parses LFS pointer file content and returns the OID and size. Returns an error if the content is not a valid LFS pointer.

Per spec: version line must appear first; remaining keys ("oid", "size") are in alphabetical order. Unknown keys (e.g. "ext-0-*") are silently ignored, allowing forward compatibility with spec extensions.

func UpdateMetaSummary added in v0.2.0

func UpdateMetaSummary(sessionPath, summary string) error

UpdateMetaSummary reads meta.json from sessionPath, updates the Summary field, and re-writes it atomically. Used by push-summary to replace the local summary with the AI-generated title.

func UploadObject

func UploadObject(action *Action, content []byte) error

UploadObject uploads a single blob using the action href from the batch response.

func WritePointerFile added in v0.3.0

func WritePointerFile(path string, ref FileRef) error

WritePointerFile writes a standard LFS pointer file at path. Replaces any existing file (content is already uploaded to LFS).

func WritePointerFiles added in v0.3.0

func WritePointerFiles(dir string, files map[string]FileRef) ([]string, error)

WritePointerFiles writes LFS pointer files for each entry in files. Keys are filenames written as dir/<key>. Returns sorted absolute paths of written files. Both sessions and imports use this to create the standard git-lfs pointer files that prevent garbage collection.

func WriteSessionMeta

func WriteSessionMeta(sessionPath string, meta *SessionMeta) error

WriteSessionMeta writes meta.json to the given session directory. When meta.Files is populated, also replaces content files with LFS pointer files (standard git-lfs naming). Pointer write failures are non-fatal — session data is safe in LFS + meta.json regardless.

Types

type Action

type Action struct {
	Href      string            `json:"href"`
	Header    map[string]string `json:"header,omitempty"`
	ExpiresIn int               `json:"expires_in,omitempty"` // seconds
	ExpiresAt string            `json:"expires_at,omitempty"` // RFC3339
}

Action is a single LFS action with an href and optional headers.

type Actions

type Actions struct {
	Upload   *Action `json:"upload,omitempty"`
	Download *Action `json:"download,omitempty"`
	Verify   *Action `json:"verify,omitempty"`
}

Actions contains the upload/download actions returned by the batch API.

type BatchObject

type BatchObject struct {
	OID  string `json:"oid"`  // SHA256 hex digest
	Size int64  `json:"size"` // bytes
}

BatchObject identifies a single LFS object by its SHA256 OID and size.

type BatchResponse

type BatchResponse struct {
	Transfer string                `json:"transfer"` // "basic"
	Objects  []BatchResponseObject `json:"objects"`
}

BatchResponse is the server response from the batch API.

type BatchResponseObject

type BatchResponseObject struct {
	OID           string       `json:"oid"`
	Size          int64        `json:"size"`
	Authenticated bool         `json:"authenticated,omitempty"`
	Actions       *Actions     `json:"actions,omitempty"`
	Error         *ObjectError `json:"error,omitempty"`
}

BatchResponseObject is a single object in the batch response.

type Client

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

Client communicates with a Git LFS Batch API server (e.g., GitLab).

func NewClient

func NewClient(repoURL, username, token string) *Client

NewClient creates an LFS client for the given git repo URL. repoURL should be the git clone URL (e.g., https://git.sageox.io/sageox/ledger.git). Auth uses HTTP Basic per the Git LFS spec: username:token base64-encoded.

func (*Client) BatchDownload

func (c *Client) BatchDownload(objects []BatchObject) (*BatchResponse, error)

BatchDownload requests download URLs for the given objects.

func (*Client) BatchUpload

func (c *Client) BatchUpload(objects []BatchObject) (*BatchResponse, error)

BatchUpload requests upload URLs for the given objects.

type DownloadResult

type DownloadResult struct {
	OID     string
	Content []byte
	Error   error
}

DownloadResult tracks the outcome of a single download.

func DownloadAll

func DownloadAll(resp *BatchResponse, maxConcurrent int) []DownloadResult

DownloadAll downloads multiple blobs in parallel. Returns results for every object so callers can see all errors, not just the first.

type FileRef

type FileRef struct {
	OID  string `json:"oid"`  // "sha256:<hex>"
	Size int64  `json:"size"` // bytes
}

FileRef identifies a content file by its LFS OID and size.

func NewFileRef

func NewFileRef(content []byte) FileRef

NewFileRef creates a FileRef from content bytes.

func ReadPointerFile added in v0.3.0

func ReadPointerFile(path string) (FileRef, error)

ReadPointerFile reads and parses an LFS pointer file, returning the FileRef.

func (FileRef) BareOID

func (f FileRef) BareOID() string

BareOID returns the hex digest without the "sha256:" prefix.

type HydrationStatus

type HydrationStatus string

HydrationStatus describes whether a session's content files are present locally.

const (
	// HydrationStatusHydrated means all content files are present locally.
	HydrationStatusHydrated HydrationStatus = "hydrated"
	// HydrationStatusDehydrated means no content files are present (only meta.json).
	HydrationStatusDehydrated HydrationStatus = "dehydrated"
	// HydrationStatusPartial means some content files are present.
	HydrationStatusPartial HydrationStatus = "partial"
)

func CheckHydrationStatus

func CheckHydrationStatus(sessionPath string, meta *SessionMeta) HydrationStatus

CheckHydrationStatus checks which content files are present as real content (not LFS pointers) for a session. Files that are missing or contain only an LFS pointer are considered dehydrated.

type ObjectError

type ObjectError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

ObjectError is returned when the server cannot process an object.

type SessionMeta

type SessionMeta struct {
	Version     string             `json:"version"` // "1.0"
	SessionName string             `json:"session_name"`
	Username    string             `json:"username"` // email of author
	UserID      string             `json:"user_id,omitempty"`
	AgentID     string             `json:"agent_id"`
	AgentType   string             `json:"agent_type"` // "claude-code", "cursor", etc.
	Model       string             `json:"model,omitempty"`
	Title       string             `json:"title,omitempty"`
	CreatedAt   time.Time          `json:"created_at"`
	EntryCount  int                `json:"entry_count,omitempty"`
	Summary     string             `json:"summary,omitempty"`
	RepoID      string             `json:"repo_id,omitempty"`
	Files       map[string]FileRef `json:"files"` // OID manifest: filename -> ref
}

SessionMeta is the git-tracked metadata + OID manifest for a session. Stored as meta.json in each session folder. When Files is populated, WriteSessionMeta also writes LFS pointer files (standard git-lfs naming) to replace content files, preventing LFS garbage collection.

func ReadSessionMeta

func ReadSessionMeta(sessionPath string) (*SessionMeta, error)

ReadSessionMeta reads meta.json from the given session directory.

type SessionMetaBuilder added in v0.2.0

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

SessionMetaBuilder constructs SessionMeta with required fields and optional setters.

func NewSessionMeta added in v0.2.0

func NewSessionMeta(sessionName, username, agentID, agentType string, createdAt time.Time) *SessionMetaBuilder

NewSessionMeta creates a builder with required fields pre-filled.

func (*SessionMetaBuilder) Build added in v0.2.0

func (b *SessionMetaBuilder) Build() *SessionMeta

Build returns the constructed SessionMeta.

func (*SessionMetaBuilder) EntryCount added in v0.2.0

func (b *SessionMetaBuilder) EntryCount(n int) *SessionMetaBuilder

func (*SessionMetaBuilder) Model added in v0.2.0

func (*SessionMetaBuilder) RepoID added in v0.2.0

func (*SessionMetaBuilder) Summary added in v0.2.0

func (*SessionMetaBuilder) Title added in v0.2.0

func (*SessionMetaBuilder) UserID added in v0.2.0

func (*SessionMetaBuilder) WithFiles added in v0.2.0

func (b *SessionMetaBuilder) WithFiles(f map[string]FileRef) *SessionMetaBuilder

type UploadResult

type UploadResult struct {
	OID   string
	Error error
}

UploadResult tracks the outcome of a single upload.

func UploadAll

func UploadAll(resp *BatchResponse, files map[string][]byte, maxConcurrent int) []UploadResult

UploadAll uploads multiple blobs in parallel. files maps OID -> content. Uses objects from the batch response to find upload actions.

Jump to

Keyboard shortcuts

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