package git
import (
+ "context"
"path"
"github.com/emirpasic/gods/trees/binaryheap"
)
// 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] = ""
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
}
}
}
} else {
- revs, err = GetLastCommitForPaths(c, treePath, entryPaths)
+ revs, err = GetLastCommitForPaths(ctx, c, treePath, entryPaths)
}
if err != nil {
return nil, nil, err
}
// 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()) {
heap.Push(&commitAndPaths{c, paths, initialHashes})
for {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
cIn, ok := heap.Pop()
if !ok {
break
import (
"bufio"
"bytes"
+ "context"
"fmt"
"io"
"math"
)
// 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] = ""
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
}
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
}
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()
}
// 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
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 {
treeReadingLoop:
for {
+ select {
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ default:
+ }
_, _, size, err := ReadBatchLine(batchReader)
if err != nil {
return nil, err
}
}
}
+ if scan.Err() != nil {
+ return nil, scan.Err()
+ }
commitsMap := make(map[string]*Commit, len(commits))
commitsMap[commit.ID.String()] = commit
package git
import (
+ "context"
"os"
"path/filepath"
"testing"
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()
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)
}
package git
import (
+ "context"
"path"
"github.com/go-git/go-git/v5/plumbing/object"
}
// 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()
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
}
entryMap[entry.Name()] = entry
}
- commits, err := GetLastCommitForPaths(index, treePath, entryPaths)
+ commits, err := GetLastCommitForPaths(ctx, index, treePath, entryPaths)
if err != nil {
return err
}
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
}
}
import (
"bufio"
+ "context"
"path"
)
}
// 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
}
entryMap[entry.Name()] = entry
}
- commits, err := GetLastCommitForPaths(commit, treePath, entryPaths)
+ commits, err := GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
if err != nil {
return err
}
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
}
}
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
return err
}
- lastCommits, err := GetLastCommitForPaths(commitNode, "", []string{path})
+ lastCommits, err := GetLastCommitForPaths(ctx, commitNode, "", []string{path})
if err != nil {
return err
}
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
path = path[idx+1:]
}
- lastCommits, err := GetLastCommitForPaths(notes, treePath, []string{path})
+ lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
if err != nil {
return err
}
package git
import (
+ "context"
"path/filepath"
"testing"
defer bareRepo1.Close()
note := Note{}
- err = GetNote(bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
+ err = GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
assert.NoError(t, err)
assert.Equal(t, []byte("Note contents\n"), note.Message)
assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name)
defer repo.Close()
note := Note{}
- err = GetNote(repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
+ err = GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
assert.NoError(t, err)
assert.Equal(t, []byte("Note 2"), note.Message)
- err = GetNote(repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
+ err = GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
assert.NoError(t, err)
assert.Equal(t, []byte("Note 1"), note.Message)
}
package repository
import (
+ "context"
"strings"
"code.gitea.io/gitea/models"
}
// 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
}
commitCache := git.NewLastCommitCache(repo.FullName(), gitRepo, setting.LastCommitCacheTTLSeconds, cache.GetCache())
- return commitCache.CacheCommit(commit)
+ return commitCache.CacheCommit(ctx, commit)
}
}
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
}
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
}
// 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 {