Filters for GetAllCommits (#24568)

The `GetAllCommits` endpoint can be pretty slow, especially in repos
with a lot of commits. The issue is that it spends a lot of time
calculating information that may not be useful/needed by the user.

The `stat` param was previously added in #21337 to address this, by
allowing the user to disable the calculating stats for each commit. But
this has two issues:
1. The name `stat` is rather misleading, because disabling `stat`
disables the Stat **and** Files. This should be separated out into two
different params, because getting a list of affected files is much less
expensive than calculating the stats
2. There's still other costly information provided that the user may not
need, such as `Verification`

This PR, adds two parameters to the endpoint, `files` and `verification`
to allow the user to explicitly disable this information when listing
commits. The default behavior is true.
This commit is contained in:
Matthew Walowski 2023-05-08 18:06:05 -07:00 committed by GitHub
parent 707c7e60c9
commit 1dd83dbb91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 72 additions and 8 deletions

View file

@ -72,8 +72,14 @@ func ToPayloadCommit(ctx context.Context, repo *repo_model.Repository, c *git.Co
}
}
type ToCommitOptions struct {
Stat bool
Verification bool
Files bool
}
// ToCommit convert a git.Commit to api.Commit
func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User, stat bool) (*api.Commit, error) {
func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User, opts ToCommitOptions) (*api.Commit, error) {
var apiAuthor, apiCommitter *api.User
// Retrieve author and committer information
@ -162,19 +168,24 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
SHA: commit.ID.String(),
Created: commit.Committer.When,
},
Verification: ToVerification(ctx, commit),
},
Author: apiAuthor,
Committer: apiCommitter,
Parents: apiParents,
}
// Retrieve verification for commit
if opts.Verification {
res.RepoCommit.Verification = ToVerification(ctx, commit)
}
// Retrieve files affected by the commit
if stat {
if opts.Files {
fileStatus, err := git.GetCommitFileStatus(gitRepo.Ctx, repo.RepoPath(), commit.ID.String())
if err != nil {
return nil, err
}
affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified))
for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} {
for _, filename := range files {
@ -184,6 +195,11 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
}
}
res.Files = affectedFileList
}
// Get diff stats for commit
if opts.Stat {
diff, err := gitdiff.GetDiff(gitRepo, &gitdiff.DiffOptions{
AfterCommitID: commit.ID.String(),
})
@ -191,7 +207,6 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
return nil, err
}
res.Files = affectedFileList
res.Stats = &api.CommitStats{
Total: diff.TotalAddition + diff.TotalDeletion,
Additions: diff.TotalAddition,