func (iter *ObjectIter) ForEach(cb func(Object) error) error {
	return iter.EncodedObjectIter.ForEach(func(obj plumbing.EncodedObject) error {
		o, err := iter.toObject(obj)
		if err == plumbing.ErrInvalidType {
			return nil
		}
		if err != nil {
			return err
		}
		return cb(o)
	})
}
ForEach call the cb function for each object contained on this iter until
an error happens or the end of the iter is reached. If ErrStop is sent
the iteration is stop but no error is returned. The iterator is closed.
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
}
func NewObjectIter(s storer.EncodedObjectStorer, iter storer.EncodedObjectIter) *ObjectIter {
	return &ObjectIter{iter, s}
}
func (iter *ObjectIter) Next() (Object, error) {
	for {
		obj, err := iter.EncodedObjectIter.Next()
		if err != nil {
			return nil, err
		}
		o, err := iter.toObject(obj)
		if err == plumbing.ErrInvalidType {
			continue
		}
		if err != nil {
			return nil, err
		}
		return o, nil
	}
}