Skip to content

Commit fcc5a65

Browse files
committed
Fix repo file list partial reloading for submodules (#35183)
Fix the TODO and add more tests
1 parent b849c6d commit fcc5a65

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
@@ -67,7 +67,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
6767

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

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
@@ -20,8 +20,8 @@ import (
2020
unit_model "code.gitea.io/gitea/models/unit"
2121
user_model "code.gitea.io/gitea/models/user"
2222
"code.gitea.io/gitea/modules/git"
23-
giturl "code.gitea.io/gitea/modules/git/url"
2423
"code.gitea.io/gitea/modules/gitrepo"
24+
"code.gitea.io/gitea/modules/htmlutil"
2525
"code.gitea.io/gitea/modules/httplib"
2626
"code.gitea.io/gitea/modules/log"
2727
repo_module "code.gitea.io/gitea/modules/repository"
@@ -309,35 +309,41 @@ func handleRepoEmptyOrBroken(ctx *context.Context) {
309309
ctx.Redirect(link)
310310
}
311311

312-
func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) {
313-
// TODO: it needs to use git.NewCommitSubmoduleFile and SubmoduleWebLinkTree to correctly handle relative paths
314-
submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL)
315-
if err != nil {
316-
HandleGitError(ctx, "handleRepoViewSubmodule: ParseRepositoryURL", err)
312+
func isViewHomeOnlyContent(ctx *context.Context) bool {
313+
return ctx.FormBool("only_content")
314+
}
315+
316+
func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.CommitSubmoduleFile) {
317+
submoduleWebLink := commitSubmoduleFile.SubmoduleWebLinkTree(ctx)
318+
if submoduleWebLink == nil {
319+
ctx.Data["NotFoundPrompt"] = ctx.Repo.TreePath
320+
ctx.NotFound(nil)
317321
return
318322
}
319-
submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL)
320-
if httplib.IsCurrentGiteaSiteURL(ctx, submoduleURL) {
321-
ctx.RedirectToCurrentSite(submoduleURL)
322-
} else {
323+
324+
redirectLink := submoduleWebLink.CommitWebLink
325+
if isViewHomeOnlyContent(ctx) {
326+
ctx.Resp.Header().Set("Content-Type", "text/html; charset=utf-8")
327+
_, _ = ctx.Resp.Write([]byte(htmlutil.HTMLFormat(`<a href="%s">%s</a>`, redirectLink, redirectLink)))
328+
} else if !httplib.IsCurrentGiteaSiteURL(ctx, redirectLink) {
323329
// don't auto-redirect to external URL, to avoid open redirect or phishing
324-
ctx.Data["NotFoundPrompt"] = submoduleURL
330+
ctx.Data["NotFoundPrompt"] = redirectLink
325331
ctx.NotFound(nil)
332+
} else {
333+
ctx.Redirect(submoduleWebLink.CommitWebLink)
326334
}
327335
}
328336

329337
func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) {
330338
return func(ctx *context.Context) {
331339
if entry.IsSubModule() {
332-
submodule, err := ctx.Repo.Commit.GetSubModule(entry.Name())
340+
commitSubmoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.Commit, entry.ID)
333341
if err != nil {
334-
HandleGitError(ctx, "prepareToRenderDirOrFile: GetSubModule", err)
342+
HandleGitError(ctx, "prepareToRenderDirOrFile: GetCommitInfoSubmoduleFile", err)
335343
return
336344
}
337-
handleRepoViewSubmodule(ctx, submodule)
338-
return
339-
}
340-
if entry.IsDir() {
345+
handleRepoViewSubmodule(ctx, commitSubmoduleFile)
346+
} else if entry.IsDir() {
341347
prepareToRenderDirectory(ctx)
342348
} else {
343349
prepareToRenderFile(ctx, entry)
@@ -473,7 +479,7 @@ func Home(ctx *context.Context) {
473479
}
474480
}
475481

476-
if ctx.FormBool("only_content") {
482+
if isViewHomeOnlyContent(ctx) {
477483
ctx.HTML(http.StatusOK, tplRepoViewContent)
478484
} else if len(treeNames) != 0 {
479485
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)