func (s *Ripsrc) CodeByCommit(ctx context.Context, res chan CommitCode) error {
	defer close(res)
	err := s.prepareGitExec(ctx)
	if err != nil {
		return err
	}
	err = s.buildCommitGraph(ctx)
	if err != nil {
		return err
	}
	var wantedBranchRefs []string
	var wantedBranchNames []string
	if s.opts.CommitFromIncl != "" && s.opts.AllBranches {
	}
	if len(wantedBranchRefs) != 0 {
		s.opts.Logger.Debug("processing additional branches", "branches", wantedBranchNames)
	}
	err = s.getCommitInfo(ctx, wantedBranchRefs)
	if err != nil {
		return err
	}
	gitRes := make(chan process.Result)
	done := make(chan bool)
	go func() {
		for r1 := range gitRes {
			sha := r1.Commit
			rc := CommitCode{}
			rc.Blames = make(chan BlameResult)
			commit, ok := s.commitMeta[sha]
			if !ok {
				panic(fmt.Errorf("commit not found in commit meta: %v", r1.Commit))
			}
			rc.Commit = commit
			rs, err := s.codeInfoFiles(r1)
			if err != nil {
				panic(err)
			}
			res <- rc
			for _, r := range rs {
				rc.Blames <- r
			}
			close(rc.Blames)
		}
		done <- true
	}()
	processOpts := process.Opts{
		Logger:                s.opts.Logger,
		RepoDir:               s.opts.RepoDir,
		CheckpointsDir:        s.opts.CheckpointsDir,
		NoStrictResume:        s.opts.NoStrictResume,
		CommitFromIncl:        s.opts.CommitFromIncl,
		CommitFromMakeNonIncl: s.opts.CommitFromMakeNonIncl,
		AllBranches:           s.opts.AllBranches,
		ParentsGraph:          s.commitGraph,
		WantedBranchRefs:      wantedBranchRefs,
	}
	gitProcessor := process.New(processOpts)
	err = gitProcessor.Run(gitRes)
	<-done
	if err != nil {
		return err
	}
	s.GitProcessTimings = gitProcessor.Timing()
	return nil
}
CodeByCommit returns code information using one record per commit that includes records by file
package ripsrc
import (
	"context"
	"fmt"
	"time"
	"github.com/pinpt/ripsrc/ripsrc/commitmeta"
	"github.com/pinpt/ripsrc/ripsrc/fileinfo"
	"github.com/pinpt/ripsrc/ripsrc/history3/process"
)
type Commit = commitmeta.Commit
type CommitFile = commitmeta.CommitFile
type BlameResult struct {
	Commit             Commit
	Language           string
	Filename           string
	Lines              []*BlameLine
	Size               int64
	Loc                int64
	Sloc               int64
	Comments           int64
	Blanks             int64
	Complexity         int64
	WeightedComplexity float64
	Skipped            string
	License            *License
	Status             CommitStatus
}
type BlameLine struct {
	Name    string
	Email   string
	Date    time.Time
	Comment bool
	Code    bool
	Blank   bool
	SHA     string
}
type License = fileinfo.License
type CommitStatus = commitmeta.CommitStatus
const (
	GitFileCommitStatusAdded = commitmeta.GitFileCommitStatusAdded
	GitFileCommitStatusModified = commitmeta.GitFileCommitStatusModified
	GitFileCommitStatusRemoved = commitmeta.GitFileCommitStatusRemoved
)
func (s *Ripsrc) Code(ctx context.Context, res chan BlameResult) error {
	defer close(res)
	res2 := make(chan CommitCode)
	done := make(chan bool)
	go func() {
		for r := range res2 {
			for f := range r.Blames {
				res <- f
			}
		}
		done <- true
	}()
	err := s.CodeByCommit(ctx, res2)
	<-done
	if err != nil {
		return err
	}
	return nil
}
type CommitCode struct {
	Commit
	Blames chan BlameResult
}