Documentation
¶
Overview ¶
Package git defines the Go-facing contract for the native Git engine.
Only internal/git2 implements this contract with real libgit2. Higher packages consume Engine and Repository through this seam, so tests can substitute a deterministic fake without native calls. The seam is a contract, not a second Git implementation.
Index ¶
- Constants
- Variables
- func CheckUniqueNames(entries []TreeEntry) error
- func ImportPack(repo Repository, data []byte) error
- func MarkShallow(repo Repository, head OID) error
- func SortTreeEntries(entries []TreeEntry)
- func ValidateCommitMessage(message string) error
- func ValidateContent(data []byte) error
- func ValidateFoldedDirectories(snap Snapshot) error
- func ValidateHistory(repo Repository, head, shallow OID) error
- func ValidatePath(path string) error
- func ValidateSnapshot(snap Snapshot) error
- type Commit
- type CommitSpec
- type Conflict
- type DiffStat
- type Engine
- type EntrySet
- func (s EntrySet) ChangedUnder(local, base Snapshot) []string
- func (s EntrySet) CoveringEntry(path string) (string, bool)
- func (s EntrySet) Covers(path string) bool
- func (s EntrySet) Entries() []string
- func (s EntrySet) Pin(local, base Snapshot) Snapshot
- func (s EntrySet) ReadCovered(repo Repository, tree OID) (Snapshot, error)
- type Features
- type File
- type FileMode
- type FileStat
- type IndexEntry
- type MarkerRange
- type MergeFileResult
- type MergeIndex
- type MergeResult
- type NativeError
- type OID
- type OverlapError
- type Pack
- type PathCollisionError
- type PathPolicy
- func (p PathPolicy) ChangedProtected(repo Repository, local, base OID) ([]string, error)
- func (p PathPolicy) Configured() bool
- func (p PathPolicy) Protects(path string) bool
- func (p PathPolicy) ReadOnly() []string
- func (p PathPolicy) RestoreProtected(repo Repository, base OID, local Snapshot, changed []string) (Snapshot, error)
- func (p PathPolicy) Writable() []string
- type Repository
- type Snapshot
- type TreeEntry
- type UnsupportedModeError
- type VersionMismatchError
Constants ¶
const ( AuthorName = "slivingdoc" AuthorEmail = "slivingdoc@localhost" )
AuthorName and AuthorEmail form the fixed commit identity in architecture/git-engine.md. Every commit uses it; there is no user-configurable identity.
Variables ¶
var ( // ErrNoNewObjects reports an increment export with nothing to publish. ErrNoNewObjects = errors.New("no new objects") // ErrObjectMissing reports notebook content the local object store // cannot supply: absent, or present but unreadable. Both are repaired by // re-importing the verified packs that carry it, so every failed object // read in this package carries it (architecture/pull.md). ErrObjectMissing = errors.New("object missing from the object store") // ErrEmptyPack reports an import of zero bytes. ErrEmptyPack = errors.New("empty pack") // ErrHeadRequired reports a boundary operation with no commit. ErrHeadRequired = errors.New("commit is required") )
Named engine failures. A caller-facing layer can only describe a cause it can identify, so every failure this package can classify itself carries one of these. Anything else is driver prose of unbounded shape and stays internal (architecture/product-contract.md).
var ErrInvalidOID = errors.New("git: invalid object id")
ErrInvalidOID reports a string that is not a Git SHA-1 object ID in its canonical form.
Functions ¶
func CheckUniqueNames ¶ added in v0.2.0
CheckUniqueNames refuses tree entries that repeat a name. A tree builder replaces an entry on a repeated insert, so a file and a directory of one name would silently lose one of them. Every Repository.WriteTree runs it, the native boundary and the test fakes alike.
func ImportPack ¶
func ImportPack(repo Repository, data []byte) error
ImportPack validates and imports a complete pack into the repository object store. A truncated pack or a corrupt trailer fails without importing any of its objects. Pack bytes are already validated against the manifest SHA-256 by the storage layer before this call.
func MarkShallow ¶
func MarkShallow(repo Repository, head OID) error
MarkShallow records a commit as a shallow history boundary: its parent commits can be absent. A checkpoint pack imports into an empty repository because it intentionally omits pre-checkpoint history; MarkShallow declares exactly that gap.
func SortTreeEntries ¶
func SortTreeEntries(entries []TreeEntry)
SortTreeEntries sorts entries in place into canonical Git tree order. Test fakes in higher packages use it so their tree ordering can never drift from BuildTree's.
func ValidateCommitMessage ¶
ValidateCommitMessage rejects messages the native commit call cannot store faithfully: they must be valid UTF-8 without U+0000. The check runs before any native mutation.
func ValidateContent ¶
ValidateContent rejects content that is not valid UTF-8 text without the U+0000 character (architecture/workspace.md). Bytes and line endings are preserved; nothing is normalized.
func ValidateFoldedDirectories ¶ added in v0.2.0
ValidateFoldedDirectories rejects a file whose name folds, under Unicode case folding, to the name of a directory of another path (`P` beside `p/x.md`). The exact case is ValidateSnapshot's. It applies to new content only: the visible scan runs it, and a commit refuses a merged state that would publish a new pair (FoldedDirectoryPairs), while accepted remote state and merge results are otherwise checked at the exact rule alone, so a notebook an older writer published with such a pair stays readable (architecture/git-engine.md).
func ValidateHistory ¶
func ValidateHistory(repo Repository, head, shallow OID) error
ValidateHistory walks every commit reachable from head and verifies that the commit chain and the complete tree closure resolve. The single permitted gap is the declared shallow boundary: the parents of shallow can be missing because the checkpoint pack omits them intentionally. Any other missing commit, tree, or blob fails the walk.
One seen set spans the whole walk. Consecutive generations share almost all of their trees and blobs, so an already-proven subtree short-circuits at its root OID and the walk costs the number of unique objects, not commits times files. An OID names one object whatever its type, so commits, trees, and blobs share the set safely.
func ValidatePath ¶
ValidatePath validates one normalized internal path against the architecture 7.1 rules: valid UTF-8 in NFC form, slash-separated relative segments, bounded lengths, no control characters, no reserved characters, no trailing space or dot, no `.`/`..`/`.git` segments, and no Windows device names. A path must not start or end with a slash and must not contain an empty segment.
func ValidateSnapshot ¶
ValidateSnapshot validates every path and content of a snapshot and rejects paths that collide under Unicode case folding, and a file whose exact name is also a directory of another path. The check runs against the full snapshot because collisions only exist between two different paths.
Types ¶
type Commit ¶
Commit is the Go-facing view of a Git commit object: its tree, parent chain, and message. The engine always writes the fixed slivingdoc identity, so that identity is not part of the value.
type CommitSpec ¶
CommitSpec describes a commit for the engine to create. Author and committer are the fixed slivingdoc identity; Time is the operation-attempt start time and is stored in UTC with one-second precision and offset zero.
type Conflict ¶
type Conflict struct {
Path string
Content []byte
Ranges []MarkerRange
}
Conflict describes one conflicted path after a three-tree merge. Content holds the conflict-marker text for text conflicts and is nil for file/directory conflicts; Ranges lists every complete marker block in Content.
type DiffStat ¶ added in v0.1.4
DiffStat is the complete line-change summary between two snapshots: one FileStat per path whose line content changed, sorted by path, and the totals across all files. A path whose comparison lines are unchanged — including byte-different content that splits to the same lines, such as a CRLF-to-LF rewrite — contributes no entry.
func DiffSnapshots ¶ added in v0.1.4
DiffSnapshots compares two notebook snapshots line by line and returns the per-file insertion and deletion counts of a deterministic shortest edit script.
base and cur are compared by normalized relative path. A path present only in cur counts every line as an insertion; a path present only in base counts every line as a deletion; a byte-identical path is omitted; a path with different bytes is diffed line by line. Files is sorted by path, and Insertions and Deletions are the sums across Files.
Line counting follows the notebook line rule: a line is an LF-terminated run of bytes with one trailing CR stripped for comparison and counting, a final run without a trailing LF counts as one line, content ending in LF has no phantom empty final line, and empty content has zero lines.
The function is pure: it never validates content or paths (snapshots are validated upstream) and never touches a repository or the filesystem.
type Engine ¶
type Engine interface {
Open() error
Close() error
Version() (string, error)
Features() (Features, error)
CreateRepo(path string) (Repository, error)
OpenRepo(path string) (Repository, error)
}
Engine is the lifecycle and capability view of the native Git engine.
Open must succeed before any other call, and the caller owns Close. A runtime libgit2 release that differs from the pinned release refuses to open with a VersionMismatchError.
type EntrySet ¶ added in v0.1.19
type EntrySet struct {
// contains filtered or unexported fields
}
EntrySet is a normalized, sorted set of notebook path entries, held by one side of a PathPolicy (architecture/product-contract.md, Read-only and writable paths). An entry covers itself and every path below it, matched under the same case folding as ValidateSnapshot. The zero value is the empty set.
func NormalizeEntries ¶ added in v0.1.19
NormalizeEntries validates each entry with ValidatePath after trimming one trailing slash, drops entries covered by another entry, and sorts the rest. The error names the invalid entry.
func (EntrySet) ChangedUnder ¶ added in v0.1.19
ChangedUnder returns, sorted, every covered path that differs between local and base (added, removed, or different bytes).
func (EntrySet) CoveringEntry ¶ added in v0.1.19
CoveringEntry returns the longest entry covering path. A set can hold an entry below another when the other policy set splits them, so the most specific match is the one that decides.
func (EntrySet) Pin ¶ added in v0.1.19
Pin returns local with its covered files replaced by base's covered files, sorted by path.
func (EntrySet) ReadCovered ¶ added in v0.1.19
func (s EntrySet) ReadCovered(repo Repository, tree OID) (Snapshot, error)
ReadCovered reads only the covered files of tree, descending into a subtree only when it is covered or contains an entry, and validates the result like ReadSnapshot.
type Features ¶
type Features struct {
Threads bool // thread-aware and safe from multiple threads
HTTPS bool // HTTPS remotes
SSH bool // SSH remotes
NSEC bool // sub-second index timestamp resolution
HTTPParser bool // HTTP parsing (always available)
Regex bool // regular expression support (always available)
I18N bool // filename translation support
AuthNTLM bool // NTLM authentication over HTTPS
AuthNegotiate bool // Kerberos (SPNEGO) authentication over HTTPS
Compression bool // zlib support (always available)
SHA1 bool // SHA-1 object support
SHA256 bool // SHA-256 object support
}
Features is the compiled feature set of the native engine.
func FeaturesFromMask ¶
FeaturesFromMask decodes a libgit2 feature bitmask into Features.
type FileMode ¶
type FileMode uint32
FileMode is a Git tree-entry file mode. Slivingdoc accepts exactly two modes — regular files (100644) and directories (040000) — and rejects every other mode on every host (architecture/git-engine.md).
type FileStat ¶ added in v0.1.4
FileStat is the per-file line-change summary of a snapshot diff: the normalized internal path and its insertion and deletion counts.
type IndexEntry ¶
IndexEntry is one entry of a merge index: a path with its stage. Stage 0 marks a resolved entry; stages 1, 2, and 3 mark the base, local, and remote variants of a conflict.
type MarkerRange ¶
MarkerRange identifies one complete conflict-marker block inside a file. Rows are one-based and inclusive, counted from the first line of the file.
func FindConflictBlocks ¶
func FindConflictBlocks(data []byte) []MarkerRange
FindConflictBlocks returns the one-based, inclusive row ranges of every complete, non-nested conflict-marker block in data. A complete block is exactly the lines `<<<<<<< local`, `=======`, and `>>>>>>> remote` at column zero in that order. LF and CRLF line endings are accepted and the line terminator is ignored during comparison. A block whose signature differs in any character is ordinary text. A nested opener inside a block is content, so scanning resumes after the closing line.
type MergeFileResult ¶
MergeFileResult is the result of a file-level three-way merge. When Automergeable is false, Content carries conflict-marker text with the exact `local` and `remote` labels.
type MergeIndex ¶
type MergeIndex struct {
Tree OID
Entries []IndexEntry
}
MergeIndex is the raw result of a three-tree merge: the resolved tree when the merge is conflict-free and every index entry (resolved and conflicted) for conflict reporting. Tree is the zero OID when the index contains conflicts.
type MergeResult ¶
type MergeResult struct {
Tree OID
Index MergeIndex
Conflicts []Conflict
}
MergeResult is the policy-level result of a three-tree merge. Tree is the merged tree (the zero OID when the merge has conflicts); Index carries the raw merge index so callers can materialize the full conflicted result; Conflicts describes every conflicted path in the merged result.
func Merge ¶
func Merge(repo Repository, base, local, remote OID) (MergeResult, error)
Merge performs a three-tree merge of base, local, and remote trees with the pinned libgit2: local change is base -> local, remote change is base -> remote, and the result merges both. When the merge is conflict-free it returns the merged tree; otherwise it returns structured conflicts with conflict-marker content and one-based marker ranges for every text conflict. A text conflict below a file/directory conflict whose local side is a file is not reported (dropBelowLocalFiles). A conflict never creates a commit.
type NativeError ¶
NativeError preserves a failed libgit2 operation together with the native error detail. The detail is copied at failure time, so the error stays valid after the native handles are released.
func (*NativeError) Error ¶
func (e *NativeError) Error() string
type OID ¶
type OID [20]byte
OID is a Git object identifier (SHA-1).
func BuildTree ¶
func BuildTree(repo Repository, snap Snapshot) (OID, error)
BuildTree writes one deterministic tree for a snapshot: blobs use mode 100644, trees use mode 040000, and every level is sorted by Git tree order. The same normalized snapshot always produces the same tree OID.
func CreateCommit ¶
func CreateCommit(repo Repository, spec CommitSpec) (OID, error)
CreateCommit creates a commit with the supplied message, tree, and zero or more parents. The engine writes the fixed slivingdoc identity and the spec time in UTC with one-second precision and offset zero. A root commit has no parents; a normal commit has exactly the observed remote head as its single parent.
func EmptyTree ¶
func EmptyTree(repo Repository) (OID, error)
EmptyTree returns the empty tree, creating it in the repository on first use. Pull uses the empty tree as the merge base for the first pull.
func ParseOID ¶
ParseOID parses a Git object ID in the canonical v1 form: exactly 40 lowercase hexadecimal characters (architecture/storage.md). Uppercase hex and any other representation are rejected.
func (OID) IsZero ¶
IsZero reports whether the OID is the all-zero object ID, which no valid Git object has.
func (OID) MarshalJSON ¶
MarshalJSON renders the canonical 40-character lowercase hexadecimal text form as a JSON string. The manifest encoder relies on it to store Git object IDs in their normative shape (architecture/storage.md).
type OverlapError ¶ added in v0.1.19
OverlapError reports one path named by both sets, the only composition with no unambiguous resolution.
func (*OverlapError) Error ¶ added in v0.1.19
func (e *OverlapError) Error() string
type Pack ¶
Pack is an exported Git pack: the exact pack bytes, the SHA-256 of those bytes, and the number of objects the pack contains. The SHA-256 is the pack-integrity checksum the storage layer records in manifest descriptors (architecture/storage.md).
func ExportCheckpoint ¶
func ExportCheckpoint(repo Repository, head OID) (Pack, error)
ExportCheckpoint exports a state-complete checkpoint pack: the checkpoint commit, its complete tree closure, and every referenced blob. Commit ancestors before the checkpoint are intentionally omitted, so the pack imports into an empty repository. The caller records the head as the shallow history boundary with MarkShallow.
func ExportIncrement ¶
func ExportIncrement(repo Repository, head, base OID) (Pack, error)
ExportIncrement exports one incremental pack containing exactly the objects reachable from head that are not already reachable from base. Importing the pack into a repository that holds base reconstructs head. The descriptor of the pack must identify base as the exact indexed base.
type PathCollisionError ¶ added in v0.1.15
type PathCollisionError struct {
First string
Path string
Fold bool // true when the collision is only under case folding
Dir bool // true when First is a file that is also a directory of Path
}
PathCollisionError reports two snapshot paths that collide, exactly or under case folding (Fold). Path is the second occurrence. With Dir set, First is a file and Path lies below a directory of the same name, so the one name would be both a file and a directory.
func FoldedDirectoryPairs ¶ added in v0.2.0
func FoldedDirectoryPairs(snap Snapshot) []PathCollisionError
FoldedDirectoryPairs returns every pair ValidateFoldedDirectories would refuse, in snapshot order: First is the file, Path a path below a directory whose name folds to the file's.
func (*PathCollisionError) Error ¶ added in v0.1.15
func (e *PathCollisionError) Error() string
type PathPolicy ¶ added in v0.1.19
type PathPolicy struct {
// contains filtered or unexported fields
}
PathPolicy answers, for one process, which notebook paths may be written and which changes to protected paths an operation must refuse or restore (architecture/product-contract.md, Read-only and writable paths). The two entry sets compose by longest match; the unmatched default is writable while the writable set is empty and protected once it is not. The zero value is unconfigured and protects nothing.
func NewPolicy ¶ added in v0.1.19
func NewPolicy(readOnly, writable []string) (PathPolicy, error)
NewPolicy normalizes each set and refuses a path named by both. The overlap test runs over the entries as the operator wrote them, before each set drops its own covered entries, so an entry named by both settings is refused whatever else its set contains. Coverage across the sets is kept, not collapsed: a writable entry below a read-only entry is the composition the operator is expressing. Each set is collapsed against the other for the same reason — an entry the other set splits from its own-set ancestor still decides paths the ancestor does not, so it survives and the collapsed sets resolve exactly as the written ones do (architecture/product-contract.md, Read-only and writable paths).
func (PathPolicy) ChangedProtected ¶ added in v0.1.19
func (p PathPolicy) ChangedProtected(repo Repository, local, base OID) ([]string, error)
ChangedProtected returns, sorted, every protected path that differs between the local and base trees. It descends only where subtree IDs differ and reads no blob: a differing blob is proved by its differing object ID.
func (PathPolicy) Configured ¶ added in v0.1.19
func (p PathPolicy) Configured() bool
Configured reports whether either set is non-empty.
func (PathPolicy) Protects ¶ added in v0.1.19
func (p PathPolicy) Protects(path string) bool
Protects reports whether path may not be written. The longest entry across both sets decides; with no match the answer is the unmatched default. The longest match is unique: within a set covering resolves the longest entry, and two matches of equal folded length across the sets would be the same folded string, which NewPolicy refuses. The answer is the one the entries the operator wrote give, since the collapse drops only an entry its own-set ancestor decides for (README invariant 5).
func (PathPolicy) ReadOnly ¶ added in v0.1.19
func (p PathPolicy) ReadOnly() []string
ReadOnly returns a copy of the normalized read-only entries; never nil. The collapse keeps every entry resolution needs, so the pair of accessors is a lossless input to NewPolicy: a policy rebuilt from them protects exactly the same paths, which is what lets a process carry its two sets as entries rather than as a policy value (architecture/product-contract.md, Read-only and writable paths).
func (PathPolicy) RestoreProtected ¶ added in v0.1.19
func (p PathPolicy) RestoreProtected(repo Repository, base OID, local Snapshot, changed []string) (Snapshot, error)
RestoreProtected returns local with each named path taken from base: a path absent from local is added back, one absent from base is dropped, and a local directory standing where base holds a file is removed with it. It reads only the named paths.
func (PathPolicy) Writable ¶ added in v0.1.19
func (p PathPolicy) Writable() []string
Writable returns a copy of the normalized writable entries; never nil, and a lossless input to NewPolicy as ReadOnly's entries are.
type Repository ¶
type Repository interface {
WriteBlob(data []byte) (OID, error)
// ReadBlob returns the raw object bytes for the given ID. Policy
// callers pass IDs of blob-mode tree entries; the engine does not
// interpret the object type.
ReadBlob(id OID) ([]byte, error)
// HasObject reports whether the object store holds the given ID,
// without reading the object content. History validation proves
// blob presence with it; a full ReadBlob would inflate every blob
// only to discard the bytes.
HasObject(id OID) (bool, error)
// ReadCommit returns the tree, parent chain, and message of a commit.
ReadCommit(id OID) (Commit, error)
// ReadTree returns the entries of a tree in Git tree order.
ReadTree(id OID) ([]TreeEntry, error)
// WriteTree writes a tree from its entries. Entries must use modes
// accepted by the native boundary and distinct names (CheckUniqueNames);
// the boundary sorts defensively.
WriteTree(entries []TreeEntry) (OID, error)
// CreateCommit writes a commit with the fixed slivingdoc identity and
// the spec time in UTC with one-second precision and offset zero.
CreateCommit(spec CommitSpec) (OID, error)
// MergeTrees merges three explicit trees without history-based
// merge-base discovery. Tree in the result is the zero OID when the
// index contains conflicts.
MergeTrees(base, local, remote OID) (MergeIndex, error)
// MergeFile performs a file-level three-way merge with the exact
// `local` and `remote` conflict-marker labels. An empty side stands
// for a deleted file.
MergeFile(base, local, remote []byte) (MergeFileResult, error)
// WritePack writes one complete pack containing exactly the listed
// objects and returns the number of objects it contains. The pack has
// no external delta bases.
WritePack(objects []OID, w io.Writer) (int, error)
// ImportPack validates and imports a complete pack into the
// repository object store.
ImportPack(data []byte) error
// MarkShallow records a commit as a shallow history boundary: its
// parents can be absent.
MarkShallow(oid OID) error
Close() error
}
Repository is an open local repository. All methods are safe for concurrent use; Close releases the native resources deterministically.
The interface exposes only narrow native operations. Policy — snapshot validation, deterministic tree building, conflict structuring, pack planning, and history validation — lives in the functions of this package (BuildTree, ReadSnapshot, Merge, ExportIncrement, and so on).
type Snapshot ¶
type Snapshot struct {
Files []File
}
Snapshot is a complete file snapshot: an ordered set of normalized, slash-separated relative paths with their content. BuildTree and ReadSnapshot sort the files by path, so a snapshot is deterministic for the same set of paths.
func MaterializeTree ¶
func MaterializeTree(repo Repository, res MergeResult, local OID) (Snapshot, error)
MaterializeTree builds the complete materialized snapshot of a merge result. A conflict-free result reads its merged tree. A conflicted result materializes the full index: resolved stage-0 entries keep their merged blobs and text conflicts carry their marker content. A file/directory conflict shows the local side in both directions, read from the local tree rather than from index stages: the local file when the remote side made the path a directory, the local subtree when the local side did. The remote side is omitted there and stays only in R. local is the tree that was merged as the local side. The returned snapshot is the exact visible state a caller must see, so a conflict never loses the caller's local intent (architecture/conflicts.md).
func ReadSnapshot ¶
func ReadSnapshot(repo Repository, tree OID) (Snapshot, error)
ReadSnapshot reads a complete UTF-8 text-file snapshot from a tree. It rejects unsupported modes, unsafe path names, and invalid content while walking, so a corrupt or hostile pack fails before any caller sees its state. The returned snapshot is sorted by path.
type TreeEntry ¶
TreeEntry is one entry of a Git tree object: a single path segment with its mode and object ID. Callers store entries in Git tree order; the native boundary re-sorts defensively on write.
type UnsupportedModeError ¶ added in v0.1.17
UnsupportedModeError reports a tree entry whose file type the notebook cannot store. Name is the entry name within its directory, never an absolute path, so it is safe to show the caller.
func (*UnsupportedModeError) Error ¶ added in v0.1.17
func (e *UnsupportedModeError) Error() string
type VersionMismatchError ¶
VersionMismatchError reports a runtime libgit2 release that differs from the pinned release the binary was built and tested against.
func (*VersionMismatchError) Error ¶
func (e *VersionMismatchError) Error() string
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package gittest holds the deterministic object hashing shared by the fake Repository implementations in higher packages (internal/workspace, internal/notebook).
|
Package gittest holds the deterministic object hashing shared by the fake Repository implementations in higher packages (internal/workspace, internal/notebook). |