chore: still keep ctx in git.Repository struct for cat-file batch command (#38684)

Unfortunately, we can't completely remove the ctx from git.Repository,
because the CatFileBatch still heavily depends on a parent context.

If we remove the Repository ctx, the CatFileBatch will become a mess and
create a lot of unnecessary git processes.

http://localhost:3000/-/admin/monitor/perftrace

* Before: open a repo home, dozens of git processes (duplicate cat-file)
* After: only a few (no duplicate cat-file)
This commit is contained in:
wxiaoguang
2026-07-29 01:04:22 +08:00
committed by GitHub
parent 5672b1c4cf
commit 4d6e172a0d
121 changed files with 259 additions and 254 deletions
+2 -2
View File
@@ -119,7 +119,7 @@ func Test_BatchChecker(t *testing.T) {
setting.AppDataPath = t.TempDir()
repoPath := "../tests/repos/language_stats_repo"
ctx := t.Context()
gitRepo, err := git.OpenRepositoryLocal(repoPath)
gitRepo, err := git.OpenRepositoryLocal(ctx, repoPath)
require.NoError(t, err)
defer gitRepo.Close()
@@ -144,7 +144,7 @@ func Test_BatchChecker(t *testing.T) {
})
assert.NoError(t, err)
tempRepo, err := git.OpenRepositoryLocal(dir)
tempRepo, err := git.OpenRepositoryLocal(ctx, dir)
assert.NoError(t, err)
defer tempRepo.Close()
+2 -2
View File
@@ -18,7 +18,7 @@ import (
func Test_Checker(t *testing.T) {
setting.AppDataPath = t.TempDir()
repoPath := "../tests/repos/language_stats_repo"
gitRepo, err := git.OpenRepositoryLocal(repoPath)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), repoPath)
require.NoError(t, err)
defer gitRepo.Close()
@@ -44,7 +44,7 @@ func Test_Checker(t *testing.T) {
})
assert.NoError(t, err)
tempRepo, err := git.OpenRepositoryLocal(dir)
tempRepo, err := git.OpenRepositoryLocal(t.Context(), dir)
assert.NoError(t, err)
defer tempRepo.Close()
+2 -2
View File
@@ -24,7 +24,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
storage := mockRepository("repo5_pulls_sha256")
repo, err := OpenRepository(storage)
repo, err := OpenRepository(ctx, storage)
assert.NoError(t, err)
defer repo.Close()
@@ -70,7 +70,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
storage := mockRepository("repo6_blame_sha256")
repo, err := OpenRepository(storage)
repo, err := OpenRepository(ctx, storage)
assert.NoError(t, err)
defer repo.Close()
+2 -2
View File
@@ -19,7 +19,7 @@ func TestReadingBlameOutput(t *testing.T) {
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
storage := mockRepository("repo5_pulls")
repo, err := OpenRepository(storage)
repo, err := OpenRepository(ctx, storage)
assert.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit(t.Context(), "f32b0a9dfd09a60f616f29158f772cedd89942d2")
@@ -64,7 +64,7 @@ func TestReadingBlameOutput(t *testing.T) {
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
storage := mockRepository("repo6_blame")
repo, err := OpenRepository(storage)
repo, err := OpenRepository(ctx, storage)
assert.NoError(t, err)
defer repo.Close()
+2 -2
View File
@@ -25,7 +25,7 @@ type Blob struct {
// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
// Calling the Close function on the result will discard all unread output.
func (b *Blob) DataAsync(ctx context.Context) (_ io.ReadCloser, retErr error) {
batch, cancel, err := b.repo.CatFileBatch(ctx)
batch, cancel, err := b.repo.CatFileBatch()
if err != nil {
return nil, err
}
@@ -56,7 +56,7 @@ func (b *Blob) Size(ctx context.Context) int64 {
return b.size
}
batch, cancel, err := b.repo.CatFileBatch(ctx)
batch, cancel, err := b.repo.CatFileBatch()
if err != nil {
log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.LogString(), err)
return 0
+2 -2
View File
@@ -16,7 +16,7 @@ import (
func TestBlob_Data(t *testing.T) {
output := "file2\n"
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
require.NoError(t, err)
defer repo.Close()
@@ -36,7 +36,7 @@ func TestBlob_Data(t *testing.T) {
func Benchmark_Blob_Data(b *testing.B) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(b.Context(), bareRepo1Path)
if err != nil {
b.Fatal(err)
}
+2 -2
View File
@@ -14,7 +14,7 @@ import (
// GetBranchesByPath returns a branch by its path
// if limit = 0 it will not limit
func GetBranchesByPath(ctx context.Context, repo RepositoryFacade, skip, limit int) ([]string, int, error) {
gitRepo, err := OpenRepository(repo)
gitRepo, err := OpenRepository(ctx, repo)
if err != nil {
return nil, 0, err
}
@@ -24,7 +24,7 @@ func GetBranchesByPath(ctx context.Context, repo RepositoryFacade, skip, limit i
}
func GetBranchCommitID(ctx context.Context, repo RepositoryFacade, branch string) (string, error) {
gitRepo, err := OpenRepository(repo)
gitRepo, err := OpenRepository(ctx, repo)
if err != nil {
return "", err
}
+10 -7
View File
@@ -9,6 +9,7 @@ import (
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/setting"
"gitea.dev/modules/util"
)
// catFileBatchCommand implements the CatFileBatch interface using the "cat-file --batch-command" command
@@ -26,11 +27,11 @@ func newCatFileBatchCommand(ctx context.Context, repo RepositoryFacade) *catFile
return &catFileBatchCommand{ctx: ctx, repo: repo}
}
func (b *catFileBatchCommand) getBatch() *catFileBatchCommunicator {
func (b *catFileBatchCommand) getBatch(callerInfo string) *catFileBatchCommunicator {
if b.batch != nil {
return b.batch
}
b.batch = newCatFileBatch(b.ctx, b.repo, gitcmd.NewCommand("cat-file", "--batch-command"))
b.batch = newCatFileBatch(b.ctx, b.repo, gitcmd.NewCommand("cat-file", "--batch-command").WithParentCallerInfo(callerInfo))
return b.batch
}
@@ -42,26 +43,28 @@ func (b *catFileBatchCommand) QueryContent(obj string) (*CatFileObject, Buffered
if strings.Contains(obj, "\n") {
setting.PanicInDevOrTesting("invalid object name with newline: %q", obj)
}
_, err := b.getBatch().reqWriter.Write([]byte("contents " + obj + "\n"))
batch := b.getBatch(util.CallerFuncName(1))
_, err := batch.reqWriter.Write([]byte("contents " + obj + "\n"))
if err != nil {
return nil, nil, err
}
info, err := catFileBatchParseInfoLine(b.getBatch().respReader)
info, err := catFileBatchParseInfoLine(batch.respReader)
if err != nil {
return nil, nil, err
}
return info, b.getBatch().respReader, nil
return info, batch.respReader, nil
}
func (b *catFileBatchCommand) QueryInfo(obj string) (*CatFileObject, error) {
if strings.Contains(obj, "\n") {
setting.PanicInDevOrTesting("invalid object name with newline: %q", obj)
}
_, err := b.getBatch().reqWriter.Write([]byte("info " + obj + "\n"))
batch := b.getBatch(util.CallerFuncName(1))
_, err := batch.reqWriter.Write([]byte("info " + obj + "\n"))
if err != nil {
return nil, err
}
return catFileBatchParseInfoLine(b.getBatch().respReader)
return catFileBatchParseInfoLine(batch.respReader)
}
func (b *catFileBatchCommand) Close() {
+1 -1
View File
@@ -52,7 +52,7 @@ func newCatFileBatch(ctx context.Context, repo RepositoryFacade, cmdCatFile *git
stdPipeClose()
}))
err := cmdCatFile.WithRepo(repo).StartWithStderr(ctx)
err := cmdCatFile.WithParentCallerInfo().WithRepo(repo).StartWithStderr(ctx)
if err != nil {
log.Error("Unable to start git command %v: %v", cmdCatFile.LogString(), err)
// ideally here it should return the error, but it would require refactoring all callers
+1 -1
View File
@@ -19,7 +19,7 @@ import (
)
func TestEntries_GetCommitsInfo_ContextErr(t *testing.T) {
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer repo.Close()
+2 -2
View File
@@ -127,7 +127,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
func TestEntries_GetCommitsInfo(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -137,7 +137,7 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
if err != nil {
assert.NoError(t, err)
}
clonedRepo1, err := OpenRepositoryLocal(clonedPath)
clonedRepo1, err := OpenRepositoryLocal(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
}
+2 -2
View File
@@ -56,7 +56,7 @@ signed commit`
0x94, 0x33, 0xb2, 0xa6, 0x2b, 0x96, 0x4c, 0x17, 0xa4, 0x48, 0x5a, 0xe1, 0x80, 0xf4, 0x5f, 0x59,
0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0,
}
gitRepo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare_sha256"))
gitRepo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare_sha256"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -99,7 +99,7 @@ signed commit`, commitFromReader.Signature.Payload)
func TestHasPreviousCommitSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
+4 -4
View File
@@ -52,7 +52,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----
empty commit`
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
gitRepo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -116,7 +116,7 @@ gpgsig -----BEGIN PGP SIGNATURE-----
ISO-8859-1`
commitString = strings.ReplaceAll(commitString, "<SPACE>", " ")
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
gitRepo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
@@ -158,7 +158,7 @@ ISO-8859-1`, commitFromReader.Signature.Payload)
func TestHasPreviousCommit(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
@@ -183,7 +183,7 @@ func TestHasPreviousCommit(t *testing.T) {
func Test_GetCommitBranchStart(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
commit, err := repo.GetBranchCommit(t.Context(), "branch1")
+5 -10
View File
@@ -382,12 +382,7 @@ func (c *Command) WithParentCallerInfo(optInfo ...string) *Command {
return c
}
skip := 1 /*parent "wrap/run" functions*/ + 1 /*this function*/
callerFuncName := util.CallerFuncName(skip)
callerInfo := callerFuncName
if pos := strings.LastIndex(callerInfo, "/"); pos >= 0 {
callerInfo = callerInfo[pos+1:]
}
c.callerInfo = callerInfo
c.callerInfo = util.CallerFuncName(skip)
return c
}
@@ -535,7 +530,7 @@ func (c *Command) StartWithStderr(ctx context.Context) RunStdError {
}
c.cmdManagedStderr = &bytes.Buffer{}
c.cmdStderr = c.cmdManagedStderr
err := c.Start(ctx)
err := c.WithParentCallerInfo().Start(ctx)
if err != nil {
return &runStdError{err: err}
}
@@ -555,14 +550,14 @@ func (c *Command) WaitWithStderr() RunStdError {
}
func (c *Command) RunWithStderr(ctx context.Context) RunStdError {
if err := c.StartWithStderr(ctx); err != nil {
if err := c.WithParentCallerInfo().StartWithStderr(ctx); err != nil {
return &runStdError{err: err}
}
return c.WaitWithStderr()
}
func (c *Command) Run(ctx context.Context) (err error) {
if err = c.Start(ctx); err != nil {
if err = c.WithParentCallerInfo().Start(ctx); err != nil {
return err
}
return c.Wait()
@@ -585,7 +580,7 @@ func (c *Command) runStdBytes(ctx context.Context) ([]byte, []byte, RunStdError)
panic("stdout and stderr field must be nil when using RunStdBytes")
}
stdoutBuf := &bytes.Buffer{}
err := c.WithParentCallerInfo().WithStdoutBuffer(stdoutBuf).RunWithStderr(ctx)
err := c.WithStdoutBuffer(stdoutBuf).RunWithStderr(ctx)
return stdoutBuf.Bytes(), c.cmdManagedStderr.Bytes(), err
}
+2 -2
View File
@@ -25,7 +25,7 @@ func RepositoryFromContextOrOpen(ctx context.Context, repo RepositoryFacade) (*R
gitRepo, err := RepositoryFromRequestContextOrOpen(reqCtx, repo)
return gitRepo, util.NopCloser{}, err
}
gitRepo, err := OpenRepository(repo)
gitRepo, err := OpenRepository(ctx, repo)
return gitRepo, gitRepo, err
}
@@ -36,7 +36,7 @@ func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Reposito
if gitRepo, ok := ctx.Value(ck).(*Repository); ok {
return gitRepo, nil
}
gitRepo, err := OpenRepository(repo)
gitRepo, err := OpenRepository(ctx, repo)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -16,7 +16,7 @@ import (
func TestGrepSearch(t *testing.T) {
defer test.MockVariableValue(&setting.RepoRootPath, t.TempDir())()
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "language_stats_repo"))
repo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "language_stats_repo"))
assert.NoError(t, err)
defer repo.Close()
@@ -21,7 +21,7 @@ import (
func GetLanguageStats(ctx context.Context, repo *git.Repository, commitID string) (map[string]int64, error) {
// We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
// so let's create a batch stdin and stdout
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
@@ -16,7 +16,7 @@ import (
func TestRepository_GetLanguageStats(t *testing.T) {
setting.AppDataPath = t.TempDir()
repoPath := "../tests/repos/language_stats_repo"
gitRepo, err := git.OpenRepositoryLocal(repoPath)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), repoPath)
require.NoError(t, err)
defer gitRepo.Close()
+3 -3
View File
@@ -12,7 +12,7 @@ import (
func TestGetNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -25,7 +25,7 @@ func TestGetNotes(t *testing.T) {
func TestGetNestedNotes(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo3_notes")
repo, err := OpenRepositoryLocal(repoPath)
repo, err := OpenRepositoryLocal(t.Context(), repoPath)
assert.NoError(t, err)
defer repo.Close()
@@ -40,7 +40,7 @@ func TestGetNestedNotes(t *testing.T) {
func TestGetNonExistentNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
+1 -1
View File
@@ -32,7 +32,7 @@ func findLFSFileFunc(ctx context.Context, repo *git.Repository, objectID git.Obj
results := make([]*LFSResult, 0)
// Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
// so let's create a batch stdin and stdout
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func TestFindLFSFile(t *testing.T) {
repoPath := "../../../tests/gitea-repositories-meta/user2/lfs.git"
gitRepo, err := git.OpenRepositoryLocal(repoPath)
gitRepo, err := git.OpenRepositoryLocal(t.Context(), repoPath)
require.NoError(t, err)
defer gitRepo.Close()
+19 -19
View File
@@ -32,7 +32,15 @@ type RepositoryBase struct {
tagCache *ObjectCache[*Tag]
objectFormatCache ObjectFormat
mu sync.Mutex
mu sync.Mutex
// Unfortunately, we can't completely remove the ctx, because CatFileBatch still heavily depends on a parent context.
// If we remove the ctx, then CatFileBatch's process management will become a mess and create a lot of unnecessary git processes.
// ref: http://localhost:3000/-/admin/monitor/perftrace
// The root problem is that some functions like "GetCommit" need to use CatFileBatch,
// if CatFileBatch accepts its own ctx, then every sub-context needs a git process.
// e.g.: open a repo home, dozens of git processes (duplicate cat-file)
// ATTENTION: this ctx is for cached cat-file process only, don't use it for other purposes.
catFileBatchCtx context.Context
catFileBatchCloser CatFileBatchCloser
catFileBatchInUse bool
}
@@ -51,7 +59,7 @@ func (repo *Repository) LogString() string {
return repo.repoFacade.LogString()
}
func OpenRepository(repo RepositoryFacade) (*Repository, error) {
func OpenRepository(catFileBatchCtx context.Context, repo RepositoryFacade) (*Repository, error) {
repoPath := gitrepo.RepoLocalPath(repo)
exist, err := util.IsDir(repoPath)
if err != nil {
@@ -61,7 +69,7 @@ func OpenRepository(repo RepositoryFacade) (*Repository, error) {
return nil, util.NewNotExistErrorf("no such file or directory")
}
gitRepo := &Repository{
RepositoryBase: RepositoryBase{tagCache: newObjectCache[*Tag](), repoFacade: repo},
RepositoryBase: RepositoryBase{tagCache: newObjectCache[*Tag](), repoFacade: repo, catFileBatchCtx: catFileBatchCtx},
}
if err = openRepositoryInternal(gitRepo); err != nil {
return nil, err
@@ -71,14 +79,14 @@ func OpenRepository(repo RepositoryFacade) (*Repository, error) {
// OpenRepositoryLocal opens a local repository that is not managed by Gitea
// If the path is relative, it will be converted to an absolute path using filepath.Abs (base on current working path)
func OpenRepositoryLocal(localPath string) (_ *Repository, err error) {
func OpenRepositoryLocal(catFileBatchCtx context.Context, localPath string) (_ *Repository, err error) {
if !filepath.IsAbs(localPath) {
localPath, err = filepath.Abs(localPath)
if err != nil {
return nil, err
}
}
return OpenRepository(gitrepo.RepositoryUnmanaged(localPath))
return OpenRepository(catFileBatchCtx, gitrepo.RepositoryUnmanaged(localPath))
}
func (repo *Repository) Close() error {
@@ -276,30 +284,21 @@ func Push(ctx context.Context, localRepoPath string, opts PushOptions) error {
// CatFileBatch obtains a "batch object provider" for this repository.
// It reuses an existing one if available, otherwise creates a new one.
func (repo *Repository) CatFileBatch(ctx context.Context) (_ CatFileBatch, closeFunc func(), err error) {
func (repo *Repository) CatFileBatch() (_ CatFileBatch, closeFunc func(), err error) {
repo.mu.Lock()
defer repo.mu.Unlock()
// clean up the cached but canceled batcher
if repo.catFileBatchCloser != nil && repo.catFileBatchCloser.Context().Err() != nil && !repo.catFileBatchInUse {
repo.catFileBatchCloser.Close()
repo.catFileBatchCloser = nil
repo.catFileBatchInUse = false
}
// if no cached batcher, make a new managed one, and cache it
if repo.catFileBatchCloser == nil {
repo.catFileBatchCloser, err = NewBatch(ctx, repo)
repo.catFileBatchCloser, err = NewBatch(repo.catFileBatchCtx, repo)
if err != nil {
repo.catFileBatchCloser = nil // otherwise it is "interface(nil)" and will cause wrong logic
return nil, nil, err
}
}
// if the cached batcher is in use, or the cached ctx is not the current ctx, then we need a new temp one
// for example: the cached one is from request context, the current ctx is a cancelable ctx with timeout
needTemp := repo.catFileBatchInUse || repo.catFileBatchCloser.Context() != ctx
if !needTemp {
// if the cached batcher is not in use, return it
if !repo.catFileBatchInUse {
repo.catFileBatchInUse = true
return CatFileBatch(repo.catFileBatchCloser), func() {
repo.mu.Lock()
@@ -308,7 +307,8 @@ func (repo *Repository) CatFileBatch(ctx context.Context) (_ CatFileBatch, close
}, nil
}
tempBatch, err := NewBatch(ctx, repo)
// return a temp one (won't be cached or shared)
tempBatch, err := NewBatch(repo.catFileBatchCtx, repo)
if err != nil {
return nil, nil, err
}
+2 -2
View File
@@ -17,12 +17,12 @@ func TestRepoCatFileBatch(t *testing.T) {
t.Run("MissingRepoAndClose", func(t *testing.T) {
testDir := filepath.Join(t.TempDir(), "testdir")
_ = os.Mkdir(testDir, 0o755)
repo, err := OpenRepositoryLocal(testDir)
repo, err := OpenRepositoryLocal(t.Context(), testDir)
require.NoError(t, err)
// when the repo is missing (it usually occurs during testing because the fixtures are synced frequently)
err = os.Remove(testDir)
require.NoError(t, err)
_, _, err = repo.CatFileBatch(t.Context())
_, _, err = repo.CatFileBatch()
require.Error(t, err)
require.NoError(t, repo.Close()) // shouldn't panic
})
+3 -3
View File
@@ -14,7 +14,7 @@ import (
func TestRepository_GetBlob_Found(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepositoryLocal(repoPath)
r, err := OpenRepositoryLocal(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()
@@ -42,7 +42,7 @@ func TestRepository_GetBlob_Found(t *testing.T) {
func TestRepository_GetBlob_NotExist(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepositoryLocal(repoPath)
r, err := OpenRepositoryLocal(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()
@@ -56,7 +56,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) {
func TestRepository_GetBlob_NoId(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := OpenRepositoryLocal(repoPath)
r, err := OpenRepositoryLocal(t.Context(), repoPath)
assert.NoError(t, err)
defer r.Close()
+2 -2
View File
@@ -23,7 +23,7 @@ func (repo *Repository) IsObjectExist(ctx context.Context, name string) bool {
return false
}
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
log.Debug("Error opening CatFileBatch %v", err)
return false
@@ -43,7 +43,7 @@ func (repo *Repository) IsReferenceExist(ctx context.Context, name string) bool
return false
}
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
log.Error("Error opening CatFileBatch %v", err)
return false
+6 -6
View File
@@ -13,7 +13,7 @@ import (
func TestRepository_GetBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -41,7 +41,7 @@ func TestRepository_GetBranches(t *testing.T) {
func BenchmarkRepository_GetBranches(b *testing.B) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(b.Context(), bareRepo1Path)
if err != nil {
b.Fatal(err)
}
@@ -57,7 +57,7 @@ func BenchmarkRepository_GetBranches(b *testing.B) {
func TestGetRefsBySha(t *testing.T) {
bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls")
bareRepo5, err := OpenRepositoryLocal(bareRepo5Path)
bareRepo5, err := OpenRepositoryLocal(t.Context(), bareRepo5Path)
if err != nil {
t.Fatal(err)
}
@@ -84,7 +84,7 @@ func TestGetRefsBySha(t *testing.T) {
func BenchmarkGetRefsBySha(b *testing.B) {
bareRepo5Path := filepath.Join(testReposDir, "repo5_pulls")
bareRepo5, err := OpenRepositoryLocal(bareRepo5Path)
bareRepo5, err := OpenRepositoryLocal(b.Context(), bareRepo5Path)
if err != nil {
b.Fatal(err)
}
@@ -98,7 +98,7 @@ func BenchmarkGetRefsBySha(b *testing.B) {
func TestRepository_IsObjectExist(t *testing.T) {
ctx := t.Context()
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepositoryLocal(ctx, filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer repo.Close()
@@ -151,7 +151,7 @@ func TestRepository_IsObjectExist(t *testing.T) {
func TestRepository_IsReferenceExist(t *testing.T) {
ctx := t.Context()
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepositoryLocal(ctx, filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer repo.Close()
+3 -3
View File
@@ -37,7 +37,7 @@ func (repo *Repository) ResolveReference(ctx context.Context, name string) (stri
// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
func (repo *Repository) GetRefCommitID(ctx context.Context, name string) (string, error) {
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return "", err
}
@@ -52,7 +52,7 @@ func (repo *Repository) GetRefCommitID(ctx context.Context, name string) (string
}
func (repo *Repository) getCommit(ctx context.Context, id ObjectID) (*Commit, error) {
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
@@ -123,7 +123,7 @@ func (repo *Repository) ConvertToGitID(ctx context.Context, ref string) (ObjectI
}
}
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
+8 -8
View File
@@ -18,7 +18,7 @@ import (
func TestRepository_GetCommitBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -45,7 +45,7 @@ func TestRepository_GetCommitBranches(t *testing.T) {
func TestGetTagCommitWithSignature(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -60,7 +60,7 @@ func TestGetTagCommitWithSignature(t *testing.T) {
func TestGetCommitWithBadCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -72,7 +72,7 @@ func TestGetCommitWithBadCommitID(t *testing.T) {
func TestIsCommitInBranch(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -87,7 +87,7 @@ func TestIsCommitInBranch(t *testing.T) {
func TestRepository_CommitsBetween(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo4_commitsbetween")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -109,7 +109,7 @@ func TestRepository_CommitsBetween(t *testing.T) {
func TestGetRefCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -136,7 +136,7 @@ func TestCommitsByFileAndRange(t *testing.T) {
defer test.MockVariableValue(&setting.Git.CommitsRangeSize, 2)()
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
require.NoError(t, err)
defer bareRepo1.Close()
@@ -179,7 +179,7 @@ M 100644 :1 b.txt
`))).RunStdString(t.Context())
require.NoError(t, runErr)
repoFollowRename, err := OpenRepositoryLocal(repoFollowRenameDir)
repoFollowRename, err := OpenRepositoryLocal(t.Context(), repoFollowRenameDir)
require.NoError(t, err)
defer repoFollowRename.Close()
+4 -4
View File
@@ -22,7 +22,7 @@ func TestGetFormatPatch(t *testing.T) {
return
}
repo, err := OpenRepositoryLocal(clonedPath)
repo, err := OpenRepositoryLocal(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -50,7 +50,7 @@ func TestGetFormatPatch(t *testing.T) {
func TestReadPatch(t *testing.T) {
// Ensure we can read the patch files
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
if err != nil {
assert.NoError(t, err)
return
@@ -88,7 +88,7 @@ func TestReadWritePullHead(t *testing.T) {
return
}
repo, err := OpenRepositoryLocal(clonedPath)
repo, err := OpenRepositoryLocal(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -130,7 +130,7 @@ func TestReadWritePullHead(t *testing.T) {
func TestGetCommitFilesChanged(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := OpenRepositoryLocal(bareRepo1Path)
repo, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer repo.Close()
+2 -2
View File
@@ -12,7 +12,7 @@ import (
func TestRepository_GetRefs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
@@ -37,7 +37,7 @@ func TestRepository_GetRefs(t *testing.T) {
func TestRepository_GetRefsFiltered(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
+1 -1
View File
@@ -13,7 +13,7 @@ import (
func TestRepository_GetCodeActivityStats(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
assert.NoError(t, err)
defer bareRepo1.Close()
+2 -2
View File
@@ -25,7 +25,7 @@ func (repo *Repository) IsTagExist(ctx context.Context, name string) bool {
// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
func (repo *Repository) GetTagType(ctx context.Context, id ObjectID) (string, error) {
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return "", err
}
@@ -85,7 +85,7 @@ func (repo *Repository) getTag(ctx context.Context, tagID ObjectID, name string)
}
// The tag is an annotated tag with a message.
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
+3 -3
View File
@@ -13,7 +13,7 @@ import (
func TestRepository_GetTagInfos(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := OpenRepositoryLocal(bareRepo1Path)
bareRepo1, err := OpenRepositoryLocal(t.Context(), bareRepo1Path)
if err != nil {
assert.NoError(t, err)
return
@@ -44,7 +44,7 @@ func TestRepository_GetTag(t *testing.T) {
return
}
bareRepo1, err := OpenRepositoryLocal(clonedPath)
bareRepo1, err := OpenRepositoryLocal(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
@@ -136,7 +136,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
return
}
bareRepo1, err := OpenRepositoryLocal(clonedPath)
bareRepo1, err := OpenRepositoryLocal(t.Context(), clonedPath)
if err != nil {
assert.NoError(t, err)
return
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func TestRepoIsEmpty(t *testing.T) {
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
repo, err := OpenRepositoryLocal(emptyRepo2Path)
repo, err := OpenRepositoryLocal(t.Context(), emptyRepo2Path)
assert.NoError(t, err)
defer repo.Close()
isEmpty, err := repo.IsEmpty(t.Context())
+1 -1
View File
@@ -11,7 +11,7 @@ import (
)
func (repo *Repository) getTree(ctx context.Context, id ObjectID) (*Tree, error) {
batch, cancel, err := repo.CatFileBatch(ctx)
batch, cancel, err := repo.CatFileBatch()
if err != nil {
return nil, err
}
+1 -1
View File
@@ -14,7 +14,7 @@ import (
)
func TestFollowLink(t *testing.T) {
r, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
r, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
require.NoError(t, err)
defer r.Close()
+1 -1
View File
@@ -18,7 +18,7 @@ func (te *TreeEntry) GetSize(ctx context.Context, gitRepo *Repository) int64 {
return te.size
}
batch, cancel, err := gitRepo.CatFileBatch(ctx)
batch, cancel, err := gitRepo.CatFileBatch()
if err != nil {
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), gitRepo.LogString(), err)
return 0
+1 -1
View File
@@ -26,7 +26,7 @@ func (t *Tree) ListEntries(ctx context.Context, gitRepo *Repository) (Entries, e
return t.entries, nil
}
batch, cancel, err := gitRepo.CatFileBatch(ctx)
batch, cancel, err := gitRepo.CatFileBatch()
if err != nil {
return nil, err
}
+2 -2
View File
@@ -11,7 +11,7 @@ import (
)
func TestSubTree_Issue29101(t *testing.T) {
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo1_bare"))
repo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
assert.NoError(t, err)
defer repo.Close()
@@ -27,7 +27,7 @@ func TestSubTree_Issue29101(t *testing.T) {
}
func Test_GetTreePathLatestCommit(t *testing.T) {
repo, err := OpenRepositoryLocal(filepath.Join(testReposDir, "repo6_blame"))
repo, err := OpenRepositoryLocal(t.Context(), filepath.Join(testReposDir, "repo6_blame"))
assert.NoError(t, err)
defer repo.Close()
+1 -1
View File
@@ -36,7 +36,7 @@ func (db *DBIndexer) Index(id int64) error {
return err
}
gitRepo, err := git.OpenRepository(repo)
gitRepo, err := git.OpenRepository(ctx, repo)
if err != nil {
if err.Error() == "no such file or directory" {
return nil
+1 -1
View File
@@ -32,7 +32,7 @@ func SyncRepoBranches(ctx context.Context, repoID, doerID int64) (int64, error)
log.Debug("SyncRepoBranches: in Repo[%d:%s]", repo.ID, repo.FullName())
gitRepo, err := git.OpenRepository(repo)
gitRepo, err := git.OpenRepository(ctx, repo)
if err != nil {
log.Error("OpenRepository[%s]: %w", repo.FullName(), err)
return 0, err
+1 -1
View File
@@ -46,7 +46,7 @@ func SyncRepoTags(ctx context.Context, repoID int64) error {
return err
}
gitRepo, err := git.OpenRepository(repo)
gitRepo, err := git.OpenRepository(ctx, repo)
if err != nil {
return err
}
+8 -1
View File
@@ -3,7 +3,10 @@
package util
import "runtime"
import (
"runtime"
"strings"
)
const isOSWindows = runtime.GOOS == "windows"
@@ -15,5 +18,9 @@ func CallerFuncName(optSkipParent ...int) string {
}
runtime.Callers(skipParent+1 /*this*/ +1 /*runtime*/, pc)
funcName := runtime.FuncForPC(pc[0]).Name()
if pos := strings.LastIndex(funcName, "/"); pos >= 0 {
// only keep the last package name and func name
funcName = funcName[pos+1:]
}
return funcName
}
+1 -1
View File
@@ -12,7 +12,7 @@ import (
func TestCallerFuncName(t *testing.T) {
s := CallerFuncName()
assert.Equal(t, "gitea.dev/modules/util.TestCallerFuncName", s)
assert.Equal(t, "util.TestCallerFuncName", s)
}
func BenchmarkCallerFuncName(b *testing.B) {