Skip to content

Commit d3200db

Browse files
zeripath6543
andauthored
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 <[email protected]> Co-authored-by: 6543 <[email protected]>
1 parent f305cff commit d3200db

File tree

1 file changed

+25
-13
lines changed

1 file changed

+25
-13
lines changed

modules/git/commit.go

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"bufio"
1010
"bytes"
1111
"container/list"
12+
"errors"
1213
"fmt"
1314
"image"
1415
"image/color"
@@ -17,6 +18,7 @@ import (
1718
_ "image/png" // for processing png images
1819
"io"
1920
"net/http"
21+
"os/exec"
2022
"strconv"
2123
"strings"
2224

@@ -309,23 +311,33 @@ func (c *Commit) CommitsBefore() (*list.List, error) {
309311

310312
// HasPreviousCommit returns true if a given commitHash is contained in commit's parents
311313
func (c *Commit) HasPreviousCommit(commitHash SHA1) (bool, error) {
312-
for i := 0; i < c.ParentCount(); i++ {
313-
commit, err := c.Parent(i)
314-
if err != nil {
315-
return false, err
316-
}
317-
if commit.ID == commitHash {
314+
this := c.ID.String()
315+
that := commitHash.String()
316+
317+
if this == that {
318+
return false, nil
319+
}
320+
321+
if err := CheckGitVersionConstraint(">= 1.8.0"); err == nil {
322+
_, err := NewCommand("merge-base", "--is-ancestor", that, this).RunInDir(c.repo.Path)
323+
if err == nil {
318324
return true, nil
319325
}
320-
commitInParentCommit, err := commit.HasPreviousCommit(commitHash)
321-
if err != nil {
322-
return false, err
323-
}
324-
if commitInParentCommit {
325-
return true, nil
326+
var exitError *exec.ExitError
327+
if errors.As(err, &exitError) {
328+
if exitError.ProcessState.ExitCode() == 1 && len(exitError.Stderr) == 0 {
329+
return false, nil
330+
}
326331
}
332+
return false, err
333+
}
334+
335+
result, err := NewCommand("rev-list", "--ancestry-path", "-n1", that+".."+this, "--").RunInDir(c.repo.Path)
336+
if err != nil {
337+
return false, err
327338
}
328-
return false, nil
339+
340+
return len(strings.TrimSpace(result)) > 0, nil
329341
}
330342

331343
// CommitsBeforeLimit returns num commits before current revision

0 commit comments

Comments
 (0)