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 <art27@cantab.net> Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: techknowlogick <techknowlogick@gitea.io>
This commit is contained in:
parent
7ae297800e
commit
58a4407acb
3 changed files with 27 additions and 27 deletions
|
@ -7,6 +7,8 @@ package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -209,9 +211,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
|
||||||
}()
|
}()
|
||||||
go func() {
|
go func() {
|
||||||
stderr := strings.Builder{}
|
stderr := strings.Builder{}
|
||||||
err := NewCommand(repo.Ctx, "log", revision, "--follow",
|
err := NewCommand(repo.Ctx, "rev-list", revision,
|
||||||
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
|
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
|
||||||
prettyLogFormat, "--", file).
|
"--skip="+strconv.Itoa(skip), "--", file).
|
||||||
Run(&RunOpts{
|
Run(&RunOpts{
|
||||||
Dir: repo.Path,
|
Dir: repo.Path,
|
||||||
Stdout: stdoutWriter,
|
Stdout: stdoutWriter,
|
||||||
|
@ -224,32 +226,30 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if skip > 0 {
|
commits := []*Commit{}
|
||||||
_, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41))
|
shaline := [41]byte{}
|
||||||
if err != nil {
|
var sha1 SHA1
|
||||||
|
for {
|
||||||
|
n, err := io.ReadFull(stdoutReader, shaline[:])
|
||||||
|
if err != nil || n < 40 {
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return []*Commit{}, nil
|
err = nil
|
||||||
}
|
}
|
||||||
_ = stdoutReader.CloseWithError(err)
|
return commits, err
|
||||||
|
}
|
||||||
|
n, err = hex.Decode(sha1[:], shaline[0:40])
|
||||||
|
if n != 20 {
|
||||||
|
err = fmt.Errorf("invalid sha %q", string(shaline[:40]))
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
commit, err := repo.getCommit(sha1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
commits = append(commits, commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
stdout, err := io.ReadAll(stdoutReader)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return repo.parsePrettyFormatLogToList(stdout)
|
|
||||||
}
|
|
||||||
|
|
||||||
// CommitsByFileAndRangeNoFollow return the commits according revision file and the page
|
|
||||||
func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) {
|
|
||||||
stdout, _, err := NewCommand(repo.Ctx, "log", revision, "--skip="+strconv.Itoa((page-1)*50),
|
|
||||||
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunStdBytes(&RunOpts{Dir: repo.Path})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return repo.parsePrettyFormatLogToList(stdout)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilesCountBetween return the number of files changed between two commits
|
// FilesCountBetween return the number of files changed between two commits
|
||||||
|
|
|
@ -427,9 +427,9 @@ func ListPageRevisions(ctx *context.APIContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get Commit Count
|
// get Commit Count
|
||||||
commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
|
commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err)
|
ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -360,12 +360,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
||||||
}
|
}
|
||||||
|
|
||||||
// get Commit Count
|
// get Commit Count
|
||||||
commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
|
commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if wikiRepo != nil {
|
if wikiRepo != nil {
|
||||||
wikiRepo.Close()
|
wikiRepo.Close()
|
||||||
}
|
}
|
||||||
ctx.ServerError("CommitsByFileAndRangeNoFollow", err)
|
ctx.ServerError("CommitsByFileAndRange", err)
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)
|
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)
|
||||||
|
|
Reference in a new issue