mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	Avoid creating unnecessary temporary cat file sub process (#33942)
Extract from #33934 In the same goroutine, we should reuse the exist cat file sub process which exist in `git.Repository` to avoid creating a unnecessary temporary subprocess. This PR reuse the exist cate file writer and reader in `getCommitFromBatchReader`. It also move `prepareLatestCommitInfo` before creating dataRc which will hold the writer so other git operation will create a temporary cat file subprocess.
This commit is contained in:
		| @@ -81,10 +81,10 @@ func (repo *Repository) getCommit(id ObjectID) (*Commit, error) { | ||||
|  | ||||
| 	_, _ = wr.Write([]byte(id.String() + "\n")) | ||||
|  | ||||
| 	return repo.getCommitFromBatchReader(rd, id) | ||||
| 	return repo.getCommitFromBatchReader(wr, rd, id) | ||||
| } | ||||
|  | ||||
| func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) { | ||||
| func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.Reader, id ObjectID) (*Commit, error) { | ||||
| 	_, typ, size, err := ReadBatchLine(rd) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, io.EOF) || IsErrNotExist(err) { | ||||
| @@ -112,7 +112,11 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		commit, err := tag.Commit(repo) | ||||
| 		if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | ||||
| 		commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|   | ||||
| @@ -41,9 +41,12 @@ func (repo *Repository) GetTagType(id ObjectID) (string, error) { | ||||
| 		return "", err | ||||
| 	} | ||||
| 	_, typ, _, err := ReadBatchLine(rd) | ||||
| 	if err != nil { | ||||
| 		if IsErrNotExist(err) { | ||||
| 			return "", ErrNotExist{ID: id.String()} | ||||
| 		} | ||||
| 		return "", err | ||||
| 	} | ||||
| 	return typ, nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -35,7 +35,11 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) { | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		commit, err := tag.Commit(repo) | ||||
|  | ||||
| 		if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|   | ||||
| @@ -21,11 +21,6 @@ type Tag struct { | ||||
| 	Signature *CommitSignature | ||||
| } | ||||
|  | ||||
| // Commit return the commit of the tag reference | ||||
| func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) { | ||||
| 	return gitRepo.getCommit(tag.Object) | ||||
| } | ||||
|  | ||||
| func parsePayloadSignature(data []byte, messageStart int) (payload, msg, sign string) { | ||||
| 	pos := messageStart | ||||
| 	signStart, signEnd := -1, -1 | ||||
|   | ||||
| @@ -126,7 +126,7 @@ func PushUpdateAddTag(ctx context.Context, repo *repo_model.Repository, gitRepo | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("unable to GetTag: %w", err) | ||||
| 	} | ||||
| 	commit, err := tag.Commit(gitRepo) | ||||
| 	commit, err := gitRepo.GetTagCommit(tag.Name) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("unable to get tag Commit: %w", err) | ||||
| 	} | ||||
|   | ||||
| @@ -110,7 +110,7 @@ func GetAnnotatedTag(ctx *context.APIContext) { | ||||
| 	if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { | ||||
| 		ctx.APIError(http.StatusBadRequest, err) | ||||
| 	} else { | ||||
| 		commit, err := tag.Commit(ctx.Repo.GitRepo) | ||||
| 		commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) | ||||
| 		if err != nil { | ||||
| 			ctx.APIError(http.StatusBadRequest, err) | ||||
| 		} | ||||
|   | ||||
| @@ -30,32 +30,31 @@ import ( | ||||
| 	"github.com/nektos/act/pkg/model" | ||||
| ) | ||||
|  | ||||
| func prepareLatestCommitInfo(ctx *context.Context) bool { | ||||
| 	commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetCommitByPath", err) | ||||
| 		return false | ||||
| 	} | ||||
|  | ||||
| 	return loadLatestCommitData(ctx, commit) | ||||
| } | ||||
|  | ||||
| func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { | ||||
| 	ctx.Data["IsViewFile"] = true | ||||
| 	ctx.Data["HideRepoInfo"] = true | ||||
| 	blob := entry.Blob() | ||||
| 	buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("getFileReader", err) | ||||
|  | ||||
| 	if !prepareLatestCommitInfo(ctx) { | ||||
| 		return | ||||
| 	} | ||||
| 	defer dataRc.Close() | ||||
|  | ||||
| 	blob := entry.Blob() | ||||
|  | ||||
| 	ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName()) | ||||
| 	ctx.Data["FileIsSymlink"] = entry.IsLink() | ||||
| 	ctx.Data["FileName"] = blob.Name() | ||||
| 	ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) | ||||
|  | ||||
| 	commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("GetCommitByPath", err) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if !loadLatestCommitData(ctx, commit) { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	if ctx.Repo.TreePath == ".editorconfig" { | ||||
| 		_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) | ||||
| 		if editorconfigWarning != nil { | ||||
| @@ -90,6 +89,15 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { | ||||
| 	isDisplayingSource := ctx.FormString("display") == "source" | ||||
| 	isDisplayingRendered := !isDisplayingSource | ||||
|  | ||||
| 	// Don't call any other repository functions depends on git.Repository until the dataRc closed to | ||||
| 	// avoid create unnecessary temporary cat file. | ||||
| 	buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob) | ||||
| 	if err != nil { | ||||
| 		ctx.ServerError("getFileReader", err) | ||||
| 		return | ||||
| 	} | ||||
| 	defer dataRc.Close() | ||||
|  | ||||
| 	if fInfo.isLFSFile { | ||||
| 		ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) | ||||
| 	} | ||||
|   | ||||
| @@ -385,7 +385,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("GetTag: %w", err) | ||||
| 		} | ||||
| 		commit, err := tag.Commit(gitRepo) | ||||
| 		commit, err := gitRepo.GetTagCommit(tag.Name) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("Commit: %w", err) | ||||
| 		} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user