package vcs import ( "net/url" "time" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing/object" "gitlab.com/tozd/go/errors" ) type Author struct { Name string Email string } type Commit struct { Hash string Message string Author Author Date time.Time Link *url.URL } func (r *Repository) makeCommitURL(hash string) *url.URL { u := r.remoteURL.JoinPath("commit") q := u.Query() q.Add("id", hash) u.RawQuery = q.Encode() return u } func (r *Repository) GetFileLog(filename string) (cs []*Commit, err error) { fl, err := r.repo.Log(&git.LogOptions{ Order: git.LogOrderCommitterTime, FileName: &filename, }) if err != nil { return nil, errors.WithMessagef(err, "could not get git log for file %s", filename) } defer fl.Close() err = fl.ForEach(func(c *object.Commit) error { cs = append(cs, &Commit{ Hash: c.Hash.String(), Message: c.Message, Author: Author{ Name: c.Author.Name, Email: c.Author.Email, }, Date: c.Author.When, Link: r.makeCommitURL(c.Hash.String()), }) return nil }) if err != nil { return nil, errors.WithMessagef(err, "could not iterate over commits for file %s", filename) } return cs, nil }