Fix force push time-line commit comments of pull request (#36653)

Fix #36647 
Fix #25827
Fix #25870

---------

Signed-off-by: silverwind <me@silverwind.io>
Signed-off-by: Lunny Xiao <xiaolunwen@gmail.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
2026-02-22 13:30:31 -08:00
committed by GitHub
parent 1eced4a7c0
commit 8f15f76dd6
2 changed files with 229 additions and 22 deletions

View File

@@ -6,11 +6,13 @@ package pull
import (
"context"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
)
// getCommitIDsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
@@ -53,35 +55,67 @@ func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *iss
}
opts := &issues_model.CreateCommentOptions{
Type: issues_model.CommentTypePullRequestPush,
Doer: pusher,
Repo: pr.BaseRepo,
IsForcePush: isForcePush,
Issue: pr.Issue,
Type: issues_model.CommentTypePullRequestPush,
Doer: pusher,
Repo: pr.BaseRepo,
Issue: pr.Issue,
}
var data issues_model.PushActionContent
if opts.IsForcePush {
data.CommitIDs = []string{oldCommitID, newCommitID}
data.IsForcePush = true
} else {
data.CommitIDs, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
if err != nil {
data.CommitIDs, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
if err != nil {
// For force-push events, a missing/unreachable old commit should not prevent
// deleting stale push comments or creating the force-push timeline entry.
if !isForcePush {
return nil, err
}
// It maybe an empty pull request. Only non-empty pull request need to create push comment
if len(data.CommitIDs) == 0 {
return nil, nil //nolint:nilnil // return nil because no comment needs to be created
log.Error("getCommitIDsFromRepo: %v", err)
}
// It maybe an empty pull request. Only non-empty pull request need to create push comment
// for force push, we always need to delete the old push comment so don't return here.
if len(data.CommitIDs) == 0 && !isForcePush {
return nil, nil //nolint:nilnil // return nil because no comment needs to be created
}
return db.WithTx2(ctx, func(ctx context.Context) (*issues_model.Comment, error) {
if isForcePush {
// Push commits comment should not have history, cross references, reactions and other
// plain comment related records, so that we just need to delete the comment itself.
if _, err := db.GetEngine(ctx).Where("issue_id = ?", pr.IssueID).
And("type = ?", issues_model.CommentTypePullRequestPush).
NoAutoCondition().
Delete(new(issues_model.Comment)); err != nil {
return nil, err
}
}
}
dataJSON, err := json.Marshal(data)
if err != nil {
return nil, err
}
if len(data.CommitIDs) > 0 {
dataJSON, err := json.Marshal(data)
if err != nil {
return nil, err
}
opts.Content = string(dataJSON)
comment, err = issues_model.CreateComment(ctx, opts)
if err != nil {
return nil, err
}
}
opts.Content = string(dataJSON)
comment, err = issues_model.CreateComment(ctx, opts)
if isForcePush { // if it's a force push, we need to add a force push comment
data.CommitIDs = []string{oldCommitID, newCommitID}
data.IsForcePush = true
dataJSON, err := json.Marshal(data)
if err != nil {
return nil, err
}
opts.Content = string(dataJSON)
opts.IsForcePush = true // FIXME: it seems the field is unnecessary any more because PushActionContent includes IsForcePush field
comment, err = issues_model.CreateComment(ctx, opts)
if err != nil {
return nil, err
}
}
return comment, err
return comment, err
})
}