gitpack

package
v0.8.1 Latest Latest
Warning

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

Go to latest
Published: Sep 29, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package gitpack answers one question about a buffered git-receive-pack request: which paths would this push change, with what file modes and sizes? It is a pure library: no sockets, no config, no fetching the base objects a thin pack refers to — a push is judged from its own bytes only. Enforcement belongs to the caller.

The answer is deliberately one-sided the safe way: a new commit with no pre-image in the pack has its whole tree enumerated and OVER-reports (over-reporting is safe for a deny rule, under-reporting is not); an uncarried directory is reported as one opaque entry, never skipped; Result.Settle removes commits the caller says the receiver already holds; and a removal is invisible, since this package reports what a push INTRODUCES, not what it takes away.

Everything else that would make the answer a guess is a refusal: ErrUninspectable for a pack missing what an answer needs (a thin pack's delta bases); ErrTooLarge for a pack that costs more than the ceilings below allow; a plain error for a malformed or hostile one.

Ceilings bound one inspection's heap beyond the buffered body to about 232 MiB total (maxInflatedBytes + per-object bookkeeping + maxChanges). How many inspections run at once is the caller's to cap.

Index

Constants

View Source
const ModeUncarried = "40000"

ModeUncarried is the Mode of a Change that stands for a directory whose tree object the pack does not hold. No other Change carries a directory mode: a directory the pack does carry is reported as the entries beneath it.

Variables

View Source
var ErrTooLarge = errors.New("gitpack: the push exceeds an inspection ceiling")

ErrTooLarge reports that the request carries everything an answer needs but costs more than one of this package's ceilings allows; the fix is on the sender's side, push fewer commits at a time.

View Source
var ErrUninspectable = errors.New("gitpack: the push cannot be inspected from its own bytes")

ErrUninspectable reports that the request is well formed but does not carry what an answer would need. A first-class result, not a failure: an agent image cloning shallow makes a push whose bases live on the remote ordinary.

Functions

This section is empty.

Types

type Change

type Change struct {
	// Path is slash-separated and relative to the repository root; "" only
	// for an uncarried root tree.
	Path string
	// Mode is the tree entry's mode verbatim ("100644", "100755" executable,
	// "120000" symlink, "160000" submodule pointer); ModeUncarried for an
	// uncarried directory.
	Mode string

	// OID is the object id the tree entry names: an entry whose mode and OID
	// match the same path in a commit the push builds on is unchanged.
	OID string
	// contains filtered or unexported fields
}

Change is one path a push introduces, at the mode and size the pushed tree gives it.

func (Change) Carried

func (c Change) Carried() bool

Carried reports whether the pack holds the object c names; one it does not is content the receiving side already stores.

func (Change) Opaque

func (c Change) Opaque() bool

Opaque reports whether a checkout may hold paths beneath c.Path that no Change names (an uncarried directory, symlink, or submodule). A rule about a path beneath an opaque entry must treat it as matched, not absent.

func (Change) Size

func (c Change) Size() (int64, bool)

Size is the blob's size in bytes, and false when unknown. Returns a pair so a comparison against a limit doesn't compile until the caller decides what unknown means.

func (Change) Within

func (c Change) Within(limit int64) bool

Within reports whether c's blob is known to be at most limit bytes; an unknown size is never within.

type Command

type Command struct {
	// Old and New are object ids in the request's object format; New is all
	// zeros when the command deletes the ref.
	Old, New string
	Ref      string
}

Command is one ref update from the request's command section.

type Result

type Result struct {
	// ObjectFormat is "sha1" or "sha256", as the capability list declared.
	ObjectFormat string
	// Commands are the ref updates, in wire order.
	Commands []Command
	// Changes are the paths the push introduces, sorted and deduplicated.
	Changes []Change
	// Bases are the commits the push builds on: every parent a pack commit
	// names that the pack doesn't carry, sorted and deduplicated. TRUST
	// BOUNDARY: a commit may name ANY object id as its parent, so a caller
	// must establish for itself that a base belongs to trusted history.
	Bases []string
	// contains filtered or unexported fields
}

Result is what one receive-pack request would change.

func Inspect

func Inspect(body []byte) (Result, error)

Inspect reads a buffered git-receive-pack request body (pkt-line command section, then packfile) and reports what the push would change. The caller must have bounded the body before buffering it.

On any error the Result is empty: a partial answer read as a whole one is the failure this package exists to avoid.

func (Result) Settle

func (r Result) Settle(held func(commit string) (bool, error)) (Result, error)

Settle is the same answer with the history the receiving side already holds taken out. held reports whether one commit the pack carries is already in trusted history; a held commit introduces nothing, and a commit built on one is diffed against it and joins Bases. held is asked as little as possible, and a commit once found new is never taken as held.

Jump to

Keyboard shortcuts

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