Skip to content

Commit 58a4407

Browse files
Remove follow from commits by file (#20765)
The use of `--follow` makes getting these commits very slow on large repositories as it results in searching the whole commit tree for a blob. Now as nice as the results of `--follow` are, I am uncertain whether it is really of sufficient importance to keep around. Fix #20764 Signed-off-by: Andrew Thornton <[email protected]> Signed-off-by: Andrew Thornton <[email protected]> Co-authored-by: techknowlogick <[email protected]>
1 parent 7ae2978 commit 58a4407

File tree

3 files changed

+27
-27
lines changed

3 files changed

+27
-27
lines changed

modules/git/repo_commit.go

+23-23
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ package git
77

88
import (
99
"bytes"
10+
"encoding/hex"
11+
"fmt"
1012
"io"
1113
"strconv"
1214
"strings"
@@ -209,9 +211,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
209211
}()
210212
go func() {
211213
stderr := strings.Builder{}
212-
err := NewCommand(repo.Ctx, "log", revision, "--follow",
214+
err := NewCommand(repo.Ctx, "rev-list", revision,
213215
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
214-
prettyLogFormat, "--", file).
216+
"--skip="+strconv.Itoa(skip), "--", file).
215217
Run(&RunOpts{
216218
Dir: repo.Path,
217219
Stdout: stdoutWriter,
@@ -224,32 +226,30 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
224226
}
225227
}()
226228

227-
if skip > 0 {
228-
_, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41))
229-
if err != nil {
229+
commits := []*Commit{}
230+
shaline := [41]byte{}
231+
var sha1 SHA1
232+
for {
233+
n, err := io.ReadFull(stdoutReader, shaline[:])
234+
if err != nil || n < 40 {
230235
if err == io.EOF {
231-
return []*Commit{}, nil
236+
err = nil
232237
}
233-
_ = stdoutReader.CloseWithError(err)
238+
return commits, err
239+
}
240+
n, err = hex.Decode(sha1[:], shaline[0:40])
241+
if n != 20 {
242+
err = fmt.Errorf("invalid sha %q", string(shaline[:40]))
243+
}
244+
if err != nil {
234245
return nil, err
235246
}
247+
commit, err := repo.getCommit(sha1)
248+
if err != nil {
249+
return nil, err
250+
}
251+
commits = append(commits, commit)
236252
}
237-
238-
stdout, err := io.ReadAll(stdoutReader)
239-
if err != nil {
240-
return nil, err
241-
}
242-
return repo.parsePrettyFormatLogToList(stdout)
243-
}
244-
245-
// CommitsByFileAndRangeNoFollow return the commits according revision file and the page
246-
func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) {
247-
stdout, _, err := NewCommand(repo.Ctx, "log", revision, "--skip="+strconv.Itoa((page-1)*50),
248-
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunStdBytes(&RunOpts{Dir: repo.Path})
249-
if err != nil {
250-
return nil, err
251-
}
252-
return repo.parsePrettyFormatLogToList(stdout)
253253
}
254254

255255
// FilesCountBetween return the number of files changed between two commits

routers/api/v1/repo/wiki.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -427,9 +427,9 @@ func ListPageRevisions(ctx *context.APIContext) {
427427
}
428428

429429
// get Commit Count
430-
commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
430+
commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
431431
if err != nil {
432-
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err)
432+
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err)
433433
return
434434
}
435435

routers/web/repo/wiki.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,12 +360,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
360360
}
361361

362362
// get Commit Count
363-
commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
363+
commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
364364
if err != nil {
365365
if wikiRepo != nil {
366366
wikiRepo.Close()
367367
}
368-
ctx.ServerError("CommitsByFileAndRangeNoFollow", err)
368+
ctx.ServerError("CommitsByFileAndRange", err)
369369
return nil, nil
370370
}
371371
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)

0 commit comments

Comments
 (0)