diff options
Diffstat (limited to 'models/issue_comment.go')
-rw-r--r-- | models/issue_comment.go | 148 |
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 +} |