Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make commit info cancelable #16032

Merged
merged 9 commits into from
Jun 6, 2021
14 changes: 10 additions & 4 deletions modules/git/commit_info_gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package git

import (
"context"
"path"

"github.com/emirpasic/gods/trees/binaryheap"
Expand All @@ -16,7 +17,7 @@ import (
)

// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) {
func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) {
entryPaths := make([]string, len(tes)+1)
// Get the commit for the treePath itself
entryPaths[0] = ""
Expand All @@ -42,7 +43,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo
return nil, nil, err
}
if len(unHitPaths) > 0 {
revs2, err := GetLastCommitForPaths(c, treePath, unHitPaths)
revs2, err := GetLastCommitForPaths(ctx, c, treePath, unHitPaths)
if err != nil {
return nil, nil, err
}
Expand All @@ -55,7 +56,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo
}
}
} else {
revs, err = GetLastCommitForPaths(c, treePath, entryPaths)
revs, err = GetLastCommitForPaths(ctx, c, treePath, entryPaths)
}
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -173,7 +174,7 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac
}

// GetLastCommitForPaths returns last commit information
func GetLastCommitForPaths(c cgobject.CommitNode, treePath string, paths []string) (map[string]*object.Commit, error) {
func GetLastCommitForPaths(ctx context.Context, c cgobject.CommitNode, treePath string, paths []string) (map[string]*object.Commit, error) {
// We do a tree traversal with nodes sorted by commit time
heap := binaryheap.NewWith(func(a, b interface{}) int {
if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) {
Expand All @@ -192,6 +193,11 @@ func GetLastCommitForPaths(c cgobject.CommitNode, treePath string, paths []strin
heap.Push(&commitAndPaths{c, paths, initialHashes})

for {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
}
cIn, ok := heap.Pop()
if !ok {
break
Expand Down
23 changes: 16 additions & 7 deletions modules/git/commit_info_nogogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package git
import (
"bufio"
"bytes"
"context"
"fmt"
"io"
"math"
Expand All @@ -18,7 +19,7 @@ import (
)

// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) {
func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string, cache *LastCommitCache) ([]CommitInfo, *Commit, error) {
entryPaths := make([]string, len(tes)+1)
// Get the commit for the treePath itself
entryPaths[0] = ""
Expand All @@ -31,13 +32,13 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo
var revs map[string]*Commit
if cache != nil {
var unHitPaths []string
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, cache)
revs, unHitPaths, err = getLastCommitForPathsByCache(ctx, commit.ID.String(), treePath, entryPaths, cache)
if err != nil {
return nil, nil, err
}
if len(unHitPaths) > 0 {
sort.Strings(unHitPaths)
commits, err := GetLastCommitForPaths(commit, treePath, unHitPaths)
commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths)
if err != nil {
return nil, nil, err
}
Expand All @@ -53,7 +54,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo
sort.Strings(entryPaths)
revs = map[string]*Commit{}
var foundCommits []*Commit
foundCommits, err = GetLastCommitForPaths(commit, treePath, entryPaths)
foundCommits, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
for i, found := range foundCommits {
revs[entryPaths[i]] = found
}
Expand Down Expand Up @@ -101,7 +102,7 @@ func (tes Entries) GetCommitsInfo(commit *Commit, treePath string, cache *LastCo
return commitsInfo, treeCommit, nil
}

func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
func getLastCommitForPathsByCache(ctx context.Context, commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
wr, rd, cancel := cache.repo.CatFileBatch()
defer cancel()

Expand All @@ -124,7 +125,7 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac
}

// GetLastCommitForPaths returns last commit information
func GetLastCommitForPaths(commit *Commit, treePath string, paths []string) ([]*Commit, error) {
func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) ([]*Commit, error) {
// We read backwards from the commit to obtain all of the commits

// We'll do this by using rev-list to provide us with parent commits in order
Expand All @@ -136,7 +137,7 @@ func GetLastCommitForPaths(commit *Commit, treePath string, paths []string) ([]*

go func() {
stderr := strings.Builder{}
err := NewCommand("rev-list", "--format=%T", commit.ID.String()).RunInDirPipeline(commit.repo.Path, revListWriter, &stderr)
err := NewCommand("rev-list", "--format=%T", commit.ID.String()).SetParentContext(ctx).RunInDirPipeline(commit.repo.Path, revListWriter, &stderr)
if err != nil {
_ = revListWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {
Expand Down Expand Up @@ -202,6 +203,11 @@ revListLoop:

treeReadingLoop:
for {
select {
case <-ctx.Done():
return nil, ctx.Err()
default:
}
_, _, size, err := ReadBatchLine(batchReader)
if err != nil {
return nil, err
Expand Down Expand Up @@ -321,6 +327,9 @@ revListLoop:
}
}
}
if scan.Err() != nil {
return nil, scan.Err()
}

commitsMap := make(map[string]*Commit, len(commits))
commitsMap[commit.ID.String()] = commit
Expand Down
5 changes: 3 additions & 2 deletions modules/git/commit_info_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package git

import (
"context"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -69,7 +70,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
assert.NoError(t, err)
entries, err := tree.ListEntries()
assert.NoError(t, err)
commitsInfo, treeCommit, err := entries.GetCommitsInfo(commit, testCase.Path, nil)
commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.Background(), commit, testCase.Path, nil)
assert.NoError(t, err)
if err != nil {
t.FailNow()
Expand Down Expand Up @@ -136,7 +137,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
b.ResetTimer()
b.Run(benchmark.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
_, _, err := entries.GetCommitsInfo(commit, "", nil)
_, _, err := entries.GetCommitsInfo(context.Background(), commit, "", nil)
if err != nil {
b.Fatal(err)
}
Expand Down
11 changes: 6 additions & 5 deletions modules/git/last_commit_cache_gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package git

import (
"context"
"path"

"github.com/go-git/go-git/v5/plumbing/object"
Expand Down Expand Up @@ -60,7 +61,7 @@ func (c *LastCommitCache) Get(ref, entryPath string) (interface{}, error) {
}

// CacheCommit will cache the commit from the gitRepository
func (c *LastCommitCache) CacheCommit(commit *Commit) error {
func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error {

commitNodeIndex, _ := commit.repo.CommitNodeIndex()

Expand All @@ -69,10 +70,10 @@ func (c *LastCommitCache) CacheCommit(commit *Commit) error {
return err
}

return c.recursiveCache(index, &commit.Tree, "", 1)
return c.recursiveCache(ctx, index, &commit.Tree, "", 1)
}

func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
func (c *LastCommitCache) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
if level == 0 {
return nil
}
Expand All @@ -89,7 +90,7 @@ func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree,
entryMap[entry.Name()] = entry
}

commits, err := GetLastCommitForPaths(index, treePath, entryPaths)
commits, err := GetLastCommitForPaths(ctx, index, treePath, entryPaths)
if err != nil {
return err
}
Expand All @@ -103,7 +104,7 @@ func (c *LastCommitCache) recursiveCache(index cgobject.CommitNode, tree *Tree,
if err != nil {
return err
}
if err := c.recursiveCache(index, subTree, entry, level-1); err != nil {
if err := c.recursiveCache(ctx, index, subTree, entry, level-1); err != nil {
return err
}
}
Expand Down
11 changes: 6 additions & 5 deletions modules/git/last_commit_cache_nogogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package git

import (
"bufio"
"context"
"path"
)

Expand Down Expand Up @@ -61,11 +62,11 @@ func (c *LastCommitCache) Get(ref, entryPath string, wr WriteCloserError, rd *bu
}

// CacheCommit will cache the commit from the gitRepository
func (c *LastCommitCache) CacheCommit(commit *Commit) error {
return c.recursiveCache(commit, &commit.Tree, "", 1)
func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error {
return c.recursiveCache(ctx, commit, &commit.Tree, "", 1)
}

func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath string, level int) error {
func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tree *Tree, treePath string, level int) error {
if level == 0 {
return nil
}
Expand All @@ -82,7 +83,7 @@ func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath st
entryMap[entry.Name()] = entry
}

commits, err := GetLastCommitForPaths(commit, treePath, entryPaths)
commits, err := GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
if err != nil {
return err
}
Expand All @@ -97,7 +98,7 @@ func (c *LastCommitCache) recursiveCache(commit *Commit, tree *Tree, treePath st
if err != nil {
return err
}
if err := c.recursiveCache(commit, subTree, entry, level-1); err != nil {
if err := c.recursiveCache(ctx, commit, subTree, entry, level-1); err != nil {
return err
}
}
Expand Down
5 changes: 3 additions & 2 deletions modules/git/notes_gogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
package git

import (
"context"
"io/ioutil"

"github.com/go-git/go-git/v5/plumbing/object"
)

// GetNote retrieves the git-notes data for a given commit.
func GetNote(repo *Repository, commitID string, note *Note) error {
func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
notes, err := repo.GetCommit(NotesRef)
if err != nil {
return err
Expand Down Expand Up @@ -62,7 +63,7 @@ func GetNote(repo *Repository, commitID string, note *Note) error {
return err
}

lastCommits, err := GetLastCommitForPaths(commitNode, "", []string{path})
lastCommits, err := GetLastCommitForPaths(ctx, commitNode, "", []string{path})
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions modules/git/notes_nogogit.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
package git

import (
"context"
"io/ioutil"
"strings"
)

// GetNote retrieves the git-notes data for a given commit.
func GetNote(repo *Repository, commitID string, note *Note) error {
func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
notes, err := repo.GetCommit(NotesRef)
if err != nil {
return err
Expand Down Expand Up @@ -63,7 +64,7 @@ func GetNote(repo *Repository, commitID string, note *Note) error {
path = path[idx+1:]
}

lastCommits, err := GetLastCommitForPaths(notes, treePath, []string{path})
lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
if err != nil {
return err
}
Expand Down
7 changes: 4 additions & 3 deletions modules/git/notes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package git

import (
"context"
"path/filepath"
"testing"

Expand All @@ -18,7 +19,7 @@ func TestGetNotes(t *testing.T) {
defer bareRepo1.Close()

note := Note{}
err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
err = GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", &note)
assert.NoError(t, err)
assert.Equal(t, []byte("Note contents\n"), note.Message)
assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name)
Expand All @@ -31,10 +32,10 @@ func TestGetNestedNotes(t *testing.T) {
defer repo.Close()

note := Note{}
err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note)
err = GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", &note)
assert.NoError(t, err)
assert.Equal(t, []byte("Note 2"), note.Message)
err = GetNote(repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", &note)
err = GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", &note)
assert.NoError(t, err)
assert.Equal(t, []byte("Note 1"), note.Message)
}
5 changes: 3 additions & 2 deletions modules/repository/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package repository

import (
"context"
"strings"

"code.gitea.io/gitea/models"
Expand All @@ -23,7 +24,7 @@ func getRefName(fullRefName string) string {
}

// CacheRef cachhe last commit information of the branch or the tag
func CacheRef(repo *models.Repository, gitRepo *git.Repository, fullRefName string) error {
func CacheRef(ctx context.Context, repo *models.Repository, gitRepo *git.Repository, fullRefName string) error {
if !setting.CacheService.LastCommit.Enabled {
return nil
}
Expand All @@ -43,5 +44,5 @@ func CacheRef(repo *models.Repository, gitRepo *git.Repository, fullRefName stri

commitCache := git.NewLastCommitCache(repo.FullName(), gitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache())

return commitCache.CacheCommit(commit)
return commitCache.CacheCommit(ctx, commit)
}
2 changes: 1 addition & 1 deletion routers/repo/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func Diff(ctx *context.Context) {
}

note := &git.Note{}
err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
err = git.GetNote(ctx, ctx.Repo.GitRepo, commitID, note)
if err == nil {
ctx.Data["Note"] = string(charset.ToUTF8WithFallback(note.Message))
ctx.Data["NoteCommit"] = note.Commit
Expand Down
2 changes: 1 addition & 1 deletion routers/repo/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ func renderDirectory(ctx *context.Context, treeLink string) {
}

var latestCommit *git.Commit
ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx.Repo.Commit, ctx.Repo.TreePath, c)
ctx.Data["Files"], latestCommit, err = entries.GetCommitsInfo(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, c)
if err != nil {
ctx.ServerError("GetCommitsInfo", err)
return
Expand Down
2 changes: 1 addition & 1 deletion services/repository/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
}

// Cache for big repository
if err := repo_module.CacheRef(repo, gitRepo, opts.RefFullName); err != nil {
if err := repo_module.CacheRef(graceful.GetManager().HammerContext(), repo, gitRepo, opts.RefFullName); err != nil {
log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err)
}
} else {
Expand Down