mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	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:
		| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user