func NewObjectIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *ObjectIter {
	return &ObjectIter{iter, s}
}
NewObjectIter takes a storer.EncodedObjectStorer and a
storer.EncodedObjectIter and returns an *ObjectIter that iterates over all
objects contained in the storer.EncodedObjectIter.
package object
import (
	"bytes"
	"errors"
	"fmt"
	"io"
	"strconv"
	"time"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/storer"
)
var ErrUnsupportedObject = errors.New("unsupported object type")
type Object interface {
	ID() plumbing.Hash
	Type() plumbing.ObjectType
	Decode(plumbing.EncodedObject) error
	Encode(plumbing.EncodedObject) error
}
func GetObject(s storer.EncodedObjectStorer, h plumbing.Hash) (Object, error) {
	o, err := s.EncodedObject(plumbing.AnyObject, h)
	if err != nil {
		return nil, err
	}
	return DecodeObject(s, o)
}
func DecodeObject(s storer.EncodedObjectStorer, o plumbing.EncodedObject) (Object, error) {
	switch o.Type() {
	case plumbing.CommitObject:
		return DecodeCommit(s, o)
	case plumbing.TreeObject:
		return DecodeTree(s, o)
	case plumbing.BlobObject:
		return DecodeBlob(o)
	case plumbing.TagObject:
		return DecodeTag(s, o)
	default:
		return nil, plumbing.ErrInvalidType
	}
}
const DateFormat = "Mon Jan 02 15:04:05 2006 -0700"
type Signature struct {
	Name string
	Email string
	When time.Time
}
func (s *Signature) Decode(b []byte) {
	open := bytes.LastIndexByte(b, '<')
	close := bytes.LastIndexByte(b, '>')
	if open == -1 || close == -1 {
		return
	}
	if close < open {
		return
	}
	s.Name = string(bytes.Trim(b[:open], " "))
	s.Email = string(b[open+1 : close])
	hasTime := close+2 < len(b)
	if hasTime {
		s.decodeTimeAndTimeZone(b[close+2:])
	}
}
func (s *Signature) Encode(w io.Writer) error {
	if _, err := fmt.Fprintf(w, "%s <%s> ", s.Name, s.Email); err != nil {
		return err
	}
	if err := s.encodeTimeAndTimeZone(w); err != nil {
		return err
	}
	return nil
}
var timeZoneLength = 5
func (s *Signature) decodeTimeAndTimeZone(b []byte) {
	space := bytes.IndexByte(b, ' ')
	if space == -1 {
		space = len(b)
	}
	ts, err := strconv.ParseInt(string(b[:space]), 10, 64)
	if err != nil {
		return
	}
	s.When = time.Unix(ts, 0).In(time.UTC)
	var tzStart = space + 1
	if tzStart >= len(b) || tzStart+timeZoneLength > len(b) {
		return
	}
	tl, err := time.Parse("2006 -0700", "1970 "+string(b[tzStart:tzStart+timeZoneLength]))
	if err != nil {
		return
	}
	s.When = s.When.In(tl.Location())
}
func (s *Signature) encodeTimeAndTimeZone(w io.Writer) error {
	_, err := fmt.Fprintf(w, "%d %s", s.When.Unix(), s.When.Format("-0700"))
	return err
}
func (s *Signature) String() string {
	return fmt.Sprintf("%s <%s>", s.Name, s.Email)
}
type ObjectIter struct {
	storer.EncodedObjectIter
	s storer.EncodedObjectStorer
}