From d3200db041a8b26169a4ec4b793fcbd1044370c1 Mon Sep 17 00:00:00 2001 From: zeripath Date: Sun, 14 Feb 2021 22:44:26 +0000 Subject: [PATCH] HasPreviousCommit causes recursive load of commits unnecessarily (#14598) (#14649) This PR improves HasPreviousCommit to prevent the automatic and recursive loading of previous commits using git merge-base --is-ancestor and git rev-list Fix #13684 Signed-off-by: Andrew Thornton Co-authored-by: 6543 <6543@obermui.de> --- modules/git/commit.go | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/modules/git/commit.go b/modules/git/commit.go index 6d2bc2b02c..b7d2c3a9f3 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -9,6 +9,7 @@ import ( "bufio" "bytes" "container/list" + "errors" "fmt" "image" "image/color" @@ -17,6 +18,7 @@ import ( _ "image/png" // for processing png images "io" "net/http" + "os/exec" "strconv" "strings" @@ -309,23 +311,33 @@ func (c *Commit) CommitsBefore() (*list.List, error) { // HasPreviousCommit returns true if a given commitHash is contained in commit's parents func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) { - for i := 0; i < c.ParentCount(); i++ { - commit, err := c.Parent(i) - if err != nil { - return false, err - } - if commit.ID == commitHash { + this := c.ID.String() + that := commitHash.String() + + if this == that { + return false, nil + } + + if err := CheckGitVersionConstraint(">= 1.8.0"); err == nil { + _, err := NewCommand("merge-base", "--is-ancestor", that, this).RunInDir(c.repo.Path) + if err == nil { return true, nil } - commitInParentCommit, err := commit.HasPreviousCommit(commitHash) - if err != nil { - return false, err - } - if commitInParentCommit { - return true, nil + var exitError *exec.ExitError + if errors.As(err, &exitError) { + if exitError.ProcessState.ExitCode() == 1 && len(exitError.Stderr) == 0 { + return false, nil + } } + return false, err + } + + result, err := NewCommand("rev-list", "--ancestry-path", "-n1", that+".."+this, "--").RunInDir(c.repo.Path) + if err != nil { + return false, err } - return false, nil + + return len(strings.TrimSpace(result)) > 0, nil } // CommitsBeforeLimit returns num commits before current revision -- 2.39.5