diff --git a/modules/git/commit_submodule_file.go b/modules/git/commit_submodule_file.go
index 2ac744fbf6..729401f752 100644
--- a/modules/git/commit_submodule_file.go
+++ b/modules/git/commit_submodule_file.go
@@ -46,9 +46,9 @@ func (sf *CommitSubmoduleFile) SubmoduleWebLink(ctx context.Context, optCommitID
 	if len(optCommitID) == 2 {
 		commitLink = sf.repoLink + "/compare/" + optCommitID[0] + "..." + optCommitID[1]
 	} else if len(optCommitID) == 1 {
-		commitLink = sf.repoLink + "/commit/" + optCommitID[0]
+		commitLink = sf.repoLink + "/tree/" + optCommitID[0]
 	} else {
-		commitLink = sf.repoLink + "/commit/" + sf.refID
+		commitLink = sf.repoLink + "/tree/" + sf.refID
 	}
 	return &SubmoduleWebLink{RepoWebLink: sf.repoLink, CommitWebLink: commitLink}
 }
diff --git a/modules/git/commit_submodule_file_test.go b/modules/git/commit_submodule_file_test.go
index 4b5b767612..98342aa9e9 100644
--- a/modules/git/commit_submodule_file_test.go
+++ b/modules/git/commit_submodule_file_test.go
@@ -15,11 +15,11 @@ func TestCommitSubmoduleLink(t *testing.T) {
 
 	wl := sf.SubmoduleWebLink(context.Background())
 	assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink)
-	assert.Equal(t, "https://github.com/user/repo/commit/aaaa", wl.CommitWebLink)
+	assert.Equal(t, "https://github.com/user/repo/tree/aaaa", wl.CommitWebLink)
 
 	wl = sf.SubmoduleWebLink(context.Background(), "1111")
 	assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink)
-	assert.Equal(t, "https://github.com/user/repo/commit/1111", wl.CommitWebLink)
+	assert.Equal(t, "https://github.com/user/repo/tree/1111", wl.CommitWebLink)
 
 	wl = sf.SubmoduleWebLink(context.Background(), "1111", "2222")
 	assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink)
diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go
index 456efb96f6..6c6e007b50 100644
--- a/routers/web/repo/view_home.go
+++ b/routers/web/repo/view_home.go
@@ -412,3 +412,9 @@ func Home(ctx *context.Context) {
 
 	ctx.HTML(http.StatusOK, tplRepoHome)
 }
+
+// HomeRedirect redirects from /tree/* to /src/* in order to maintain a similar URL structure.
+func HomeRedirect(ctx *context.Context) {
+	remainder := ctx.PathParam("*")
+	ctx.Redirect(ctx.Repo.RepoLink + "/src/" + util.PathEscapeSegments(remainder))
+}
diff --git a/routers/web/web.go b/routers/web/web.go
index fc01d81b50..096f1e6bbe 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -1584,6 +1584,13 @@ func registerRoutes(m *web.Router) {
 			m.Get("/*", context.RepoRefByType(""), repo.Home) // "/*" route is deprecated, and kept for backward compatibility
 		}, repo.SetEditorconfigIfExists)
 
+		// Add a /tree/* path to redirect to the /src/* path, which
+		// will redirect to the canonical URL for that ref. This is
+		// included so that Gitea's repo URL structure matches what
+		// other forges provide, allowing clients to construct URLs
+		// that work across forges.
+		m.Get("/tree/*", repo.HomeRedirect)
+
 		m.Get("/forks", context.RepoRef(), repo.Forks)
 		m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff)
 		m.Post("/lastcommit/*", context.RepoRefByType(git.RefTypeCommit), repo.LastCommit)
diff --git a/services/gitdiff/submodule_test.go b/services/gitdiff/submodule_test.go
index 89f32c0e0c..f0eab5557c 100644
--- a/services/gitdiff/submodule_test.go
+++ b/services/gitdiff/submodule_test.go
@@ -230,7 +230,7 @@ func TestSubmoduleInfo(t *testing.T) {
 	assert.EqualValues(t, "name", sdi.SubmoduleRepoLinkHTML(ctx))
 
 	sdi.SubmoduleFile = git.NewCommitSubmoduleFile("https://github.com/owner/repo", "1234")
-	assert.EqualValues(t, `<a href="https://github.com/owner/repo/commit/1111">1111</a>`, sdi.CommitRefIDLinkHTML(ctx, "1111"))
+	assert.EqualValues(t, `<a href="https://github.com/owner/repo/tree/1111">1111</a>`, sdi.CommitRefIDLinkHTML(ctx, "1111"))
 	assert.EqualValues(t, `<a href="https://github.com/owner/repo/compare/aaaa...bbbb">aaaa...bbbb</a>`, sdi.CompareRefIDLinkHTML(ctx))
 	assert.EqualValues(t, `<a href="https://github.com/owner/repo">name</a>`, sdi.SubmoduleRepoLinkHTML(ctx))
 }