Documentation ¶
Overview ¶
Package packfile implements encoding and decoding of packfile format.
== pack-*.pack files have the following format: - A header appears at the beginning and consists of the following: 4-byte signature: The signature is: {'P', 'A', 'C', 'K'} 4-byte version number (network byte order): GIT currently accepts version number 2 or 3 but generates version 2 only. 4-byte number of objects contained in the pack (network byte order) Observation: we cannot have more than 4G versions ;-) and more than 4G objects in a pack. - The header is followed by number of object entries, each of which looks like this: (undeltified representation) n-byte type and length (3-bit type, (n-1)*7+4-bit length) compressed data (deltified representation) n-byte type and length (3-bit type, (n-1)*7+4-bit length) 20-byte base object name compressed delta data Observation: length of each object is encoded in a variable length format and is not constrained to 32-bit or anything. - The trailer records 20-byte SHA1 checksum of all of the above.
Source: https://www.kernel.org/pub/software/scm/git/docs/v1.7.5/technical/pack-protocol.txt
Index ¶
- Constants
- Variables
- func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) error
- func DiffDelta(src, tgt []byte) []byte
- func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, error)
- func PatchDelta(src, delta []byte) ([]byte, error)
- func UpdateObjectStorage(s storer.EncodedObjectStorer, packfile io.Reader) error
- type Decoder
- func (d *Decoder) Close() error
- func (d *Decoder) Decode() (checksum plumbing.Hash, err error)
- func (d *Decoder) DecodeObject() (plumbing.EncodedObject, error)
- func (d *Decoder) DecodeObjectAt(offset int64) (plumbing.EncodedObject, error)
- func (d *Decoder) Index() *Index
- func (d *Decoder) SetIndex(idx *Index)
- type Encoder
- type Error
- type Format
- type Index
- type ObjectHeader
- type ObjectToPack
- func (o *ObjectToPack) BackToOriginal()
- func (o *ObjectToPack) CleanOriginal()
- func (o *ObjectToPack) Hash() plumbing.Hash
- func (o *ObjectToPack) IsDelta() bool
- func (o *ObjectToPack) IsWritten() bool
- func (o *ObjectToPack) MarkWantWrite()
- func (o *ObjectToPack) SaveOriginalMetadata()
- func (o *ObjectToPack) SetDelta(base *ObjectToPack, delta plumbing.EncodedObject)
- func (o *ObjectToPack) SetOriginal(obj plumbing.EncodedObject)
- func (o *ObjectToPack) Size() int64
- func (o *ObjectToPack) Type() plumbing.ObjectType
- func (o *ObjectToPack) WantWrite() bool
- type Scanner
- func (s *Scanner) Checksum() (plumbing.Hash, error)
- func (s *Scanner) Close() error
- func (s *Scanner) Flush() error
- func (s *Scanner) Header() (version, objects uint32, err error)
- func (s *Scanner) NextObject(w io.Writer) (written int64, crc32 uint32, err error)
- func (s *Scanner) NextObjectHeader() (*ObjectHeader, error)
- func (s *Scanner) SeekFromStart(offset int64) (previous int64, err error)
Constants ¶
const ( // VersionSupported is the packfile version supported by this package VersionSupported uint32 = 2 )
Variables ¶
var ( // ErrMaxObjectsLimitReached is returned by Decode when the number // of objects in the packfile is higher than // Decoder.MaxObjectsLimit. ErrMaxObjectsLimitReached = NewError("max. objects limit reached") // ErrInvalidObject is returned by Decode when an invalid object is // found in the packfile. ErrInvalidObject = NewError("invalid git object") // ErrPackEntryNotFound is returned by Decode when a reference in // the packfile references and unknown object. ErrPackEntryNotFound = NewError("can't find a pack entry") // ErrZLib is returned by Decode when there was an error unzipping // the packfile contents. ErrZLib = NewError("zlib reading error") // ErrCannotRecall is returned by RecallByOffset or RecallByHash if the object // to recall cannot be returned. ErrCannotRecall = NewError("cannot recall object") // ErrResolveDeltasNotSupported is returned if a NewDecoder is used with a // non-seekable scanner and without a plumbing.ObjectStorage ErrResolveDeltasNotSupported = NewError("resolve delta is not supported") // ErrNonSeekable is returned if a ReadObjectAt method is called without a // seekable scanner ErrNonSeekable = NewError("non-seekable scanner") // ErrRollback error making Rollback over a transaction after an error ErrRollback = NewError("rollback error, during set error") // ErrAlreadyDecoded is returned if NewDecoder is called for a second time ErrAlreadyDecoded = NewError("packfile was already decoded") )
var ( ErrInvalidDelta = errors.New("invalid delta") ErrDeltaCmd = errors.New("wrong delta command") )
var ( // ErrEmptyPackfile is returned by ReadHeader when no data is found in the packfile ErrEmptyPackfile = NewError("empty packfile") // ErrBadSignature is returned by ReadHeader when the signature in the packfile is incorrect. ErrBadSignature = NewError("malformed pack file signature") // ErrUnsupportedVersion is returned by ReadHeader when the packfile version is // different than VersionSupported. ErrUnsupportedVersion = NewError("unsupported packfile version") // ErrSeekNotSupported returned if seek is not support ErrSeekNotSupported = NewError("not seek support") )
var T = []uint32{}/* 256 elements not displayed */
Functions ¶
func ApplyDelta ¶
func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) error
ApplyDelta writes to target the result of applying the modification deltas in delta to base.
func DiffDelta ¶
DiffDelta returns the delta that transforms src into tgt.
func GetDelta ¶
func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, error)
GetDelta returns an EncodedObject of type OFSDeltaObject. Base and Target object, will be loaded into memory to be able to create the delta object. To generate target again, you will need the obtained object and "base" one. Error will be returned if base or target object cannot be read.
func PatchDelta ¶
PatchDelta returns the result of applying the modification deltas in delta to src. An error will be returned if delta is corrupted (ErrDeltaLen) or an action command is not copy from source or copy from delta (ErrDeltaCmd).
Types ¶
type Decoder ¶
type Decoder struct {
// contains filtered or unexported fields
}
Decoder reads and decodes packfiles from an input Scanner, if an ObjectStorer was provided the decoded objects are store there. If not the decode object is destroyed. The Offsets and CRCs are calculated whether an ObjectStorer was provided or not.
func NewDecoder ¶
func NewDecoder(s *Scanner, o storer.EncodedObjectStorer) (*Decoder, error)
NewDecoder returns a new Decoder that decodes a Packfile using the given Scanner and stores the objects in the provided EncodedObjectStorer. ObjectStorer can be nil, in this If the passed EncodedObjectStorer is nil, objects are not stored, but offsets on the Packfile and CRCs are calculated.
If EncodedObjectStorer is nil and the Scanner is not Seekable, ErrNonSeekable is returned.
If the ObjectStorer implements storer.Transactioner, a transaction is created during the Decode execution. If anything fails, Rollback is called
func NewDecoderForType ¶
func NewDecoderForType(s *Scanner, o storer.EncodedObjectStorer, t plumbing.ObjectType, cacheObject cache.Object) (*Decoder, error)
NewDecoderForType returns a new Decoder but in this case for a specific object type. When an object is read using this Decoder instance and it is not of the same type of the specified one, nil will be returned. This is intended to avoid the content deserialization of all the objects.
cacheObject is a cache.Object implementation that is used to speed up the process. If cache is not needed you can pass nil. To create an LRU cache object with the default size you can use the helper cache.ObjectLRUDefault().
func NewDecoderWithCache ¶
func NewDecoderWithCache(s *Scanner, o storer.EncodedObjectStorer, cacheObject cache.Object) (*Decoder, error)
NewDecoderWithCache is a version of NewDecoder where cache can be specified.
func (*Decoder) Close ¶
Close closes the Scanner. usually this mean that the whole reader is read and discarded
func (*Decoder) Decode ¶
Decode reads a packfile and stores it in the value pointed to by s. The offsets and the CRCs are calculated by this method
func (*Decoder) DecodeObject ¶
func (d *Decoder) DecodeObject() (plumbing.EncodedObject, error)
DecodeObject reads the next object from the scanner and returns it. This method can be used in replacement of the Decode method, to work in a interactive way. If you created a new decoder instance using NewDecoderForType constructor, if the object decoded is not equals to the specified one, nil will be returned
func (*Decoder) DecodeObjectAt ¶
func (d *Decoder) DecodeObjectAt(offset int64) (plumbing.EncodedObject, error)
DecodeObjectAt reads an object at the given location. Every EncodedObject returned is added into a internal index. This is intended to be able to regenerate objects from deltas (offset deltas or reference deltas) without an package index (.idx file). If Decode wasn't called previously objects offset should provided using the SetOffsets method. It decodes the object regardless of the Decoder type.
func (*Decoder) Index ¶
Index returns the index for the packfile. If index was set with SetIndex, Index will return it. Otherwise, it will return an index that is built while decoding. If neither SetIndex was called with a full index or Decode called for the whole packfile, then the returned index will be incomplete.
type Encoder ¶
type Encoder struct {
// contains filtered or unexported fields
}
Encoder gets the data from the storage and write it into the writer in PACK format
func NewEncoder ¶
NewEncoder creates a new packfile encoder using a specific Writer and EncodedObjectStorer. By default deltas used to generate the packfile will be OFSDeltaObject. To use Reference deltas, set useRefDeltas to true.
func (*Encoder) Encode ¶
Encode creates a packfile containing all the objects referenced in hashes and writes it to the writer in the Encoder. `packWindow` specifies the size of the sliding window used to compare objects for delta compression; 0 turns off delta compression entirely.
type Error ¶
type Error struct {
// contains filtered or unexported fields
}
Error specifies errors returned during packfile parsing.
func (*Error) AddDetails ¶
AddDetails adds details to an error, with additional text.
type Index ¶
type Index struct {
// contains filtered or unexported fields
}
Index is an in-memory representation of a packfile index. This uses idxfile.Idxfile under the hood to obtain indexes from .idx files or to store them.
func NewIndex ¶
NewIndex creates a new empty index with the given size. Size is a hint and can be 0. It is recommended to set it to the number of objects to be indexed if it is known beforehand (e.g. reading from a packfile).
func NewIndexFromIdxFile ¶
NewIndexFromIdxFile creates a new Index from an idxfile.IdxFile.
func (*Index) Add ¶
Add adds a new Entry with the given values to the index.
func (*Index) LookupHash ¶
LookupHash looks an entry up by its hash. An idxfile.Entry is returned and a bool, which is true if it was found or false if it wasn't.
func (*Index) LookupOffset ¶
LookupHash looks an entry up by its offset in the packfile. An idxfile.Entry is returned and a bool, which is true if it was found or false if it wasn't.
type ObjectHeader ¶
type ObjectHeader struct { Type plumbing.ObjectType Offset int64 Length int64 Reference plumbing.Hash OffsetReference int64 }
ObjectHeader contains the information related to the object, this information is collected from the previous bytes to the content of the object.
type ObjectToPack ¶
type ObjectToPack struct { // The main object to pack, it could be any object, including deltas Object plumbing.EncodedObject // Base is the object that a delta is based on (it could be also another delta). // If the main object is not a delta, Base will be null Base *ObjectToPack // Original is the object that we can generate applying the delta to // Base, or the same object as Object in the case of a non-delta // object. Original plumbing.EncodedObject // Depth is the amount of deltas needed to resolve to obtain Original // (delta based on delta based on ...) Depth int // offset in pack when object has been already written, or 0 if it // has not been written yet Offset int64 // contains filtered or unexported fields }
ObjectToPack is a representation of an object that is going to be into a pack file.
func (*ObjectToPack) BackToOriginal ¶
func (o *ObjectToPack) BackToOriginal()
BackToOriginal converts that ObjectToPack to a non-deltified object if it was one
func (*ObjectToPack) CleanOriginal ¶
func (o *ObjectToPack) CleanOriginal()
CleanOriginal sets Original to nil
func (*ObjectToPack) Hash ¶
func (o *ObjectToPack) Hash() plumbing.Hash
func (*ObjectToPack) IsDelta ¶
func (o *ObjectToPack) IsDelta() bool
func (*ObjectToPack) IsWritten ¶
func (o *ObjectToPack) IsWritten() bool
IsWritten returns if that ObjectToPack was already written into the packfile or not
func (*ObjectToPack) MarkWantWrite ¶
func (o *ObjectToPack) MarkWantWrite()
MarkWantWrite marks this ObjectToPack as WantWrite to avoid delta chain loops
func (*ObjectToPack) SaveOriginalMetadata ¶
func (o *ObjectToPack) SaveOriginalMetadata()
SaveOriginalMetadata saves size, type and hash of Original object
func (*ObjectToPack) SetDelta ¶
func (o *ObjectToPack) SetDelta(base *ObjectToPack, delta plumbing.EncodedObject)
func (*ObjectToPack) SetOriginal ¶
func (o *ObjectToPack) SetOriginal(obj plumbing.EncodedObject)
SetOriginal sets both Original and saves size, type and hash. If object is nil Original is set but previous resolved values are kept
func (*ObjectToPack) Size ¶
func (o *ObjectToPack) Size() int64
func (*ObjectToPack) Type ¶
func (o *ObjectToPack) Type() plumbing.ObjectType
func (*ObjectToPack) WantWrite ¶
func (o *ObjectToPack) WantWrite() bool
WantWrite checks if this ObjectToPack was marked as WantWrite before
type Scanner ¶
type Scanner struct { // lsSeekable says if this scanner can do Seek or not, to have a Scanner // seekable a r implementing io.Seeker is required IsSeekable bool // contains filtered or unexported fields }
func NewScanner ¶
NewScanner returns a new Scanner based on a reader, if the given reader implements io.ReadSeeker the Scanner will be also Seekable
func (*Scanner) Checksum ¶
Checksum returns the checksum of the packfile
func (*Scanner) Flush ¶
Flush finishes writing the buffer to crc hasher in case we are using a teeReader. Otherwise it is a no-op.
func (*Scanner) Header ¶
Header reads the whole packfile header (signature, version and object count). It returns the version and the object count and performs checks on the validity of the signature and the version fields.
func (*Scanner) NextObject ¶
NextObject writes the content of the next object into the reader, returns the number of bytes written, the CRC32 of the content and an error, if any
func (*Scanner) NextObjectHeader ¶
func (s *Scanner) NextObjectHeader() (*ObjectHeader, error)
NextObjectHeader returns the ObjectHeader for the next object in the reader