summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
author赵智超 <1012112796@qq.com>2020-05-20 20:47:24 +0800
committerGitHub <noreply@github.com>2020-05-20 09:47:24 -0300
commit0903b1ac8c7b64bb571d02cdd69fa671cc1c18c1 (patch)
treeeaa680114a5a0d736ff7b71baf526fe2bb1f2966 /models
parent9e0e2a9fcfae4336958dc3e93d4beacfc7a2f642 (diff)
downloadgitea-0903b1ac8c7b64bb571d02cdd69fa671cc1c18c1.tar.gz
gitea-0903b1ac8c7b64bb571d02cdd69fa671cc1c18c1.zip
Add push commits history comment on PR time-line (#11167)
* Add push commits history comment on PR time-line * Add notify by email and ui of this comment type also Signed-off-by: a1012112796 <1012112796@qq.com> * Add migrations for IsForcePush * fix wrong force-push judgement * Apply suggestions from code review * Remove commit number check * add own notify fun * fix some typo Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> * fix lint * fix style again, I forgot something before * Change email notify way * fix api * add number check if It's force-push * Add repo commit link fuction remove unnecessary check skip show push commits comment which not have commits alive * Update issue_comment.go * Apply suggestions from code review Co-authored-by: mrsdizzie <info@mrsdizzie.com> * Apply suggestions from code review * fix ui view Co-authored-by: silverwind <me@silverwind.io> * fix height * remove unnecessary style define * simplify GetBranchName * Apply suggestions from code review * save commit ids and isForce push by json * simplify GetBranchName * fix bug Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com> Co-authored-by: mrsdizzie <info@mrsdizzie.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: silverwind <me@silverwind.io>
Diffstat (limited to 'models')
-rw-r--r--models/issue_comment.go148
-rw-r--r--models/repo.go11
2 files changed, 159 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
+}
diff --git a/models/repo.go b/models/repo.go
index f79740e747..c45abdf63d 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -264,6 +264,17 @@ func (repo *Repository) HTMLURL() string {
return setting.AppURL + repo.FullName()
}
+// CommitLink make link to by commit full ID
+// note: won't check whether it's an right id
+func (repo *Repository) CommitLink(commitID string) (result string) {
+ if commitID == "" || commitID == "0000000000000000000000000000000000000000" {
+ result = ""
+ } else {
+ result = repo.HTMLURL() + "/commit/" + commitID
+ }
+ return
+}
+
// APIURL returns the repository API URL
func (repo *Repository) APIURL() string {
return setting.AppURL + path.Join("api/v1/repos", repo.FullName())