refactor: decouple git.Repository(ctx) from git.Commit & git.Tree (#38464)

1. Storing "ctx" in a long-living object is wrong
2. Make the commit & tree cacheable (for the future performance
optimization)
3. Also fix some bad designs like `// FIXME: bad design, this field can
be nil if the commit is from "last commit cache"`

ref:
* #33893
This commit is contained in:
wxiaoguang
2026-07-16 01:30:01 +08:00
committed by GitHub
parent ed678b9d45
commit 82edc3da01
115 changed files with 732 additions and 864 deletions

View File

@@ -26,7 +26,7 @@ func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (stri
}
// getRepoChanges returns changes to repo since last indexer update
func getRepoChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
func getRepoChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, revision string) (*internal.RepoChanges, error) {
status, err := repo_model.GetIndexerStatus(ctx, repo, repo_model.RepoIndexerTypeCode)
if err != nil {
return nil, err
@@ -40,9 +40,9 @@ func getRepoChanges(ctx context.Context, repo *repo_model.Repository, revision s
}
if needGenesis {
return genesisChanges(ctx, repo, revision)
return genesisChanges(ctx, repo, gitRepo, revision)
}
return nonGenesisChanges(ctx, repo, revision)
return nonGenesisChanges(ctx, repo, gitRepo, revision)
}
func isIndexable(entry *git.TreeEntry) bool {
@@ -64,7 +64,7 @@ func isIndexable(entry *git.TreeEntry) bool {
}
// parseGitLsTreeOutput parses the output of a `git ls-tree -r --full-name` command
func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) {
func parseGitLsTreeOutput(ctx context.Context, gitRepo *git.Repository, stdout []byte) ([]internal.FileUpdate, error) {
entries, err := git.ParseTreeEntries(stdout)
if err != nil {
return nil, err
@@ -76,7 +76,7 @@ func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) {
updates[idxCount] = internal.FileUpdate{
Filename: entry.Name(),
BlobSha: entry.ID.String(),
Size: entry.Size(),
Size: entry.GetSize(ctx, gitRepo),
Sized: true,
}
idxCount++
@@ -86,7 +86,7 @@ func parseGitLsTreeOutput(stdout []byte) ([]internal.FileUpdate, error) {
}
// genesisChanges get changes to add repo to the indexer for the first time
func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
func genesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, revision string) (*internal.RepoChanges, error) {
var changes internal.RepoChanges
stdout, _, runErr := gitrepo.RunCmdBytes(ctx, repo, gitcmd.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision))
if runErr != nil {
@@ -94,12 +94,12 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, revision s
}
var err error
changes.Updates, err = parseGitLsTreeOutput(stdout)
changes.Updates, err = parseGitLsTreeOutput(ctx, gitRepo, stdout)
return &changes, err
}
// nonGenesisChanges get changes since the previous indexer update
func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revision string) (*internal.RepoChanges, error) {
func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, revision string) (*internal.RepoChanges, error) {
diffCmd := gitcmd.NewCommand("diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision)
stdout, _, runErr := gitrepo.RunCmdString(ctx, repo, diffCmd)
if runErr != nil {
@@ -109,7 +109,7 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
if err := (*globalIndexer.Load()).Delete(ctx, repo.ID); err != nil {
return nil, err
}
return genesisChanges(ctx, repo, revision)
return genesisChanges(ctx, repo, gitRepo, revision)
}
var changes internal.RepoChanges
@@ -124,7 +124,7 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
return err
}
updates, err1 := parseGitLsTreeOutput(lsTreeStdout)
updates, err1 := parseGitLsTreeOutput(ctx, gitRepo, lsTreeStdout)
if err1 != nil {
return err1
}

View File

@@ -13,6 +13,7 @@ import (
"gitea.dev/models/db"
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/graceful"
"gitea.dev/modules/indexer"
"gitea.dev/modules/indexer/code/bleve"
@@ -73,11 +74,17 @@ func index(ctx context.Context, indexer internal.Indexer, repoID int64) error {
return nil
}
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
return err
}
defer closer.Close()
sha, err := getDefaultBranchSha(ctx, repo)
if err != nil {
return err
}
changes, err := getRepoChanges(ctx, repo, sha)
changes, err := getRepoChanges(ctx, repo, gitRepo, sha)
if err != nil {
return err
} else if changes == nil {