Skip to content

Commit f4ccbd3

Browse files
authored
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) ```
1 parent 344c89e commit f4ccbd3

File tree

4 files changed

+35
-21
lines changed

4 files changed

+35
-21
lines changed

modules/git/tree.go

+11
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,14 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error
6262

6363
return filelist, err
6464
}
65+
66+
// GetTreePathLatestCommitID returns the latest commit of a tree path
67+
func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) {
68+
stdout, _, err := NewCommand(repo.Ctx, "rev-list", "-1").
69+
AddDynamicArguments(refName).AddDashesAndList(treePath).
70+
RunStdString(&RunOpts{Dir: repo.Path})
71+
if err != nil {
72+
return nil, err
73+
}
74+
return repo.GetCommit(strings.TrimSpace(stdout))
75+
}

modules/git/tree_test.go

+15
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,18 @@ func TestSubTree_Issue29101(t *testing.T) {
2525
assert.True(t, IsErrNotExist(err))
2626
}
2727
}
28+
29+
func Test_GetTreePathLatestCommit(t *testing.T) {
30+
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo6_blame"))
31+
assert.NoError(t, err)
32+
defer repo.Close()
33+
34+
commitID, err := repo.GetBranchCommitID("master")
35+
assert.NoError(t, err)
36+
assert.EqualValues(t, "544d8f7a3b15927cddf2299b4b562d6ebd71b6a7", commitID)
37+
38+
commit, err := repo.GetTreePathLatestCommit("master", "blame.txt")
39+
assert.NoError(t, err)
40+
assert.NotNil(t, commit)
41+
assert.EqualValues(t, "45fb6cbc12f970b04eacd5cd4165edd11c8d7376", commit.ID.String())
42+
}

routers/api/v1/repo/file.go

+4-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"fmt"
1212
"io"
1313
"net/http"
14-
"path"
1514
"strings"
1615
"time"
1716

@@ -242,19 +241,14 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn
242241
return nil, nil, nil
243242
}
244243

245-
info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
244+
latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
246245
if err != nil {
247-
ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err)
246+
ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err)
248247
return nil, nil, nil
249248
}
249+
when := &latestCommit.Committer.When
250250

251-
if len(info) == 1 {
252-
// Not Modified
253-
lastModified = &info[0].Commit.Committer.When
254-
}
255-
blob = entry.Blob()
256-
257-
return blob, entry, lastModified
251+
return entry.Blob(), entry, when
258252
}
259253

260254
// GetArchive get archive of a repository

routers/web/repo/download.go

+5-11
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
package repo
66

77
import (
8-
"path"
98
"time"
109

1110
git_model "code.gitea.io/gitea/models/git"
@@ -82,7 +81,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
8281
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
8382
}
8483

85-
func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) {
84+
func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
8685
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
8786
if err != nil {
8887
if git.IsErrNotExist(err) {
@@ -98,19 +97,14 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.T
9897
return nil, nil
9998
}
10099

101-
info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
100+
latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
102101
if err != nil {
103-
ctx.ServerError("GetCommitsInfo", err)
102+
ctx.ServerError("GetTreePathLatestCommit", err)
104103
return nil, nil
105104
}
105+
lastModified := &latestCommit.Committer.When
106106

107-
if len(info) == 1 {
108-
// Not Modified
109-
lastModified = &info[0].Commit.Committer.When
110-
}
111-
blob = entry.Blob()
112-
113-
return blob, lastModified
107+
return entry.Blob(), lastModified
114108
}
115109

116110
// SingleDownload download a file by repos path

0 commit comments

Comments
 (0)