func (d *Decoder) Decode() (checksum plumbing.Hash, err error) {
	defer func() { d.isDecoded = true }()
	if d.isDecoded {
		return plumbing.ZeroHash, ErrAlreadyDecoded
	}
	if err := d.doDecode(); err != nil {
		return plumbing.ZeroHash, err
	}
	return d.s.Checksum()
}
Decode reads a packfile and stores it in the value pointed to by s. The
offsets and the CRCs are calculated by this method
package packfile
import (
	"bytes"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/cache"
	"gopkg.in/src-d/go-git.v4/plumbing/storer"
)
type Format int
const (
	UnknownFormat Format = iota
	OFSDeltaFormat
	REFDeltaFormat
)
var (
	ErrMaxObjectsLimitReached = NewError("max. objects limit reached")
	ErrInvalidObject = NewError("invalid git object")
	ErrPackEntryNotFound = NewError("can't find a pack entry")
	ErrZLib = NewError("zlib reading error")
	ErrCannotRecall = NewError("cannot recall object")
	ErrResolveDeltasNotSupported = NewError("resolve delta is not supported")
	ErrNonSeekable = NewError("non-seekable scanner")
	ErrRollback = NewError("rollback error, during set error")
	ErrAlreadyDecoded = NewError("packfile was already decoded")
)
type Decoder struct {
	DeltaBaseCache cache.Object
	s  *Scanner
	o  storer.EncodedObjectStorer
	tx storer.Transaction
	isDecoded bool
	hasBuiltIndex bool
	idx           *Index
	offsetToType map[int64]plumbing.ObjectType
	decoderType  plumbing.ObjectType
}
func NewDecoder(s *Scanner, o storer.EncodedObjectStorer) (*Decoder, error) {
	return NewDecoderForType(s, o, plumbing.AnyObject)
}
func NewDecoderForType(s *Scanner, o storer.EncodedObjectStorer,
	t plumbing.ObjectType) (*Decoder, error) {
	if t == plumbing.OFSDeltaObject ||
		t == plumbing.REFDeltaObject ||
		t == plumbing.InvalidObject {
		return nil, plumbing.ErrInvalidType
	}
	if !canResolveDeltas(s, o) {
		return nil, ErrResolveDeltasNotSupported
	}
	return &Decoder{
		s: s,
		o: o,
		idx:          NewIndex(0),
		offsetToType: make(map[int64]plumbing.ObjectType),
		decoderType:  t,
	}, nil
}
func canResolveDeltas(s *Scanner, o storer.EncodedObjectStorer) bool {
	return s.IsSeekable || o != nil
}