func blobHash(path string, commit *object.Commit) (hash plumbing.Hash, found bool) {
	file, err := commit.File(path)
	if err != nil {
		var empty plumbing.Hash
		return empty, found
	}
	return file.Hash, true
}
blobHash returns the hash of a path in a commit
package git
import (
	"io"
	"sort"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/object"
	"gopkg.in/src-d/go-git.v4/utils/diff"
	"github.com/sergi/go-diff/diffmatchpatch"
)
func references(c *object.Commit, path string) ([]*object.Commit, error) {
	var result []*object.Commit
	seen := make(map[plumbing.Hash]struct{})
	if err := walkGraph(&result, &seen, c, path); err != nil {
		return nil, err
	}
	sortCommits(result)
	return removeComp(path, result, equivalent)
}
type commitSorterer struct {
	l []*object.Commit
}
func (s commitSorterer) Len() int {
	return len(s.l)
}
func (s commitSorterer) Less(i, j int) bool {
	return s.l[i].Committer.When.Before(s.l[j].Committer.When)
}
func (s commitSorterer) Swap(i, j int) {
	s.l[i], s.l[j] = s.l[j], s.l[i]
}
func sortCommits(l []*object.Commit) {
	s := &commitSorterer{l}
	sort.Sort(s)
}
func walkGraph(result *[]*object.Commit, seen *map[plumbing.Hash]struct{}, current *object.Commit, path string) error {
	if _, ok := (*seen)[current.Hash]; ok {
		return nil
	}
	(*seen)[current.Hash] = struct{}{}
	if _, err := current.File(path); err != nil {
		return nil
	}
	parents, err := parentsContainingPath(path, current)
	if err != nil {
		return err
	}
	switch len(parents) {
	case 0:
		*result = append(*result, current)
		return nil
	case 1:  
		different, err := differentContents(path, current, parents)
		if err != nil {
			return err
		}
		if len(different) == 1 {
			*result = append(*result, current)
		}
		return walkGraph(result, seen, parents[0], path)
	default:  
		for _, p := range parents {
			err := walkGraph(result, seen, p, path)
			if err != nil {
				return err
			}
		}
	}
	return nil
}
func parentsContainingPath(path string, c *object.Commit) ([]*object.Commit, error) {
	var result []*object.Commit
	iter := c.Parents()
	for {
		parent, err := iter.Next()
		if err == io.EOF {
			return result, nil
		}
		if err != nil {
			return nil, err
		}
		if _, err := parent.File(path); err == nil {
			result = append(result, parent)
		}
	}
}
func differentContents(path string, c *object.Commit, cs []*object.Commit) ([]*object.Commit, error) {
	result := make([]*object.Commit, 0, len(cs))
	h, found := blobHash(path, c)
	if !found {
		return nil, object.ErrFileNotFound
	}
	for _, cx := range cs {
		if hx, found := blobHash(path, cx); found && h != hx {
			result = append(result, cx)
		}
	}
	return result, nil
}