Skip to content

Commit fd2d5f0

Browse files
authored
Add stat to ToCommit function for speed (#21337)
Calls to ToCommit are very slow due to fetching diffs, analyzing files. This patch lets us supply `stat` as false to speed fetching a commit when we don't need the diff. /v1/repo/commits has a default `stat` set as true now. Set to false to experience fetching thousands of commits per second instead of 2-5 per second.
1 parent 8765f13 commit fd2d5f0

File tree

5 files changed

+49
-31
lines changed

5 files changed

+49
-31
lines changed

modules/convert/git_commit.go

+32-27
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func ToPayloadCommit(repo *repo_model.Repository, c *git.Commit) *api.PayloadCom
7373
}
7474

7575
// ToCommit convert a git.Commit to api.Commit
76-
func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User) (*api.Commit, error) {
76+
func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, userCache map[string]*user_model.User, stat bool) (*api.Commit, error) {
7777
var apiAuthor, apiCommitter *api.User
7878

7979
// Retrieve author and committer information
@@ -133,28 +133,7 @@ func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.
133133
}
134134
}
135135

136-
// Retrieve files affected by the commit
137-
fileStatus, err := git.GetCommitFileStatus(gitRepo.Ctx, repo.RepoPath(), commit.ID.String())
138-
if err != nil {
139-
return nil, err
140-
}
141-
affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified))
142-
for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} {
143-
for _, filename := range files {
144-
affectedFileList = append(affectedFileList, &api.CommitAffectedFiles{
145-
Filename: filename,
146-
})
147-
}
148-
}
149-
150-
diff, err := gitdiff.GetDiff(gitRepo, &gitdiff.DiffOptions{
151-
AfterCommitID: commit.ID.String(),
152-
})
153-
if err != nil {
154-
return nil, err
155-
}
156-
157-
return &api.Commit{
136+
res := &api.Commit{
158137
CommitMeta: &api.CommitMeta{
159138
URL: repo.APIURL() + "/git/commits/" + url.PathEscape(commit.ID.String()),
160139
SHA: commit.ID.String(),
@@ -188,11 +167,37 @@ func ToCommit(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.
188167
Author: apiAuthor,
189168
Committer: apiCommitter,
190169
Parents: apiParents,
191-
Files: affectedFileList,
192-
Stats: &api.CommitStats{
170+
}
171+
172+
// Retrieve files affected by the commit
173+
if stat {
174+
fileStatus, err := git.GetCommitFileStatus(gitRepo.Ctx, repo.RepoPath(), commit.ID.String())
175+
if err != nil {
176+
return nil, err
177+
}
178+
affectedFileList := make([]*api.CommitAffectedFiles, 0, len(fileStatus.Added)+len(fileStatus.Removed)+len(fileStatus.Modified))
179+
for _, files := range [][]string{fileStatus.Added, fileStatus.Removed, fileStatus.Modified} {
180+
for _, filename := range files {
181+
affectedFileList = append(affectedFileList, &api.CommitAffectedFiles{
182+
Filename: filename,
183+
})
184+
}
185+
}
186+
187+
diff, err := gitdiff.GetDiff(gitRepo, &gitdiff.DiffOptions{
188+
AfterCommitID: commit.ID.String(),
189+
})
190+
if err != nil {
191+
return nil, err
192+
}
193+
194+
res.Files = affectedFileList
195+
res.Stats = &api.CommitStats{
193196
Total: diff.TotalAddition + diff.TotalDeletion,
194197
Additions: diff.TotalAddition,
195198
Deletions: diff.TotalDeletion,
196-
},
197-
}, nil
199+
}
200+
}
201+
202+
return res, nil
198203
}

routers/api/v1/repo/commits.go

+9-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func getCommit(ctx *context.APIContext, identifier string) {
7070
return
7171
}
7272

73-
json, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil)
73+
json, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, nil, true)
7474
if err != nil {
7575
ctx.Error(http.StatusInternalServerError, "toCommit", err)
7676
return
@@ -104,6 +104,10 @@ func GetAllCommits(ctx *context.APIContext) {
104104
// in: query
105105
// description: filepath of a file/dir
106106
// type: string
107+
// - name: stat
108+
// in: query
109+
// description: include diff stats for every commit (disable for speedup, default 'true')
110+
// type: boolean
107111
// - name: page
108112
// in: query
109113
// description: page number of results to return (1-based)
@@ -209,9 +213,12 @@ func GetAllCommits(ctx *context.APIContext) {
209213
userCache := make(map[string]*user_model.User)
210214

211215
apiCommits := make([]*api.Commit, len(commits))
216+
217+
stat := ctx.FormString("stat") == "" || ctx.FormBool("stat")
218+
212219
for i, commit := range commits {
213220
// Create json struct
214-
apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache)
221+
apiCommits[i], err = convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, stat)
215222
if err != nil {
216223
ctx.Error(http.StatusInternalServerError, "toCommit", err)
217224
return

routers/api/v1/repo/notes.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func getNote(ctx *context.APIContext, identifier string) {
6969
return
7070
}
7171

72-
cmt, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil)
72+
cmt, err := convert.ToCommit(ctx.Repo.Repository, ctx.Repo.GitRepo, note.Commit, nil, true)
7373
if err != nil {
7474
ctx.Error(http.StatusInternalServerError, "ToCommit", err)
7575
return

routers/api/v1/repo/pull.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1306,7 +1306,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
13061306

13071307
apiCommits := make([]*api.Commit, 0, end-start)
13081308
for i := start; i < end; i++ {
1309-
apiCommit, err := convert.ToCommit(ctx.Repo.Repository, baseGitRepo, commits[i], userCache)
1309+
apiCommit, err := convert.ToCommit(ctx.Repo.Repository, baseGitRepo, commits[i], userCache, true)
13101310
if err != nil {
13111311
ctx.ServerError("toCommit", err)
13121312
return

templates/swagger/v1_json.tmpl

+6
Original file line numberDiff line numberDiff line change
@@ -3264,6 +3264,12 @@
32643264
"name": "path",
32653265
"in": "query"
32663266
},
3267+
{
3268+
"type": "boolean",
3269+
"description": "include diff stats for every commit (disable for speedup, default 'true')",
3270+
"name": "stat",
3271+
"in": "query"
3272+
},
32673273
{
32683274
"type": "integer",
32693275
"description": "page number of results to return (1-based)",

0 commit comments

Comments
 (0)