diff --git a/contrib/fixtures/fixture_generation.go b/contrib/fixtures/fixture_generation.go deleted file mode 100644 index 31797cc800f..00000000000 --- a/contrib/fixtures/fixture_generation.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -//nolint:forbidigo -package main - -import ( - "context" - "fmt" - "os" - "path/filepath" - - "code.gitea.io/gitea/models" - "code.gitea.io/gitea/models/unittest" -) - -// To generate derivative fixtures, execute the following from Gitea's repository base dir: -// go run -tags 'sqlite sqlite_unlock_notify' contrib/fixtures/fixture_generation.go [fixture...] - -var ( - generators = []struct { - gen func(ctx context.Context) (string, error) - name string - }{ - { - models.GetYamlFixturesAccess, "access", - }, - } - fixturesDir string -) - -func main() { - pathToGiteaRoot := "." - fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures") - if err := unittest.CreateTestEngine(unittest.FixturesOptions{ - Dir: fixturesDir, - }); err != nil { - fmt.Printf("CreateTestEngine: %+v", err) - os.Exit(1) - } - if err := unittest.PrepareTestDatabase(); err != nil { - fmt.Printf("PrepareTestDatabase: %+v\n", err) - os.Exit(1) - } - ctx := context.Background() - if len(os.Args) == 0 { - for _, r := range os.Args { - if err := generate(ctx, r); err != nil { - fmt.Printf("generate '%s': %+v\n", r, err) - os.Exit(1) - } - } - } else { - for _, g := range generators { - if err := generate(ctx, g.name); err != nil { - fmt.Printf("generate '%s': %+v\n", g.name, err) - os.Exit(1) - } - } - } -} - -func generate(ctx context.Context, name string) error { - for _, g := range generators { - if g.name == name { - data, err := g.gen(ctx) - if err != nil { - return err - } - path := filepath.Join(fixturesDir, name+".yml") - if err := os.WriteFile(path, []byte(data), 0o644); err != nil { - return fmt.Errorf("%s: %+v", path, err) - } - fmt.Printf("%s created.\n", path) - return nil - } - } - - return fmt.Errorf("generator not found") -} diff --git a/models/fixture_generation.go b/models/fixture_generation.go deleted file mode 100644 index 6234caefada..00000000000 --- a/models/fixture_generation.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package models - -import ( - "context" - "fmt" - "strings" - - "code.gitea.io/gitea/models/db" - access_model "code.gitea.io/gitea/models/perm/access" - repo_model "code.gitea.io/gitea/models/repo" -) - -// GetYamlFixturesAccess returns a string containing the contents -// for the access table, as recalculated using repo.RecalculateAccesses() -func GetYamlFixturesAccess(ctx context.Context) (string, error) { - repos := make([]*repo_model.Repository, 0, 50) - if err := db.GetEngine(ctx).Find(&repos); err != nil { - return "", err - } - - for _, repo := range repos { - repo.MustOwner(ctx) - if err := access_model.RecalculateAccesses(ctx, repo); err != nil { - return "", err - } - } - - var b strings.Builder - - accesses := make([]*access_model.Access, 0, 200) - if err := db.GetEngine(ctx).OrderBy("user_id, repo_id").Find(&accesses); err != nil { - return "", err - } - - for i, a := range accesses { - fmt.Fprintf(&b, "-\n") - fmt.Fprintf(&b, " id: %d\n", i+1) - fmt.Fprintf(&b, " user_id: %d\n", a.UserID) - fmt.Fprintf(&b, " repo_id: %d\n", a.RepoID) - fmt.Fprintf(&b, " mode: %d\n", a.Mode) - if i < len(accesses)-1 { - fmt.Fprintf(&b, "\n") - } - } - - return b.String(), nil -} diff --git a/models/fixture_test.go b/models/fixture_test.go deleted file mode 100644 index de5f412388d..00000000000 --- a/models/fixture_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2020 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package models - -import ( - "context" - "os" - "path/filepath" - "testing" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/util" - - "github.com/stretchr/testify/assert" -) - -func TestFixtureGeneration(t *testing.T) { - assert.NoError(t, unittest.PrepareTestDatabase()) - - test := func(ctx context.Context, gen func(ctx context.Context) (string, error), name string) { - expected, err := gen(ctx) - if !assert.NoError(t, err) { - return - } - p := filepath.Join(unittest.FixturesDir(), name+".yml") - bytes, err := os.ReadFile(p) - if !assert.NoError(t, err) { - return - } - data := string(util.NormalizeEOL(bytes)) - assert.EqualValues(t, expected, data, "Differences detected for %s", p) - } - - test(db.DefaultContext, GetYamlFixturesAccess, "access") -} diff --git a/models/repo/repo.go b/models/repo/repo.go index 4a12de9d98d..8d211caf40b 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -617,7 +617,7 @@ func (repo *Repository) CanEnableEditor() bool { // DescriptionHTML does special handles to description and return HTML string. func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML { - desc, err := markup.RenderDescriptionHTML(markup.NewRenderContext(ctx), repo.Description) + desc, err := markup.PostProcessDescriptionHTML(markup.NewRenderContext(ctx), repo.Description) if err != nil { log.Error("Failed to render description for %s (ID: %d): %v", repo.Name, repo.ID, err) return template.HTML(markup.SanitizeDescription(repo.Description)) diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go index 84580be9a5b..993013eef7b 100644 --- a/modules/git/repo_commit_gogit.go +++ b/modules/git/repo_commit_gogit.go @@ -14,9 +14,16 @@ import ( "github.com/go-git/go-git/v5/plumbing/object" ) -// GetRefCommitID returns the last commit ID string of given reference (branch or tag). +// GetRefCommitID returns the last commit ID string of given reference. func (repo *Repository) GetRefCommitID(name string) (string, error) { - ref, err := repo.gogitRepo.Reference(plumbing.ReferenceName(name), true) + if plumbing.IsHash(name) { + return name, nil + } + refName := plumbing.ReferenceName(name) + if err := refName.Validate(); err != nil { + return "", err + } + ref, err := repo.gogitRepo.Reference(refName, true) if err != nil { if err == plumbing.ErrReferenceNotFound { return "", ErrNotExist{ diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go index 19983b47b19..4c26fa2a486 100644 --- a/modules/git/repo_commit_test.go +++ b/modules/git/repo_commit_test.go @@ -101,3 +101,28 @@ func TestRepository_CommitsBetweenIDs(t *testing.T) { assert.Len(t, commits, c.ExpectedCommits, "case %d", i) } } + +func TestGetRefCommitID(t *testing.T) { + bareRepo1Path := filepath.Join(testReposDir, "repo1_bare") + bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path) + assert.NoError(t, err) + defer bareRepo1.Close() + + // these test case are specific to the repo1_bare test repo + testCases := []struct { + Ref string + ExpectedCommitID string + }{ + {RefNameFromBranch("master").String(), "ce064814f4a0d337b333e646ece456cd39fab612"}, + {RefNameFromBranch("branch1").String(), "2839944139e0de9737a044f78b0e4b40d989a9e3"}, + {RefNameFromTag("test").String(), "3ad28a9149a2864384548f3d17ed7f38014c9e8a"}, + {"ce064814f4a0d337b333e646ece456cd39fab612", "ce064814f4a0d337b333e646ece456cd39fab612"}, + } + + for _, testCase := range testCases { + commitID, err := bareRepo1.GetRefCommitID(testCase.Ref) + if assert.NoError(t, err) { + assert.Equal(t, testCase.ExpectedCommitID, commitID) + } + } +} diff --git a/modules/markup/html.go b/modules/markup/html.go index 04b768bb8ec..25628db39e4 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -159,9 +159,9 @@ func PostProcessDefault(ctx *RenderContext, input io.Reader, output io.Writer) e return postProcess(ctx, procs, input, output) } -// RenderCommitMessage will use the same logic as PostProcess, but will disable +// PostProcessCommitMessage will use the same logic as PostProcess, but will disable // the shortLinkProcessor. -func RenderCommitMessage(ctx *RenderContext, content string) (string, error) { +func PostProcessCommitMessage(ctx *RenderContext, content string) (string, error) { procs := []processor{ fullIssuePatternProcessor, comparePatternProcessor, @@ -183,11 +183,11 @@ var emojiProcessors = []processor{ emojiProcessor, } -// RenderCommitMessageSubject will use the same logic as PostProcess and -// RenderCommitMessage, but will disable the shortLinkProcessor and +// PostProcessCommitMessageSubject will use the same logic as PostProcess and +// PostProcessCommitMessage, but will disable the shortLinkProcessor and // emailAddressProcessor, will add a defaultLinkProcessor if defaultLink is set, // which changes every text node into a link to the passed default link. -func RenderCommitMessageSubject(ctx *RenderContext, defaultLink, content string) (string, error) { +func PostProcessCommitMessageSubject(ctx *RenderContext, defaultLink, content string) (string, error) { procs := []processor{ fullIssuePatternProcessor, comparePatternProcessor, @@ -211,15 +211,33 @@ func RenderCommitMessageSubject(ctx *RenderContext, defaultLink, content string) return postProcessString(ctx, procs, content) } -// RenderIssueTitle to process title on individual issue/pull page -func RenderIssueTitle(ctx *RenderContext, title string) (string, error) { - // do not render other issue/commit links in an issue's title - which in most cases is already a link. +// PostProcessIssueTitle to process title on individual issue/pull page +func PostProcessIssueTitle(ctx *RenderContext, title string) (string, error) { return postProcessString(ctx, []processor{ + issueIndexPatternProcessor, + commitCrossReferencePatternProcessor, + hashCurrentPatternProcessor, emojiShortCodeProcessor, emojiProcessor, }, title) } +// PostProcessDescriptionHTML will use similar logic as PostProcess, but will +// use a single special linkProcessor. +func PostProcessDescriptionHTML(ctx *RenderContext, content string) (string, error) { + return postProcessString(ctx, []processor{ + descriptionLinkProcessor, + emojiShortCodeProcessor, + emojiProcessor, + }, content) +} + +// PostProcessEmoji for when we want to just process emoji and shortcodes +// in various places it isn't already run through the normal markdown processor +func PostProcessEmoji(ctx *RenderContext, content string) (string, error) { + return postProcessString(ctx, emojiProcessors, content) +} + func postProcessString(ctx *RenderContext, procs []processor, content string) (string, error) { var buf strings.Builder if err := postProcess(ctx, procs, strings.NewReader(content), &buf); err != nil { @@ -228,23 +246,10 @@ func postProcessString(ctx *RenderContext, procs []processor, content string) (s return buf.String(), nil } -// RenderDescriptionHTML will use similar logic as PostProcess, but will -// use a single special linkProcessor. -func RenderDescriptionHTML(ctx *RenderContext, content string) (string, error) { - return postProcessString(ctx, []processor{ - descriptionLinkProcessor, - emojiShortCodeProcessor, - emojiProcessor, - }, content) -} - -// RenderEmoji for when we want to just process emoji and shortcodes -// in various places it isn't already run through the normal markdown processor -func RenderEmoji(ctx *RenderContext, content string) (string, error) { - return postProcessString(ctx, emojiProcessors, content) -} - func postProcess(ctx *RenderContext, procs []processor, input io.Reader, output io.Writer) error { + if !ctx.usedByRender && ctx.RenderHelper != nil { + defer ctx.RenderHelper.CleanUp() + } // FIXME: don't read all content to memory rawHTML, err := io.ReadAll(input) if err != nil { diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 651e674108c..9419350e615 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -252,7 +252,7 @@ func TestRender_IssueIndexPattern_NoShortPattern(t *testing.T) { testRenderIssueIndexPattern(t, "!1", "!1", NewTestRenderContext(metas)) } -func TestRender_RenderIssueTitle(t *testing.T) { +func TestRender_PostProcessIssueTitle(t *testing.T) { setting.AppURL = TestAppURL metas := map[string]string{ "format": "https://someurl.com/{user}/{repo}/{index}", @@ -260,7 +260,7 @@ func TestRender_RenderIssueTitle(t *testing.T) { "repo": "someRepo", "style": IssueNameStyleNumeric, } - actual, err := RenderIssueTitle(NewTestRenderContext(metas), "#1") + actual, err := PostProcessIssueTitle(NewTestRenderContext(metas), "#1") assert.NoError(t, err) assert.Equal(t, "#1", actual) } diff --git a/modules/markup/render.go b/modules/markup/render.go index 3b112b1a142..b239e59687b 100644 --- a/modules/markup/render.go +++ b/modules/markup/render.go @@ -57,6 +57,9 @@ type RenderOptions struct { type RenderContext struct { ctx context.Context + // the context might be used by the "render" function, but it might also be used by "postProcess" function + usedByRender bool + SidebarTocNode ast.Node RenderHelper RenderHelper @@ -182,6 +185,7 @@ func pipes() (io.ReadCloser, io.WriteCloser, func()) { } func render(ctx *RenderContext, renderer Renderer, input io.Reader, output io.Writer) error { + ctx.usedByRender = true if ctx.RenderHelper != nil { defer ctx.RenderHelper.CleanUp() } diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index 3237de5ecb1..1800747f48d 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -38,9 +38,9 @@ func (ut *RenderUtils) RenderCommitMessage(msg string, metas map[string]string) cleanMsg := template.HTMLEscapeString(msg) // we can safely assume that it will not return any error, since there // shouldn't be any special HTML. - fullMessage, err := markup.RenderCommitMessage(markup.NewRenderContext(ut.ctx).WithMetas(metas), cleanMsg) + fullMessage, err := markup.PostProcessCommitMessage(markup.NewRenderContext(ut.ctx).WithMetas(metas), cleanMsg) if err != nil { - log.Error("RenderCommitMessage: %v", err) + log.Error("PostProcessCommitMessage: %v", err) return "" } msgLines := strings.Split(strings.TrimSpace(fullMessage), "\n") @@ -65,9 +65,9 @@ func (ut *RenderUtils) RenderCommitMessageLinkSubject(msg, urlDefault string, me // we can safely assume that it will not return any error, since there // shouldn't be any special HTML. - renderedMessage, err := markup.RenderCommitMessageSubject(markup.NewRenderContext(ut.ctx).WithMetas(metas), urlDefault, template.HTMLEscapeString(msgLine)) + renderedMessage, err := markup.PostProcessCommitMessageSubject(markup.NewRenderContext(ut.ctx).WithMetas(metas), urlDefault, template.HTMLEscapeString(msgLine)) if err != nil { - log.Error("RenderCommitMessageSubject: %v", err) + log.Error("PostProcessCommitMessageSubject: %v", err) return "" } return renderCodeBlock(template.HTML(renderedMessage)) @@ -87,9 +87,9 @@ func (ut *RenderUtils) RenderCommitBody(msg string, metas map[string]string) tem return "" } - renderedMessage, err := markup.RenderCommitMessage(markup.NewRenderContext(ut.ctx).WithMetas(metas), template.HTMLEscapeString(msgLine)) + renderedMessage, err := markup.PostProcessCommitMessage(markup.NewRenderContext(ut.ctx).WithMetas(metas), template.HTMLEscapeString(msgLine)) if err != nil { - log.Error("RenderCommitMessage: %v", err) + log.Error("PostProcessCommitMessage: %v", err) return "" } return template.HTML(renderedMessage) @@ -106,12 +106,19 @@ func renderCodeBlock(htmlEscapedTextToRender template.HTML) template.HTML { // RenderIssueTitle renders issue/pull title with defined post processors func (ut *RenderUtils) RenderIssueTitle(text string, metas map[string]string) template.HTML { - renderedText, err := markup.RenderIssueTitle(markup.NewRenderContext(ut.ctx).WithMetas(metas), template.HTMLEscapeString(text)) + renderedText, err := markup.PostProcessIssueTitle(markup.NewRenderContext(ut.ctx).WithMetas(metas), template.HTMLEscapeString(text)) if err != nil { - log.Error("RenderIssueTitle: %v", err) + log.Error("PostProcessIssueTitle: %v", err) return "" } - return template.HTML(renderedText) + return renderCodeBlock(template.HTML(renderedText)) +} + +// RenderIssueSimpleTitle only renders with emoji and inline code block +func (ut *RenderUtils) RenderIssueSimpleTitle(text string) template.HTML { + ret := ut.RenderEmoji(text) + ret = renderCodeBlock(ret) + return ret } // RenderLabel renders a label @@ -174,7 +181,7 @@ func (ut *RenderUtils) RenderLabel(label *issues_model.Label) template.HTML { // RenderEmoji renders html text with emoji post processors func (ut *RenderUtils) RenderEmoji(text string) template.HTML { - renderedText, err := markup.RenderEmoji(markup.NewRenderContext(ut.ctx), template.HTMLEscapeString(text)) + renderedText, err := markup.PostProcessEmoji(markup.NewRenderContext(ut.ctx), template.HTMLEscapeString(text)) if err != nil { log.Error("RenderEmoji: %v", err) return "" diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go index c0241c0a8c5..80094ab26ea 100644 --- a/modules/templates/util_render_test.go +++ b/modules/templates/util_render_test.go @@ -164,11 +164,11 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit ๐Ÿ‘ mail@domain.com @mention-user test -#123 +#123 space ` expected = strings.ReplaceAll(expected, "", " ") - assert.EqualValues(t, expected, string(newTestRenderUtils().RenderIssueTitle(testInput(), nil))) + assert.EqualValues(t, expected, string(newTestRenderUtils().RenderIssueTitle(testInput(), testMetas))) } func TestRenderMarkdownToHtml(t *testing.T) { diff --git a/modules/web/route.go b/modules/web/route.go index 77c411a97b9..787521dfb07 100644 --- a/modules/web/route.go +++ b/modules/web/route.go @@ -9,6 +9,7 @@ import ( "reflect" "strings" + "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/web/middleware" @@ -214,7 +215,9 @@ func (r *Router) normalizeRequestPath(resp http.ResponseWriter, req *http.Reques normalizedPath = "/" } else if !strings.HasPrefix(normalizedPath+"/", "/v2/") { // do not respond to other requests, to simulate a real sub-path environment - http.Error(resp, "404 page not found, sub-path is: "+setting.AppSubURL, http.StatusNotFound) + resp.Header().Add("Content-Type", "text/html; charset=utf-8") + resp.WriteHeader(http.StatusNotFound) + _, _ = resp.Write([]byte(htmlutil.HTMLFormat(`404 page not found, sub-path is: %s`, setting.AppSubURL, setting.AppSubURL))) return } normalized = true diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 1dc0c3cb81d..57d2d89c5ac 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1032,6 +1032,8 @@ fork_to_different_account = Fork to a different account fork_visibility_helper = The visibility of a forked repository cannot be changed. fork_branch = Branch to be cloned to the fork all_branches = All branches +view_all_branches = View all branches +view_all_tags = View all tags fork_no_valid_owners = This repository can not be forked because there are no valid owners. fork.blocked_user = Cannot fork the repository because you are blocked by the repository owner. use_template = Use this template @@ -2588,7 +2590,6 @@ diff.generated = generated diff.vendored = vendored diff.comment.add_line_comment = Add line comment diff.comment.placeholder = Leave a comment -diff.comment.markdown_info = Styling with markdown is supported. diff.comment.add_single_comment = Add single comment diff.comment.add_review_comment = Add comment diff.comment.start_review = Start review diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index d17e4875b13..c3da5a7513b 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -610,40 +610,46 @@ func CommonRoutes() *web.Router { }, reqPackageAccess(perm.AccessModeWrite)) }, reqPackageAccess(perm.AccessModeRead)) r.Group("/swift", func() { - r.Group("/{scope}/{name}", func() { - r.Group("", func() { - r.Get("", swift.EnumeratePackageVersions) - r.Get(".json", swift.EnumeratePackageVersions) - }, swift.CheckAcceptMediaType(swift.AcceptJSON)) - r.Group("/{version}", func() { - r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest) - r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile) - r.Get("", func(ctx *context.Context) { - // Can't use normal routes here: https://github.com/go-chi/chi/issues/781 + r.Group("", func() { // Needs to be unauthenticated. + r.Post("", swift.CheckAuthenticate) + r.Post("/login", swift.CheckAuthenticate) + }) + r.Group("", func() { + r.Group("/{scope}/{name}", func() { + r.Group("", func() { + r.Get("", swift.EnumeratePackageVersions) + r.Get(".json", swift.EnumeratePackageVersions) + }, swift.CheckAcceptMediaType(swift.AcceptJSON)) + r.Group("/{version}", func() { + r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest) + r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile) + r.Get("", func(ctx *context.Context) { + // Can't use normal routes here: https://github.com/go-chi/chi/issues/781 - version := ctx.PathParam("version") - if strings.HasSuffix(version, ".zip") { - swift.CheckAcceptMediaType(swift.AcceptZip)(ctx) - if ctx.Written() { - return + version := ctx.PathParam("version") + if strings.HasSuffix(version, ".zip") { + swift.CheckAcceptMediaType(swift.AcceptZip)(ctx) + if ctx.Written() { + return + } + ctx.SetPathParam("version", version[:len(version)-4]) + swift.DownloadPackageFile(ctx) + } else { + swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx) + if ctx.Written() { + return + } + if strings.HasSuffix(version, ".json") { + ctx.SetPathParam("version", version[:len(version)-5]) + } + swift.PackageVersionMetadata(ctx) } - ctx.SetPathParam("version", version[:len(version)-4]) - swift.DownloadPackageFile(ctx) - } else { - swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx) - if ctx.Written() { - return - } - if strings.HasSuffix(version, ".json") { - ctx.SetPathParam("version", version[:len(version)-5]) - } - swift.PackageVersionMetadata(ctx) - } + }) }) }) - }) - r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers) - }, reqPackageAccess(perm.AccessModeRead)) + r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers) + }, reqPackageAccess(perm.AccessModeRead)) + }) r.Group("/vagrant", func() { r.Group("/authenticate", func() { r.Get("", vagrant.CheckAuthenticate) diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go index d5d4d4e9d13..4d7fb8b1a69 100644 --- a/routers/api/packages/swift/swift.go +++ b/routers/api/packages/swift/swift.go @@ -27,7 +27,7 @@ import ( "github.com/hashicorp/go-version" ) -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning const ( AcceptJSON = "application/vnd.swift.registry.v1+json" AcceptSwift = "application/vnd.swift.registry.v1+swift" @@ -35,9 +35,9 @@ const ( ) var ( - // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#361-package-scope + // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#361-package-scope scopePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-]{0,38}\z`) - // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#362-package-name + // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#362-package-name namePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-_]{0,99}\z`) ) @@ -49,7 +49,7 @@ type headers struct { Link string } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func setResponseHeaders(resp http.ResponseWriter, h *headers) { if h.ContentType != "" { resp.Header().Set("Content-Type", h.ContentType) @@ -69,7 +69,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) { } } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#33-error-handling +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling func apiError(ctx *context.Context, status int, obj any) { // https://www.rfc-editor.org/rfc/rfc7807 type Problem struct { @@ -91,7 +91,7 @@ func apiError(ctx *context.Context, status int, obj any) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) { return func(ctx *context.Context) { accept := ctx.Req.Header.Get("Accept") @@ -101,6 +101,16 @@ func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context } } +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/PackageRegistryUsage.md#registry-authentication +func CheckAuthenticate(ctx *context.Context) { + if ctx.Doer == nil { + apiError(ctx, http.StatusUnauthorized, nil) + return + } + + ctx.Status(http.StatusOK) +} + func buildPackageID(scope, name string) string { return scope + "." + name } @@ -113,7 +123,7 @@ type EnumeratePackageVersionsResponse struct { Releases map[string]Release `json:"releases"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#41-list-package-releases +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases func EnumeratePackageVersions(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -170,7 +180,7 @@ type PackageVersionMetadataResponse struct { Metadata *swift_module.SoftwareSourceCode `json:"metadata"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-2 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2 func PackageVersionMetadata(ctx *context.Context) { id := buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")) @@ -228,7 +238,7 @@ func PackageVersionMetadata(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#43-fetch-manifest-for-a-package-release +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release func DownloadManifest(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -280,7 +290,7 @@ func DownloadManifest(ctx *context.Context) { }) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-6 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6 func UploadPackageFile(ctx *context.Context) { packageScope := ctx.PathParam("scope") packageName := ctx.PathParam("name") @@ -379,7 +389,7 @@ func UploadPackageFile(ctx *context.Context) { ctx.Status(http.StatusCreated) } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-4 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4 func DownloadPackageFile(ctx *context.Context) { pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.PathParam("scope"), ctx.PathParam("name")), ctx.PathParam("version")) if err != nil { @@ -420,7 +430,7 @@ type LookupPackageIdentifiersResponse struct { Identifiers []string `json:"identifiers"` } -// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-5 +// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5 func LookupPackageIdentifiers(ctx *context.Context) { url := ctx.FormTrim("url") if url == "" { diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 45c5c1cd145..53f3b4648a5 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -150,11 +150,6 @@ func DeleteBranch(ctx *context.APIContext) { } } - if ctx.Repo.Repository.IsMirror { - ctx.Error(http.StatusForbidden, "IsMirrored", fmt.Errorf("can not delete branch of an mirror repository")) - return - } - if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil { switch { case git.IsErrBranchNotExist(err): diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 28d7379f07b..1116a4e9b1d 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1057,49 +1057,54 @@ func MergePullRequest(ctx *context.APIContext) { } log.Trace("Pull request merged: %d", pr.ID) - if form.DeleteBranchAfterMerge { - // Don't cleanup when there are other PR's that use this branch as head branch. - exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) - if err != nil { - ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) - return - } - if exist { - ctx.Status(http.StatusOK) - return - } - - var headRepo *git.Repository - if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil { - headRepo = ctx.Repo.GitRepo - } else { - headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) + // for agit flow, we should not delete the agit reference after merge + if form.DeleteBranchAfterMerge && pr.Flow == issues_model.PullRequestFlowGithub { + // check permission even it has been checked in repo_service.DeleteBranch so that we don't need to + // do RetargetChildrenOnMerge + if err := repo_service.CanDeleteBranch(ctx, pr.HeadRepo, pr.HeadBranch, ctx.Doer); err == nil { + // Don't cleanup when there are other PR's that use this branch as head branch. + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) if err != nil { - ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err) + ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) return } - defer headRepo.Close() - } - if err := pull_service.RetargetChildrenOnMerge(ctx, ctx.Doer, pr); err != nil { - ctx.Error(http.StatusInternalServerError, "RetargetChildrenOnMerge", err) - return - } - if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch); err != nil { - switch { - case git.IsErrBranchNotExist(err): - ctx.NotFound(err) - case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch")) - case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected")) - default: - ctx.Error(http.StatusInternalServerError, "DeleteBranch", err) + if exist { + ctx.Status(http.StatusOK) + return + } + + var headRepo *git.Repository + if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil { + headRepo = ctx.Repo.GitRepo + } else { + headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) + if err != nil { + ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err) + return + } + defer headRepo.Close() + } + if err := pull_service.RetargetChildrenOnMerge(ctx, ctx.Doer, pr); err != nil { + ctx.Error(http.StatusInternalServerError, "RetargetChildrenOnMerge", err) + return + } + if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch); err != nil { + switch { + case git.IsErrBranchNotExist(err): + ctx.NotFound(err) + case errors.Is(err, repo_service.ErrBranchIsDefault): + ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch")) + case errors.Is(err, git_model.ErrBranchIsProtected): + ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected")) + default: + ctx.Error(http.StatusInternalServerError, "DeleteBranch", err) + } + return + } + if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { + // Do not fail here as branch has already been deleted + log.Error("DeleteBranch: %v", err) } - return - } - if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil { - // Do not fail here as branch has already been deleted - log.Error("DeleteBranch: %v", err) } } diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index 0be9689c3f5..c5652784fa0 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -394,9 +394,9 @@ func Diff(ctx *context.Context) { ctx.Data["NoteCommit"] = note.Commit ctx.Data["NoteAuthor"] = user_model.ValidateCommitWithEmail(ctx, note.Commit) rctx := renderhelper.NewRenderContextRepoComment(ctx, ctx.Repo.Repository, renderhelper.RepoCommentOptions{CurrentRefPath: path.Join("commit", util.PathEscapeSegments(commitID))}) - ctx.Data["NoteRendered"], err = markup.RenderCommitMessage(rctx, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message, charset.ConvertOpts{})))) + ctx.Data["NoteRendered"], err = markup.PostProcessCommitMessage(rctx, template.HTMLEscapeString(string(charset.ToUTF8WithFallback(note.Message, charset.ConvertOpts{})))) if err != nil { - ctx.ServerError("RenderCommitMessage", err) + ctx.ServerError("PostProcessCommitMessage", err) return } } diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 60592305330..6c8215aac53 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -1186,32 +1186,34 @@ func MergePullRequest(ctx *context.Context) { log.Trace("Pull request merged: %d", pr.ID) - if form.DeleteBranchAfterMerge { - // Don't cleanup when other pr use this branch as head branch - exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) - if err != nil { - ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) - return - } - if exist { - ctx.JSONRedirect(issue.Link()) - return - } - - var headRepo *git.Repository - if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil { - headRepo = ctx.Repo.GitRepo - } else { - headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) - if err != nil { - ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err) - return - } - defer headRepo.Close() - } - deleteBranch(ctx, pr, headRepo) + if !form.DeleteBranchAfterMerge { + ctx.JSONRedirect(issue.Link()) + return } + // Don't cleanup when other pr use this branch as head branch + exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch) + if err != nil { + ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err) + return + } + if exist { + ctx.JSONRedirect(issue.Link()) + return + } + + var headRepo *git.Repository + if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil { + headRepo = ctx.Repo.GitRepo + } else { + headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) + if err != nil { + ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err) + return + } + defer headRepo.Close() + } + deleteBranch(ctx, pr, headRepo) ctx.JSONRedirect(issue.Link()) } @@ -1404,8 +1406,8 @@ func CleanUpPullRequest(ctx *context.Context) { pr := issue.PullRequest - // Don't cleanup unmerged and unclosed PRs - if !pr.HasMerged && !issue.IsClosed { + // Don't cleanup unmerged and unclosed PRs and agit PRs + if !pr.HasMerged && !issue.IsClosed && pr.Flow != issues_model.PullRequestFlowGithub { ctx.NotFound("CleanUpPullRequest", nil) return } @@ -1436,13 +1438,12 @@ func CleanUpPullRequest(ctx *context.Context) { return } - perm, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, ctx.Doer) - if err != nil { - ctx.ServerError("GetUserRepoPermission", err) - return - } - if !perm.CanWrite(unit.TypeCode) { - ctx.NotFound("CleanUpPullRequest", nil) + if err := repo_service.CanDeleteBranch(ctx, pr.HeadRepo, pr.HeadBranch, ctx.Doer); err != nil { + if errors.Is(err, util.ErrPermissionDenied) { + ctx.NotFound("CanDeleteBranch", nil) + } else { + ctx.ServerError("CanDeleteBranch", err) + } return } diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go index 96c512dd3df..c178ba24916 100644 --- a/routers/web/repo/release.go +++ b/routers/web/repo/release.go @@ -31,6 +31,7 @@ import ( "code.gitea.io/gitea/services/context/upload" "code.gitea.io/gitea/services/forms" releaseservice "code.gitea.io/gitea/services/release" + repo_service "code.gitea.io/gitea/services/repository" ) const ( @@ -193,6 +194,8 @@ func Releases(ctx *context.Context) { pager.SetDefaultParams(ctx) ctx.Data["Page"] = pager + ctx.Data["LicenseFileName"] = repo_service.LicenseFileName + ctx.HTML(http.StatusOK, tplReleasesList) } @@ -251,6 +254,7 @@ func TagsList(ctx *context.Context) { pager.SetDefaultParams(ctx) ctx.Data["Page"] = pager ctx.Data["PageIsViewCode"] = !ctx.Repo.Repository.UnitEnabled(ctx, unit.TypeReleases) + ctx.Data["LicenseFileName"] = repo_service.LicenseFileName ctx.HTML(http.StatusOK, tplTagsList) } diff --git a/routers/web/web.go b/routers/web/web.go index 2ba85b0e59e..ee3c12a3c50 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -485,6 +485,8 @@ func registerRoutes(m *web.Router) { m.Methods("GET, HEAD", "/*", public.FileHandlerFunc()) }, optionsCorsHandler()) + m.Post("/-/markup", reqSignIn, web.Bind(structs.MarkupOption{}), misc.Markup) + m.Group("/explore", func() { m.Get("", func(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/explore/repos") diff --git a/services/repository/branch.go b/services/repository/branch.go index 600ba96e92e..508817c83e6 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -14,7 +14,9 @@ import ( "code.gitea.io/gitea/models/db" git_model "code.gitea.io/gitea/models/git" issues_model "code.gitea.io/gitea/models/issues" + access_model "code.gitea.io/gitea/models/perm/access" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/git" @@ -463,15 +465,17 @@ var ( ErrBranchIsDefault = errors.New("branch is default") ) -// DeleteBranch delete branch -func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string) error { - err := repo.MustNotBeArchived() +func CanDeleteBranch(ctx context.Context, repo *repo_model.Repository, branchName string, doer *user_model.User) error { + if branchName == repo.DefaultBranch { + return ErrBranchIsDefault + } + + perm, err := access_model.GetUserRepoPermission(ctx, repo, doer) if err != nil { return err } - - if branchName == repo.DefaultBranch { - return ErrBranchIsDefault + if !perm.CanWrite(unit.TypeCode) { + return util.NewPermissionDeniedErrorf("permission denied to access repo %d unit %s", repo.ID, unit.TypeCode.LogString()) } isProtected, err := git_model.IsBranchProtected(ctx, repo.ID, branchName) @@ -481,6 +485,19 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R if isProtected { return git_model.ErrBranchIsProtected } + return nil +} + +// DeleteBranch delete branch +func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string) error { + err := repo.MustNotBeArchived() + if err != nil { + return err + } + + if err := CanDeleteBranch(ctx, repo, branchName, doer); err != nil { + return err + } rawBranch, err := git_model.GetBranch(ctx, repo.ID, branchName) if err != nil && !git_model.IsErrBranchNotExist(err) { diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl index b6c26c85274..7e4c8854f5f 100644 --- a/templates/admin/user/list.tmpl +++ b/templates/admin/user/list.tmpl @@ -7,10 +7,12 @@
-
- + +
+ {{template "shared/search/combo" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.user_kind")}} +
- - - {{template "shared/search/combo" dict "Value" .Keyword "Placeholder" (ctx.Locale.Tr "search.user_kind")}}
diff --git a/templates/devtest/devtest-footer.tmpl b/templates/devtest/devtest-footer.tmpl index 1c755508a5e..a1b3b86e5c4 100644 --- a/templates/devtest/devtest-footer.tmpl +++ b/templates/devtest/devtest-footer.tmpl @@ -1,3 +1,3 @@ {{/* TODO: the devtest.js is isolated from index.js, so no module is shared and many index.js functions do not work in devtest.ts */}} -{{template "base/footer" dict}} +{{template "base/footer" ctx.RootData}} diff --git a/templates/devtest/devtest-header.tmpl b/templates/devtest/devtest-header.tmpl index a5910b96e6f..ee085456406 100644 --- a/templates/devtest/devtest-header.tmpl +++ b/templates/devtest/devtest-header.tmpl @@ -1,2 +1,2 @@ -{{template "base/head" dict}} +{{template "base/head" ctx.RootData}} diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl index 303421fe134..5b40268761d 100644 --- a/templates/devtest/gitea-ui.tmpl +++ b/templates/devtest/gitea-ui.tmpl @@ -183,8 +183,7 @@

ComboMarkdownEditor

-
ps: no JS code attached, so just a layout
- {{template "shared/combomarkdowneditor" .}} + {{template "shared/combomarkdowneditor" dict "MarkdownPreviewContext" "/owner/path"}}

Tailwind CSS Demo

diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl index 62debfc0aef..3b817d068b5 100644 --- a/templates/org/settings/options.tmpl +++ b/templates/org/settings/options.tmpl @@ -23,6 +23,7 @@
+ {{/* it is rendered as markdown, but the length is limited, so at the moment we do not use the markdown editor here */}}
diff --git a/templates/projects/new.tmpl b/templates/projects/new.tmpl index bd173b54bce..a936079c466 100644 --- a/templates/projects/new.tmpl +++ b/templates/projects/new.tmpl @@ -18,7 +18,16 @@
- + {{/* TODO: repo-level project and org-level project have different behaviros to render */}} + {{/* the "Repository" is nil when the project is org-level */}} + {{template "shared/combomarkdowneditor" (dict + "MarkdownPreviewInRepo" $.Repository + "MarkdownPreviewContext" (Iif $.Repository "" .HomeLink) + "MarkdownPreviewMode" (Iif $.Repository "comment") + "TextareaName" "content" + "TextareaContent" .content + "TextareaPlaceholder" (ctx.Locale.Tr "repo.projects.description_placeholder") + )}}
{{if not .PageIsEditProjects}} diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index 43568732fbb..b68c34a02af 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -10,6 +10,7 @@ * ShowTabBranches * ShowTabTagsTab * AllowCreateNewRef +* ShowViewAllRefsEntry Search "repo/branch_dropdown" in the template directory to find all occurrences. */}} @@ -24,6 +25,8 @@ Search "repo/branch_dropdown" in the template directory to find all occurrences. data-text-create-branch="{{ctx.Locale.Tr "repo.branch.create_branch"}}" data-text-create-ref-from="{{ctx.Locale.Tr "repo.branch.create_from"}}" data-text-no-results="{{ctx.Locale.Tr "no_results_found"}}" + data-text-view-all-branches="{{ctx.Locale.Tr "repo.view_all_branches"}}" + data-text-view-all-tags="{{ctx.Locale.Tr "repo.view_all_tags"}}" data-current-repo-default-branch="{{.Repository.DefaultBranch}}" data-current-repo-link="{{.Repository.Link}}" @@ -37,6 +40,7 @@ Search "repo/branch_dropdown" in the template directory to find all occurrences. data-show-tab-branches="{{.ShowTabBranches}}" data-show-tab-tags="{{.ShowTabTags}}" data-allow-create-new-ref="{{.AllowCreateNewRef}}" + data-show-view-all-refs-entry="{{.ShowViewAllRefsEntry}}" data-enable-feed="{{ctx.RootData.EnableFeed}}" > diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl index 20e0c9db668..0f1458bfbfd 100644 --- a/templates/repo/diff/box.tmpl +++ b/templates/repo/diff/box.tmpl @@ -240,8 +240,9 @@