diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 7ff23af42e..d3731cb928 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -7,6 +7,8 @@ package git import ( "bytes" + "encoding/hex" + "fmt" "io" "strconv" "strings" @@ -209,9 +211,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( }() go func() { 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), - prettyLogFormat, "--", file). + "--skip="+strconv.Itoa(skip), "--", file). Run(&RunOpts{ Dir: repo.Path, Stdout: stdoutWriter, @@ -224,32 +226,30 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) ( } }() - if skip > 0 { - _, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41)) - if err != nil { + commits := []*Commit{} + shaline := [41]byte{} + var sha1 SHA1 + for { + n, err := io.ReadFull(stdoutReader, shaline[:]) + if err != nil || n < 40 { 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 } + 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 diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go index a3a5904925..d423bddbbd 100644 --- a/routers/api/v1/repo/wiki.go +++ b/routers/api/v1/repo/wiki.go @@ -427,9 +427,9 @@ func ListPageRevisions(ctx *context.APIContext) { } // get Commit Count - commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page) + commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page) if err != nil { - ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err) + ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err) return } diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 1af511f50a..4cd5856ea6 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -360,12 +360,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) } // get Commit Count - commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page) + commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page) if err != nil { if wikiRepo != nil { wikiRepo.Close() } - ctx.ServerError("CommitsByFileAndRangeNoFollow", err) + ctx.ServerError("CommitsByFileAndRange", err) return nil, nil } ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)