func()

in backend/plugins/gitextractor/parser/repo_libgit2.go [249:343]


func (r *Libgit2RepoCollector) CollectCommits(subtaskCtx plugin.SubTaskContext) error {
	taskOpts := subtaskCtx.GetData().(*GitExtractorTaskData).Options
	opts, err := getDiffOpts()
	if err != nil {
		return err
	}
	db := subtaskCtx.GetDal()
	components := make([]code.Component, 0)
	err = db.All(&components, dal.From(components), dal.Where("repo_id= ?", r.id))
	if err != nil {
		return err
	}
	componentMap := make(map[string]*regexp.Regexp)
	for _, component := range components {
		componentMap[component.Name] = regexp.MustCompile(component.PathRegex)
	}
	odb, err := errors.Convert01(r.repo.Odb())
	if err != nil {
		return err
	}
	return errors.Convert(odb.ForEach(func(id *git.Oid) error {
		select {
		case <-subtaskCtx.GetContext().Done():
			return subtaskCtx.GetContext().Err()
		default:
		}
		commit, err1 := r.repo.LookupCommit(id)
		if err1 != nil && err1.Error() != TypeNotMatchError {
			return errors.Convert(err1)
		}
		if commit == nil {
			return nil
		}
		var parent *git.Commit
		if commit.ParentCount() > 0 {
			parent = commit.Parent(0)
			// Skip calculating commit statistics when there are parent commits, but the first one cannot be fetched from the ODB.
			// This usually happens during a shallow clone for incremental collection. Otherwise, we might end up overwriting
			// the correct addition/deletion data in the database with an absurdly large addition number.
			if parent == nil {
				r.logger.Info("skip commit %s because it has no parent commit", commit.Id().String())
				return nil
			}
		}
		commitSha := commit.Id().String()
		r.logger.Debug("process commit: %s", commitSha)
		c := &code.Commit{
			Sha:     commitSha,
			Message: commit.Message(),
		}
		author := commit.Author()
		if author != nil {
			c.AuthorName = author.Name
			c.AuthorEmail = author.Email
			c.AuthorId = author.Email
			c.AuthoredDate = author.When
		}
		committer := commit.Committer()
		if committer != nil {
			c.CommitterName = committer.Name
			c.CommitterEmail = committer.Email
			c.CommitterId = committer.Email
			c.CommittedDate = committer.When
		}
		err = r.storeParentCommits(commitSha, commit)
		if err != nil {
			return err
		}

		if !*taskOpts.SkipCommitStat {
			var stats *git.DiffStats
			if stats, err = r.getDiffComparedToParent(taskOpts, c.Sha, commit, parent, opts, componentMap); err != nil {
				return err
			}
			r.logger.Debug("state: %#+v\n", stats.Deletions())
			c.Additions += stats.Insertions()
			c.Deletions += stats.Deletions()
		}

		err = r.store.Commits(c)
		if err != nil {
			return err
		}
		repoCommit := &code.RepoCommit{
			RepoId:    r.id,
			CommitSha: c.Sha,
		}
		err = r.store.RepoCommits(repoCommit)
		if err != nil {
			return err
		}
		subtaskCtx.IncProgress(1)
		return nil
	}))
}