Skip to content

Commit d51209c

Browse files
authored
Merge branch 'main' into support-choose-email-more
2 parents d8b90aa + b57d9f4 commit d51209c

File tree

12 files changed

+77
-51
lines changed

12 files changed

+77
-51
lines changed

routers/web/repo/branch.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ func Branches(ctx *context.Context) {
9393

9494
// DeleteBranchPost responses for delete merged branch
9595
func DeleteBranchPost(ctx *context.Context) {
96-
defer redirect(ctx)
96+
defer jsonRedirectBranches(ctx)
9797
branchName := ctx.FormString("name")
9898

9999
if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName, nil); err != nil {
@@ -120,7 +120,7 @@ func DeleteBranchPost(ctx *context.Context) {
120120

121121
// RestoreBranchPost responses for delete merged branch
122122
func RestoreBranchPost(ctx *context.Context) {
123-
defer redirect(ctx)
123+
defer jsonRedirectBranches(ctx)
124124

125125
branchID := ctx.FormInt64("branch_id")
126126
branchName := ctx.FormString("name")
@@ -170,7 +170,7 @@ func RestoreBranchPost(ctx *context.Context) {
170170
ctx.Flash.Success(ctx.Tr("repo.branch.restore_success", deletedBranch.Name))
171171
}
172172

173-
func redirect(ctx *context.Context) {
173+
func jsonRedirectBranches(ctx *context.Context) {
174174
ctx.JSONRedirect(ctx.Repo.RepoLink + "/branches?page=" + url.QueryEscape(ctx.FormString("page")))
175175
}
176176

routers/web/repo/view_home.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,8 +413,19 @@ func Home(ctx *context.Context) {
413413
ctx.HTML(http.StatusOK, tplRepoHome)
414414
}
415415

416-
// HomeRedirect redirects from /tree/* to /src/* in order to maintain a similar URL structure.
417-
func HomeRedirect(ctx *context.Context) {
418-
remainder := ctx.PathParam("*")
419-
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(remainder))
416+
func RedirectRepoTreeToSrc(ctx *context.Context) {
417+
// Redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*",
418+
// then use the deprecated "/src/*" handler to guess the ref type and render a file list page.
419+
// This is done intentionally so that Gitea's repo URL structure matches other forges (GitHub/GitLab) provide,
420+
// allowing us to construct submodule URLs across forges easily.
421+
// For example, when viewing a submodule, we can simply construct the link as:
422+
// * "https://gitea/owner/repo/tree/{CommitID}"
423+
// * "https://github/owner/repo/tree/{CommitID}"
424+
// * "https://gitlab/owner/repo/tree/{CommitID}"
425+
// Then no matter which forge the submodule is using, the link works.
426+
redirect := ctx.Repo.RepoLink + "/src/" + ctx.PathParamRaw("*")
427+
if ctx.Req.URL.RawQuery != "" {
428+
redirect += "?" + ctx.Req.URL.RawQuery
429+
}
430+
ctx.Redirect(redirect)
420431
}

routers/web/web.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,13 +1582,7 @@ func registerRoutes(m *web.Router) {
15821582
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.Home)
15831583
m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
15841584
}, repo.SetEditorconfigIfExists)
1585-
1586-
// Add a /tree/* path to redirect to the /src/* path, which
1587-
// will redirect to the canonical URL for that ref. This is
1588-
// included so that Gitea's repo URL structure matches what
1589-
// other forges provide, allowing clients to construct URLs
1590-
// that work across forges.
1591-
m.Get("/tree/*", repo.HomeRedirect)
1585+
m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*"
15921586

15931587
m.Get("/forks", context.RepoRef(), repo.Forks)
15941588
m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff)

services/context/api.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
293293
return
294294
}
295295

296-
refName, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref"))
296+
refName, _, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref"))
297297
var err error
298298

299299
if ctx.Repo.GitRepo.IsBranchExist(refName) {

services/context/repo.go

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -686,24 +686,24 @@ func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool
686686
return ""
687687
}
688688

689-
func getRefNameLegacy(ctx *Base, repo *Repository, reqPath, extraRef string) (string, git.RefType) {
689+
func getRefNameLegacy(ctx *Base, repo *Repository, reqPath, extraRef string) (refName string, refType git.RefType, fallbackDefaultBranch bool) {
690690
reqRefPath := path.Join(extraRef, reqPath)
691691
reqRefPathParts := strings.Split(reqRefPath, "/")
692692
if refName := getRefName(ctx, repo, reqRefPath, git.RefTypeBranch); refName != "" {
693-
return refName, git.RefTypeBranch
693+
return refName, git.RefTypeBranch, false
694694
}
695695
if refName := getRefName(ctx, repo, reqRefPath, git.RefTypeTag); refName != "" {
696-
return refName, git.RefTypeTag
696+
return refName, git.RefTypeTag, false
697697
}
698698
if git.IsStringLikelyCommitID(git.ObjectFormatFromName(repo.Repository.ObjectFormatName), reqRefPathParts[0]) {
699699
// FIXME: this logic is different from other types. Ideally, it should also try to GetCommit to check if it exists
700700
repo.TreePath = strings.Join(reqRefPathParts[1:], "/")
701-
return reqRefPathParts[0], git.RefTypeCommit
701+
return reqRefPathParts[0], git.RefTypeCommit, false
702702
}
703703
// FIXME: the old code falls back to default branch if "ref" doesn't exist, there could be an edge case:
704704
// "README?ref=no-such" would read the README file from the default branch, but the user might expect a 404
705705
repo.TreePath = reqPath
706-
return repo.Repository.DefaultBranch, git.RefTypeBranch
706+
return repo.Repository.DefaultBranch, git.RefTypeBranch, true
707707
}
708708

709709
func getRefName(ctx *Base, repo *Repository, path string, refType git.RefType) string {
@@ -838,8 +838,9 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
838838
}
839839
} else { // there is a path in request
840840
guessLegacyPath := refType == ""
841+
fallbackDefaultBranch := false
841842
if guessLegacyPath {
842-
refShortName, refType = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
843+
refShortName, refType, fallbackDefaultBranch = getRefNameLegacy(ctx.Base, ctx.Repo, reqPath, "")
843844
} else {
844845
refShortName = getRefName(ctx.Base, ctx.Repo, reqPath, refType)
845846
}
@@ -897,12 +898,24 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
897898

898899
if guessLegacyPath {
899900
// redirect from old URL scheme to new URL scheme
900-
prefix := strings.TrimPrefix(setting.AppSubURL+strings.ToLower(strings.TrimSuffix(ctx.Req.URL.Path, ctx.PathParam("*"))), strings.ToLower(ctx.Repo.RepoLink))
901-
redirect := path.Join(
902-
ctx.Repo.RepoLink,
903-
util.PathEscapeSegments(prefix),
904-
ctx.Repo.RefTypeNameSubURL(),
905-
util.PathEscapeSegments(ctx.Repo.TreePath))
901+
// * /user2/repo1/commits/master => /user2/repo1/commits/branch/master
902+
// * /user2/repo1/src/master => /user2/repo1/src/branch/master
903+
// * /user2/repo1/src/README.md => /user2/repo1/src/branch/master/README.md (fallback to default branch)
904+
var redirect string
905+
refSubPath := "src"
906+
// remove the "/subpath/owner/repo/" prefix, the names are case-insensitive
907+
remainingLowerPath, cut := strings.CutPrefix(setting.AppSubURL+strings.ToLower(ctx.Req.URL.Path), strings.ToLower(ctx.Repo.RepoLink)+"/")
908+
if cut {
909+
refSubPath, _, _ = strings.Cut(remainingLowerPath, "/") // it could be "src" or "commits"
910+
}
911+
if fallbackDefaultBranch {
912+
redirect = fmt.Sprintf("%s/%s/%s/%s/%s", ctx.Repo.RepoLink, refSubPath, refType, util.PathEscapeSegments(refShortName), ctx.PathParamRaw("*"))
913+
} else {
914+
redirect = fmt.Sprintf("%s/%s/%s/%s", ctx.Repo.RepoLink, refSubPath, refType, ctx.PathParamRaw("*"))
915+
}
916+
if ctx.Req.URL.RawQuery != "" {
917+
redirect += "?" + ctx.Req.URL.RawQuery
918+
}
906919
ctx.Redirect(redirect)
907920
return
908921
}

templates/repo/issue/sidebar/assignee_list.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@
1515
<i class="icon">{{svg "octicon-search" 16}}</i>
1616
<input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_assignees"}}">
1717
</div>
18-
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}</div>
1918
<div class="scrolling menu flex-items-block">
19+
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_assignees"}}</div>
20+
<div class="divider"></div>
2021
{{range $data.CandidateAssignees}}
2122
<a class="item" href="#" data-value="{{.ID}}">
2223
<span class="item-check-mark">{{svg "octicon-check"}}</span>

templates/repo/issue/sidebar/label_list.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616
<i class="icon">{{svg "octicon-search" 16}}</i>
1717
<input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_labels"}}">
1818
</div>
19-
<a class="item clear-selection" href="#">{{ctx.Locale.Tr "repo.issues.new.clear_labels"}}</a>
2019
<div class="scrolling menu">
20+
<a class="item clear-selection" href="#">{{ctx.Locale.Tr "repo.issues.new.clear_labels"}}</a>
21+
<div class="divider"></div>
2122
{{$previousExclusiveScope := "_no_scope"}}
2223
{{range $data.RepoLabels}}
2324
{{$exclusiveScope := .ExclusiveScope}}

templates/repo/issue/sidebar/milestone_list.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
<i class="icon">{{svg "octicon-search"}}</i>
1919
<input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_milestones"}}">
2020
</div>
21-
<div class="divider"></div>
22-
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
2321
<div class="scrolling menu">
22+
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
23+
<div class="divider"></div>
2424
{{if $data.OpenMilestones}}
2525
<div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div>
2626
{{range $data.OpenMilestones}}

templates/repo/issue/sidebar/project_list.tmpl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
<input type="text" placeholder="{{ctx.Locale.Tr "repo.issues.filter_projects"}}">
1818
</div>
1919
{{end}}
20-
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_projects"}}</div>
2120
<div class="scrolling menu">
21+
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_projects"}}</div>
22+
<div class="divider"></div>
2223
{{if $data.OpenProjects}}
2324
<div class="header">{{ctx.Locale.Tr "repo.issues.new.open_projects"}}</div>
2425
{{range $data.OpenProjects}}

tests/integration/links_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,11 @@ func TestRedirectsNoLogin(t *testing.T) {
5252
redirects := []struct{ from, to string }{
5353
{"/user2/repo1/commits/master", "/user2/repo1/commits/branch/master"},
5454
{"/user2/repo1/src/master", "/user2/repo1/src/branch/master"},
55-
{"/user2/repo1/src/master/file.txt", "/user2/repo1/src/branch/master/file.txt"},
56-
{"/user2/repo1/src/master/directory/file.txt", "/user2/repo1/src/branch/master/directory/file.txt"},
57-
{"/user/avatar/Ghost/-1", "/assets/img/avatar_default.png"},
55+
{"/user2/repo1/src/master/a%2fb.txt", "/user2/repo1/src/branch/master/a%2fb.txt"},
56+
{"/user2/repo1/src/master/directory/file.txt?a=1", "/user2/repo1/src/branch/master/directory/file.txt?a=1"},
57+
{"/user2/repo1/tree/a%2fb?a=1", "/user2/repo1/src/a%2fb?a=1"},
58+
{"/user/avatar/GhosT/-1", "/assets/img/avatar_default.png"},
59+
{"/user/avatar/Gitea-ActionS/0", "/assets/img/avatar_default.png"},
5860
{"/api/v1/swagger", "/api/swagger"},
5961
}
6062
for _, c := range redirects {

0 commit comments

Comments
 (0)