Skip to content

Commit c3f5ea3

Browse files
authored
Fix repo file list partial reloading for submodules (go-gitea#35183)
Fix the TODO and add more tests
1 parent 2e8a4a0 commit c3f5ea3

File tree

6 files changed

+40
-32
lines changed

6 files changed

+40
-32
lines changed

modules/git/commit_info.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,21 @@
33

44
package git
55

6-
import "path"
7-
86
// CommitInfo describes the first commit with the provided entry
97
type CommitInfo struct {
108
Entry *TreeEntry
119
Commit *Commit
1210
SubmoduleFile *CommitSubmoduleFile
1311
}
1412

15-
func getCommitInfoSubmoduleFile(repoLink string, entry *TreeEntry, commit *Commit, treePathDir string) (*CommitSubmoduleFile, error) {
16-
fullPath := path.Join(treePathDir, entry.Name())
13+
func GetCommitInfoSubmoduleFile(repoLink, fullPath string, commit *Commit, refCommitID ObjectID) (*CommitSubmoduleFile, error) {
1714
submodule, err := commit.GetSubModule(fullPath)
1815
if err != nil {
1916
return nil, err
2017
}
2118
if submodule == nil {
2219
// unable to find submodule from ".gitmodules" file
23-
return NewCommitSubmoduleFile(repoLink, fullPath, "", entry.ID.String()), nil
20+
return NewCommitSubmoduleFile(repoLink, fullPath, "", refCommitID.String()), nil
2421
}
25-
return NewCommitSubmoduleFile(repoLink, fullPath, submodule.URL, entry.ID.String()), nil
22+
return NewCommitSubmoduleFile(repoLink, fullPath, submodule.URL, refCommitID.String()), nil
2623
}

modules/git/commit_info_gogit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
7373

7474
// If the entry is a submodule, add a submodule file for this
7575
if entry.IsSubModule() {
76-
commitsInfo[i].SubmoduleFile, err = getCommitInfoSubmoduleFile(repoLink, entry, commit, treePath)
76+
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(repoLink, path.Join(treePath, entry.Name()), commit, entry.ID)
7777
if err != nil {
7878
return nil, nil, err
7979
}

modules/git/commit_info_nogogit.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
6464

6565
// If the entry is a submodule, add a submodule file for this
6666
if entry.IsSubModule() {
67-
commitsInfo[i].SubmoduleFile, err = getCommitInfoSubmoduleFile(repoLink, entry, commit, treePath)
67+
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(repoLink, path.Join(treePath, entry.Name()), commit, entry.ID)
6868
if err != nil {
6969
return nil, nil, err
7070
}

modules/git/commit_info_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,9 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
125125
t.Run("NonExistingSubmoduleAsNil", func(t *testing.T) {
126126
commit, err := bareRepo1.GetCommit("HEAD")
127127
require.NoError(t, err)
128-
tree, err := commit.GetTreeEntryByPath("file1.txt")
128+
treeEntry, err := commit.GetTreeEntryByPath("file1.txt")
129129
require.NoError(t, err)
130-
cisf, err := getCommitInfoSubmoduleFile("/any/repo-link", tree, commit, "")
130+
cisf, err := GetCommitInfoSubmoduleFile("/any/repo-link", "file1.txt", commit, treeEntry.ID)
131131
require.NoError(t, err)
132132
assert.Equal(t, &CommitSubmoduleFile{
133133
repoLink: "/any/repo-link",

routers/web/repo/view_home.go

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919
unit_model "code.gitea.io/gitea/models/unit"
2020
user_model "code.gitea.io/gitea/models/user"
2121
"code.gitea.io/gitea/modules/git"
22-
giturl "code.gitea.io/gitea/modules/git/url"
2322
"code.gitea.io/gitea/modules/gitrepo"
23+
"code.gitea.io/gitea/modules/htmlutil"
2424
"code.gitea.io/gitea/modules/httplib"
2525
"code.gitea.io/gitea/modules/log"
2626
repo_module "code.gitea.io/gitea/modules/repository"
@@ -258,35 +258,41 @@ func handleRepoEmptyOrBroken(ctx *context.Context) {
258258
ctx.Redirect(link)
259259
}
260260

261-
func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) {
262-
// TODO: it needs to use git.NewCommitSubmoduleFile and SubmoduleWebLinkTree to correctly handle relative paths
263-
submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL)
264-
if err != nil {
265-
HandleGitError(ctx, "handleRepoViewSubmodule: ParseRepositoryURL", err)
261+
func isViewHomeOnlyContent(ctx *context.Context) bool {
262+
return ctx.FormBool("only_content")
263+
}
264+
265+
func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.CommitSubmoduleFile) {
266+
submoduleWebLink := commitSubmoduleFile.SubmoduleWebLinkTree(ctx)
267+
if submoduleWebLink == nil {
268+
ctx.Data["NotFoundPrompt"] = ctx.Repo.TreePath
269+
ctx.NotFound(nil)
266270
return
267271
}
268-
submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL)
269-
if httplib.IsCurrentGiteaSiteURL(ctx, submoduleURL) {
270-
ctx.RedirectToCurrentSite(submoduleURL)
271-
} else {
272+
273+
redirectLink := submoduleWebLink.CommitWebLink
274+
if isViewHomeOnlyContent(ctx) {
275+
ctx.Resp.Header().Set("Content-Type", "text/html; charset=utf-8")
276+
_, _ = ctx.Resp.Write([]byte(htmlutil.HTMLFormat(`<a href="%s">%s</a>`, redirectLink, redirectLink)))
277+
} else if !httplib.IsCurrentGiteaSiteURL(ctx, redirectLink) {
272278
// don't auto-redirect to external URL, to avoid open redirect or phishing
273-
ctx.Data["NotFoundPrompt"] = submoduleURL
279+
ctx.Data["NotFoundPrompt"] = redirectLink
274280
ctx.NotFound(nil)
281+
} else {
282+
ctx.Redirect(submoduleWebLink.CommitWebLink)
275283
}
276284
}
277285

278286
func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) {
279287
return func(ctx *context.Context) {
280288
if entry.IsSubModule() {
281-
submodule, err := ctx.Repo.Commit.GetSubModule(entry.Name())
289+
commitSubmoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.Commit, entry.ID)
282290
if err != nil {
283-
HandleGitError(ctx, "prepareToRenderDirOrFile: GetSubModule", err)
291+
HandleGitError(ctx, "prepareToRenderDirOrFile: GetCommitInfoSubmoduleFile", err)
284292
return
285293
}
286-
handleRepoViewSubmodule(ctx, submodule)
287-
return
288-
}
289-
if entry.IsDir() {
294+
handleRepoViewSubmodule(ctx, commitSubmoduleFile)
295+
} else if entry.IsDir() {
290296
prepareToRenderDirectory(ctx)
291297
} else {
292298
prepareFileView(ctx, entry)
@@ -441,7 +447,7 @@ func Home(ctx *context.Context) {
441447
}
442448
}
443449

444-
if ctx.FormBool("only_content") {
450+
if isViewHomeOnlyContent(ctx) {
445451
ctx.HTML(http.StatusOK, tplRepoViewContent)
446452
} else if len(treeNames) != 0 {
447453
ctx.HTML(http.StatusOK, tplRepoView)

routers/web/repo/view_home_test.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99

1010
"code.gitea.io/gitea/models/unittest"
1111
git_module "code.gitea.io/gitea/modules/git"
12-
"code.gitea.io/gitea/modules/setting"
1312
"code.gitea.io/gitea/services/contexttest"
1413

1514
"github.com/stretchr/testify/assert"
@@ -19,14 +18,20 @@ func TestViewHomeSubmoduleRedirect(t *testing.T) {
1918
unittest.PrepareTestEnv(t)
2019

2120
ctx, _ := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
22-
submodule := &git_module.SubModule{Path: "test-submodule", URL: setting.AppURL + "user2/repo-other.git"}
21+
submodule := git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
2322
handleRepoViewSubmodule(ctx, submodule)
2423
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
25-
assert.Equal(t, "/user2/repo-other", ctx.Resp.Header().Get("Location"))
24+
assert.Equal(t, "/user2/repo-other/tree/any-ref-id", ctx.Resp.Header().Get("Location"))
2625

2726
ctx, _ = contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
28-
submodule = &git_module.SubModule{Path: "test-submodule", URL: "https://other/user2/repo-other.git"}
27+
submodule = git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "https://other/user2/repo-other.git", "any-ref-id")
2928
handleRepoViewSubmodule(ctx, submodule)
3029
// do not auto-redirect for external URLs, to avoid open redirect or phishing
3130
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
31+
32+
ctx, respWriter := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule?only_content=true")
33+
submodule = git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
34+
handleRepoViewSubmodule(ctx, submodule)
35+
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
36+
assert.Equal(t, `<a href="/user2/repo-other/tree/any-ref-id">/user2/repo-other/tree/any-ref-id</a>`, respWriter.Body.String())
3237
}

0 commit comments

Comments
 (0)