aboutsummaryrefslogtreecommitdiffstats
path: root/models/issue_comment.go
diff options
context:
space:
mode:
Diffstat (limited to 'models/issue_comment.go')
-rw-r--r--models/issue_comment.go148
1 files changed, 148 insertions, 0 deletions
diff --git a/models/issue_comment.go b/models/issue_comment.go
index f7017435d7..e23fae6715 100644
--- a/models/issue_comment.go
+++ b/models/issue_comment.go
@@ -7,6 +7,8 @@
package models
import (
+ "container/list"
+ "encoding/json"
"fmt"
"strings"
@@ -90,6 +92,8 @@ const (
CommentTypeReviewRequest
// merge pull request
CommentTypeMergePull
+ // push to PR head branch
+ CommentTypePullPush
)
// CommentTag defines comment tag type
@@ -167,6 +171,18 @@ type Comment struct {
RefRepo *Repository `xorm:"-"`
RefIssue *Issue `xorm:"-"`
RefComment *Comment `xorm:"-"`
+
+ Commits *list.List `xorm:"-"`
+ OldCommit string `xorm:"-"`
+ NewCommit string `xorm:"-"`
+ CommitsNum int64 `xorm:"-"`
+ IsForcePush bool `xorm:"-"`
+}
+
+// PushActionContent is content of push pull comment
+type PushActionContent struct {
+ IsForcePush bool `json:"is_force_push"`
+ CommitIDs []string `json:"commit_ids"`
}
// LoadIssue loads issue from database
@@ -543,6 +559,47 @@ func (c *Comment) CodeCommentURL() string {
return fmt.Sprintf("%s/files#%s", c.Issue.HTMLURL(), c.HashTag())
}
+// LoadPushCommits Load push commits
+func (c *Comment) LoadPushCommits() (err error) {
+ if c.Content == "" || c.Commits != nil || c.Type != CommentTypePullPush {
+ return nil
+ }
+
+ var data PushActionContent
+
+ err = json.Unmarshal([]byte(c.Content), &data)
+ if err != nil {
+ return
+ }
+
+ c.IsForcePush = data.IsForcePush
+
+ if c.IsForcePush {
+ if len(data.CommitIDs) != 2 {
+ return nil
+ }
+ c.OldCommit = data.CommitIDs[0]
+ c.NewCommit = data.CommitIDs[1]
+ } else {
+ repoPath := c.Issue.Repo.RepoPath()
+ gitRepo, err := git.OpenRepository(repoPath)
+ if err != nil {
+ return err
+ }
+ defer gitRepo.Close()
+
+ c.Commits = gitRepo.GetCommitsFromIDs(data.CommitIDs)
+ c.CommitsNum = int64(c.Commits.Len())
+ if c.CommitsNum > 0 {
+ c.Commits = ValidateCommitsWithEmails(c.Commits)
+ c.Commits = ParseCommitsWithSignature(c.Commits, c.Issue.Repo)
+ c.Commits = ParseCommitsWithStatus(c.Commits, c.Issue.Repo)
+ }
+ }
+
+ return err
+}
+
func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err error) {
var LabelID int64
if opts.Label != nil {
@@ -576,6 +633,7 @@ func createComment(e *xorm.Session, opts *CreateCommentOptions) (_ *Comment, err
RefCommentID: opts.RefCommentID,
RefAction: opts.RefAction,
RefIsPull: opts.RefIsPull,
+ IsForcePush: opts.IsForcePush,
}
if _, err = e.Insert(comment); err != nil {
return nil, err
@@ -738,6 +796,7 @@ type CreateCommentOptions struct {
RefCommentID int64
RefAction references.XRefAction
RefIsPull bool
+ IsForcePush bool
}
// CreateComment creates comment of issue or commit.
@@ -1016,3 +1075,92 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID
})
return err
}
+
+// CreatePushPullComment create push code to pull base commend
+func CreatePushPullComment(pusher *User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
+ if pr.HasMerged || oldCommitID == "" || newCommitID == "" {
+ return nil, nil
+ }
+
+ ops := &CreateCommentOptions{
+ Type: CommentTypePullPush,
+ Doer: pusher,
+ Repo: pr.BaseRepo,
+ }
+
+ var data PushActionContent
+
+ data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
+ if err != nil {
+ return nil, err
+ }
+
+ ops.Issue = pr.Issue
+ dataJSON, err := json.Marshal(data)
+ if err != nil {
+ return nil, err
+ }
+
+ ops.Content = string(dataJSON)
+
+ comment, err = CreateComment(ops)
+
+ return
+}
+
+// getCommitsFromRepo get commit IDs from repo in betwern oldCommitID and newCommitID
+// isForcePush will be true if oldCommit isn't on the branch
+// Commit on baseBranch will skip
+func getCommitIDsFromRepo(repo *Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
+ repoPath := repo.RepoPath()
+ gitRepo, err := git.OpenRepository(repoPath)
+ if err != nil {
+ return nil, false, err
+ }
+ defer gitRepo.Close()
+
+ oldCommit, err := gitRepo.GetCommit(oldCommitID)
+ if err != nil {
+ return nil, false, err
+ }
+
+ oldCommitBranch, err := oldCommit.GetBranchName()
+ if err != nil {
+ return nil, false, err
+ }
+
+ if oldCommitBranch == "undefined" {
+ commitIDs = make([]string, 2)
+ commitIDs[0] = oldCommitID
+ commitIDs[1] = newCommitID
+
+ return commitIDs, true, err
+ }
+
+ newCommit, err := gitRepo.GetCommit(newCommitID)
+ if err != nil {
+ return nil, false, err
+ }
+
+ var commits *list.List
+ commits, err = newCommit.CommitsBeforeUntil(oldCommitID)
+ if err != nil {
+ return nil, false, err
+ }
+
+ commitIDs = make([]string, 0, commits.Len())
+
+ for e := commits.Back(); e != nil; e = e.Prev() {
+ commit := e.Value.(*git.Commit)
+ commitBranch, err := commit.GetBranchName()
+ if err != nil {
+ return nil, false, err
+ }
+
+ if commitBranch != baseBranch {
+ commitIDs = append(commitIDs, commit.ID.String())
+ }
+ }
+
+ return
+}