mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	Use gitrepo.GetTreePathLatestCommit to get file lastest commit instead from latest commit cache (#32987)
The latest commit cache is currently used only for listing tree files. However, a cold start may take longer than directly invoking the Git command. This PR addresses the issue of slow response times when accessing raw files, improving performance in such scenarios. ```log gitea.log:105521:2024/12/23 08:22:18 ...eb/routing/logger.go:68:func1() [W] router: slow GET /xxxx/xxxxxx/raw/commit/xxxxxxxxxxxxxxxxxxxxxxxxxxx/.editorconfig for 172.18.0.5:53252, elapsed 3526.8ms @ repo/download.go:117(repo.SingleDownload) ```
This commit is contained in:
		| @@ -62,3 +62,14 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error | |||||||
|  |  | ||||||
| 	return filelist, err | 	return filelist, err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // GetTreePathLatestCommitID returns the latest commit of a tree path | ||||||
|  | func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) { | ||||||
|  | 	stdout, _, err := NewCommand(repo.Ctx, "rev-list", "-1"). | ||||||
|  | 		AddDynamicArguments(refName).AddDashesAndList(treePath). | ||||||
|  | 		RunStdString(&RunOpts{Dir: repo.Path}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	return repo.GetCommit(strings.TrimSpace(stdout)) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -25,3 +25,18 @@ func TestSubTree_Issue29101(t *testing.T) { | |||||||
| 		assert.True(t, IsErrNotExist(err)) | 		assert.True(t, IsErrNotExist(err)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func Test_GetTreePathLatestCommit(t *testing.T) { | ||||||
|  | 	repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo6_blame")) | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	defer repo.Close() | ||||||
|  |  | ||||||
|  | 	commitID, err := repo.GetBranchCommitID("master") | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.EqualValues(t, "544d8f7a3b15927cddf2299b4b562d6ebd71b6a7", commitID) | ||||||
|  |  | ||||||
|  | 	commit, err := repo.GetTreePathLatestCommit("master", "blame.txt") | ||||||
|  | 	assert.NoError(t, err) | ||||||
|  | 	assert.NotNil(t, commit) | ||||||
|  | 	assert.EqualValues(t, "45fb6cbc12f970b04eacd5cd4165edd11c8d7376", commit.ID.String()) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -11,7 +11,6 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"path" |  | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| @@ -242,19 +241,14 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn | |||||||
| 		return nil, nil, nil | 		return nil, nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) | 	latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err) | 		ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err) | ||||||
| 		return nil, nil, nil | 		return nil, nil, nil | ||||||
| 	} | 	} | ||||||
|  | 	when := &latestCommit.Committer.When | ||||||
|  |  | ||||||
| 	if len(info) == 1 { | 	return entry.Blob(), entry, when | ||||||
| 		// Not Modified |  | ||||||
| 		lastModified = &info[0].Commit.Committer.When |  | ||||||
| 	} |  | ||||||
| 	blob = entry.Blob() |  | ||||||
|  |  | ||||||
| 	return blob, entry, lastModified |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // GetArchive get archive of a repository | // GetArchive get archive of a repository | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| package repo | package repo | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"path" |  | ||||||
| 	"time" | 	"time" | ||||||
|  |  | ||||||
| 	git_model "code.gitea.io/gitea/models/git" | 	git_model "code.gitea.io/gitea/models/git" | ||||||
| @@ -82,7 +81,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim | |||||||
| 	return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified) | 	return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified) | ||||||
| } | } | ||||||
|  |  | ||||||
| func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) { | func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) { | ||||||
| 	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) | 	entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if git.IsErrNotExist(err) { | 		if git.IsErrNotExist(err) { | ||||||
| @@ -98,19 +97,14 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.T | |||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:]) | 	latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		ctx.ServerError("GetCommitsInfo", err) | 		ctx.ServerError("GetTreePathLatestCommit", err) | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
|  | 	lastModified := &latestCommit.Committer.When | ||||||
|  |  | ||||||
| 	if len(info) == 1 { | 	return entry.Blob(), lastModified | ||||||
| 		// Not Modified |  | ||||||
| 		lastModified = &info[0].Commit.Committer.When |  | ||||||
| 	} |  | ||||||
| 	blob = entry.Blob() |  | ||||||
|  |  | ||||||
| 	return blob, lastModified |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // SingleDownload download a file by repos path | // SingleDownload download a file by repos path | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user