From ae20de7771d81d76ff62227e464a699d55c62084 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E6=99=BA=E8=B6=85?= <1012112796@qq.com> Date: Thu, 25 Jun 2020 03:40:52 +0800 Subject: [PATCH] fix bug about can't skip commits base on base branch (#11555) * fix bug about can't skip commits base on base branch Signed-off-by: a1012112796 <1012112796@qq.com> * Update modules/git/commit.go Co-authored-by: Lauris BH * Update models/issue_comment.go Co-authored-by: Lauris BH * fix lint Co-authored-by: Lauris BH --- models/issue_comment.go | 100 +++++++++++++++++++++++++++++++++++----- modules/git/commit.go | 10 ++++ 2 files changed, 98 insertions(+), 12 deletions(-) diff --git a/models/issue_comment.go b/models/issue_comment.go index 452afc79f0..94fca493e0 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -1157,12 +1157,11 @@ func getCommitIDsFromRepo(repo *Repository, oldCommitID, newCommitID, baseBranch return nil, false, err } - oldCommitBranch, err := oldCommit.GetBranchName() - if err != nil { + if err = oldCommit.LoadBranchName(); err != nil { return nil, false, err } - if oldCommitBranch == "" { + if len(oldCommit.Branch) == 0 { commitIDs = make([]string, 2) commitIDs[0] = oldCommitID commitIDs[1] = newCommitID @@ -1175,25 +1174,102 @@ func getCommitIDsFromRepo(repo *Repository, oldCommitID, newCommitID, baseBranch return nil, false, err } - var commits *list.List + var ( + commits *list.List + commitChecks map[string]commitBranchCheckItem + ) commits, err = newCommit.CommitsBeforeUntil(oldCommitID) if err != nil { return nil, false, err } commitIDs = make([]string, 0, commits.Len()) + commitChecks = make(map[string]commitBranchCheckItem) + + for e := commits.Front(); e != nil; e = e.Next() { + commitChecks[e.Value.(*git.Commit).ID.String()] = commitBranchCheckItem{ + Commit: e.Value.(*git.Commit), + Checked: false, + } + } + + if err = commitBranchCheck(gitRepo, newCommit, oldCommitID, baseBranch, commitChecks); err != nil { + return + } 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()) + commitID := e.Value.(*git.Commit).ID.String() + if item, ok := commitChecks[commitID]; ok && item.Checked { + commitIDs = append(commitIDs, commitID) } } return } + +type commitBranchCheckItem struct { + Commit *git.Commit + Checked bool +} + +func commitBranchCheck(gitRepo *git.Repository, startCommit *git.Commit, endCommitID, baseBranch string, commitList map[string]commitBranchCheckItem) (err error) { + var ( + item commitBranchCheckItem + ok bool + listItem *list.Element + tmp string + ) + + if startCommit.ID.String() == endCommitID { + return + } + + checkStack := list.New() + checkStack.PushBack(startCommit.ID.String()) + listItem = checkStack.Back() + + for listItem != nil { + tmp = listItem.Value.(string) + checkStack.Remove(listItem) + + if item, ok = commitList[tmp]; !ok { + listItem = checkStack.Back() + continue + } + + if item.Commit.ID.String() == endCommitID { + listItem = checkStack.Back() + continue + } + + if err = item.Commit.LoadBranchName(); err != nil { + return + } + + if item.Commit.Branch == baseBranch { + listItem = checkStack.Back() + continue + } + + if item.Checked { + listItem = checkStack.Back() + continue + } + + item.Checked = true + commitList[tmp] = item + + parentNum := item.Commit.ParentCount() + for i := 0; i < parentNum; i++ { + var parentCommit *git.Commit + parentCommit, err = item.Commit.Parent(i) + if err != nil { + return + } + checkStack.PushBack(parentCommit.ID.String()) + } + + listItem = checkStack.Back() + } + return nil +} diff --git a/modules/git/commit.go b/modules/git/commit.go index c06eabfbd4..b8ff99cdb6 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -482,6 +482,16 @@ func (c *Commit) GetBranchName() (string, error) { return strings.SplitN(strings.TrimSpace(data), "~", 2)[0], nil } +// LoadBranchName load branch name for commit +func (c *Commit) LoadBranchName() (err error) { + if len(c.Branch) != 0 { + return + } + + c.Branch, err = c.GetBranchName() + return +} + // GetTagName gets the current tag name for given commit func (c *Commit) GetTagName() (string, error) { data, err := NewCommand("describe", "--exact-match", "--tags", "--always", c.ID.String()).RunInDir(c.repo.Path)