diff options
author | 赵智超 <1012112796@qq.com> | 2020-05-20 20:47:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-05-20 09:47:24 -0300 |
commit | 0903b1ac8c7b64bb571d02cdd69fa671cc1c18c1 (patch) | |
tree | eaa680114a5a0d736ff7b71baf526fe2bb1f2966 /models | |
parent | 9e0e2a9fcfae4336958dc3e93d4beacfc7a2f642 (diff) | |
download | gitea-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.go | 148 | ||||
-rw-r--r-- | models/repo.go | 11 |
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()) |