Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,6 @@ prime/
/.goosehints
/.windsurfrules
/.github/copilot-instructions.md
/AGENT.md
/CLAUDE.md
/llms.txt

# Ignore worktrees when working on multiple branches
Expand Down
2 changes: 0 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
# Instructions for agents

- Use `make help` to find available development targets
- Use the latest Golang stable release when working on Go code
- Use the latest Node.js LTS release when working on TypeScript code
- Before committing `.go` changes, run `make fmt` to format, and run `make lint-go` to lint
- Before committing `.ts` changes, run `make lint-js` to lint
- Before committing `go.mod` changes, run `make tidy`
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@AGENTS.md
12 changes: 9 additions & 3 deletions models/issues/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,12 +658,18 @@ func (pr *PullRequest) IsWorkInProgress(ctx context.Context) bool {

// HasWorkInProgressPrefix determines if the given PR title has a Work In Progress prefix
func HasWorkInProgressPrefix(title string) bool {
_, ok := CutWorkInProgressPrefix(title)
return ok
}

func CutWorkInProgressPrefix(title string) (origTitle string, ok bool) {
for _, prefix := range setting.Repository.PullRequest.WorkInProgressPrefixes {
if strings.HasPrefix(strings.ToUpper(title), strings.ToUpper(prefix)) {
return true
prefixLen := len(prefix)
if prefixLen <= len(title) && util.AsciiEqualFold(title[:prefixLen], prefix) {
return title[len(prefix):], true
}
}
return false
return title, false
}

// IsFilesConflicted determines if the Pull Request has changes conflicting with the target branch.
Expand Down
48 changes: 48 additions & 0 deletions modules/templates/util_render_comment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package templates

import (
"html/template"
"strings"

issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/htmlutil"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/svg"
"code.gitea.io/gitea/modules/translation"
"code.gitea.io/gitea/modules/util"
)

func commentTimelineEventIsWipToggle(c *issues_model.Comment) (isToggle, isWip bool) {
title1, ok1 := issues_model.CutWorkInProgressPrefix(c.OldTitle)
title2, ok2 := issues_model.CutWorkInProgressPrefix(c.NewTitle)
return ok1 != ok2 && strings.TrimSpace(title1) == strings.TrimSpace(title2), ok2
}

func (ut *RenderUtils) RenderTimelineEventBadge(c *issues_model.Comment) template.HTML {
if c.Type == issues_model.CommentTypeChangeTitle {
isToggle, isWip := commentTimelineEventIsWipToggle(c)
if !isToggle {
return svg.RenderHTML("octicon-pencil")
}
return util.Iif(isWip, svg.RenderHTML("octicon-git-pull-request-draft"), svg.RenderHTML("octicon-eye"))
}
setting.PanicInDevOrTesting("unimplemented comment type %v: %v", c.Type, c)
return htmlutil.HTMLFormat("(CommentType:%v)", c.Type)
}

func (ut *RenderUtils) RenderTimelineEventComment(c *issues_model.Comment, createdStr template.HTML) template.HTML {
if c.Type == issues_model.CommentTypeChangeTitle {
locale := ut.ctx.Value(translation.ContextKey).(translation.Locale)
isToggle, isWip := commentTimelineEventIsWipToggle(c)
if !isToggle {
return locale.Tr("repo.issues.change_title_at", ut.RenderEmoji(c.OldTitle), ut.RenderEmoji(c.NewTitle), createdStr)
}
trKey := util.Iif(isWip, "repo.pulls.marked_as_work_in_progress", "repo.pulls.marked_as_ready_for_review")
return locale.Tr(trKey, createdStr)
}
setting.PanicInDevOrTesting("unimplemented comment type %v: %v", c.Type, c)
return htmlutil.HTMLFormat("(Comment:%v,%v)", c.Type, c.Content)
}
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1778,6 +1778,8 @@
"repo.pulls.title_desc": "wants to merge %[1]d commits from <code>%[2]s</code> into <code id=\"branch_target\">%[3]s</code>",
"repo.pulls.merged_title_desc": "merged %[1]d commits from <code>%[2]s</code> into <code>%[3]s</code> %[4]s",
"repo.pulls.change_target_branch_at": "changed target branch from <b>%s</b> to <b>%s</b> %s",
"repo.pulls.marked_as_work_in_progress": "marked the pull request as work in progress %s",
"repo.pulls.marked_as_ready_for_review": "marked the pull request as ready for review %s",
"repo.pulls.tab_conversation": "Conversation",
"repo.pulls.tab_commits": "Commits",
"repo.pulls.tab_files": "Files Changed",
Expand Down
61 changes: 33 additions & 28 deletions routers/web/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,35 @@ func (d *pullCommitStatusCheckData) CommitStatusCheckPrompt(locale translation.L
return locale.TrString("repo.pulls.status_checking")
}

func getViewPullHeadRepoInfo(ctx *context.Context, pull *issues_model.PullRequest, baseGitRepo *git.Repository) (headCommitID string, headCommitExists bool, err error) {
if pull.HeadRepo == nil {
return "", false, nil
}
headGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pull.HeadRepo)
if err != nil {
return "", false, util.Iif(errors.Is(err, util.ErrNotExist), nil, err)
}
defer closer.Close()

if pull.Flow == issues_model.PullRequestFlowGithub {
headCommitExists, _ = git_model.IsBranchExist(ctx, pull.HeadRepo.ID, pull.HeadBranch)
} else {
headCommitExists = gitrepo.IsReferenceExist(ctx, pull.BaseRepo, pull.GetGitHeadRefName())
}

if headCommitExists {
if pull.Flow != issues_model.PullRequestFlowGithub {
headCommitID, err = baseGitRepo.GetRefCommitID(pull.GetGitHeadRefName())
} else {
headCommitID, err = headGitRepo.GetBranchCommitID(pull.HeadBranch)
}
if err != nil {
return "", false, util.Iif(errors.Is(err, util.ErrNotExist), nil, err)
}
}
return headCommitID, headCommitExists, nil
}

// prepareViewPullInfo show meta information for a pull request preview page
func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git_service.CompareInfo {
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
Expand Down Expand Up @@ -430,34 +459,10 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git_s
return compareInfo
}

var headBranchExist bool
var headBranchSha string
// HeadRepo may be missing
if pull.HeadRepo != nil {
headGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pull.HeadRepo)
if err != nil {
ctx.ServerError("RepositoryFromContextOrOpen", err)
return nil
}
defer closer.Close()

if pull.Flow == issues_model.PullRequestFlowGithub {
headBranchExist, _ = git_model.IsBranchExist(ctx, pull.HeadRepo.ID, pull.HeadBranch)
} else {
headBranchExist = gitrepo.IsReferenceExist(ctx, pull.BaseRepo, pull.GetGitHeadRefName())
}

if headBranchExist {
if pull.Flow != issues_model.PullRequestFlowGithub {
headBranchSha, err = baseGitRepo.GetRefCommitID(pull.GetGitHeadRefName())
} else {
headBranchSha, err = headGitRepo.GetBranchCommitID(pull.HeadBranch)
}
if err != nil {
ctx.ServerError("GetBranchCommitID", err)
return nil
}
}
headBranchSha, headBranchExist, err := getViewPullHeadRepoInfo(ctx, pull, baseGitRepo)
if err != nil {
ctx.ServerError("getViewPullHeadRepoInfo", err)
return nil
}

if headBranchExist {
Expand Down
6 changes: 3 additions & 3 deletions templates/repo/issue/view_content/comments.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{template "base/alert"}}
{{range .Issue.Comments}}
{{range $comment := .Issue.Comments}}
{{if call $.ShouldShowCommentType .Type}}
{{$createdStr:= DateUtils.TimeSince .CreatedUnix}}

Expand Down Expand Up @@ -220,11 +220,11 @@
</div>
{{else if eq .Type 10}}
<div class="timeline-item event" id="{{.HashTag}}">
<span class="badge">{{svg "octicon-pencil"}}</span>
<span class="badge">{{ctx.RenderUtils.RenderTimelineEventBadge $comment}}</span>
{{template "shared/user/avatarlink" dict "user" .Poster}}
<span class="comment-text-line">
{{template "shared/user/authorlink" .Poster}}
{{ctx.Locale.Tr "repo.issues.change_title_at" (.OldTitle|ctx.RenderUtils.RenderEmoji) (.NewTitle|ctx.RenderUtils.RenderEmoji) $createdStr}}
{{ctx.RenderUtils.RenderTimelineEventComment $comment $createdStr}}
</span>
</div>
{{else if eq .Type 11}}
Expand Down
Loading