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
+7 -5
View File
@@ -4,6 +4,8 @@
package actions
import (
"context"
"gitea.dev/modules/actions/jobparser"
"gitea.dev/modules/git"
"gitea.dev/modules/log"
@@ -13,8 +15,8 @@ import (
)
// ListScopedWorkflows lists scoped workflow files (under SCOPED_WORKFLOW_DIRS) at the given commit.
func ListScopedWorkflows(commit *git.Commit) (string, git.Entries, error) {
return listWorkflowsInDirs(commit, setting.Actions.ScopedWorkflowDirs)
func ListScopedWorkflows(ctx context.Context, gitRepo *git.Repository, commit *git.Commit) (string, git.Entries, error) {
return listWorkflowsInDirs(ctx, gitRepo, commit, setting.Actions.ScopedWorkflowDirs)
}
// ParsedScopedWorkflow is one scoped workflow's source-side parse result
@@ -26,15 +28,15 @@ type ParsedScopedWorkflow struct {
}
// ParseScopedWorkflows lists and parses the scoped workflow files at sourceCommit (under SCOPED_WORKFLOW_DIRS).
func ParseScopedWorkflows(sourceCommit *git.Commit) ([]*ParsedScopedWorkflow, error) {
_, entries, err := ListScopedWorkflows(sourceCommit)
func ParseScopedWorkflows(ctx context.Context, gitRepo *git.Repository, sourceCommit *git.Commit) ([]*ParsedScopedWorkflow, error) {
_, entries, err := ListScopedWorkflows(ctx, gitRepo, sourceCommit)
if err != nil {
return nil, err
}
parsed := make([]*ParsedScopedWorkflow, 0, len(entries))
for _, entry := range entries {
content, err := GetContentFromEntry(entry)
content, err := GetContentFromEntry(gitRepo, entry)
if err != nil {
return nil, err
}
+20 -18
View File
@@ -5,6 +5,7 @@ package actions
import (
"bytes"
"context"
"fmt"
"path"
"slices"
@@ -69,16 +70,16 @@ func isWorkflowInDirs(path string, dirs []string) bool {
return false
}
func ListWorkflows(commit *git.Commit) (string, git.Entries, error) {
return listWorkflowsInDirs(commit, setting.Actions.WorkflowDirs)
func ListWorkflows(ctx context.Context, gitRepo *git.Repository, commit *git.Commit) (string, git.Entries, error) {
return listWorkflowsInDirs(ctx, gitRepo, commit, setting.Actions.WorkflowDirs)
}
func listWorkflowsInDirs(commit *git.Commit, dirs []string) (string, git.Entries, error) {
func listWorkflowsInDirs(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, dirs []string) (string, git.Entries, error) {
var tree *git.Tree
var err error
var workflowDir string
for _, workflowDir = range dirs {
tree, err = commit.SubTree(workflowDir)
tree, err = commit.SubTree(ctx, gitRepo, workflowDir)
if err == nil {
break
}
@@ -90,7 +91,7 @@ func listWorkflowsInDirs(commit *git.Commit, dirs []string) (string, git.Entries
return "", nil, nil
}
entries, err := tree.ListEntriesRecursiveFast()
entries, err := tree.ListEntriesRecursiveFast(ctx, gitRepo)
if err != nil {
return "", nil, err
}
@@ -104,8 +105,8 @@ func listWorkflowsInDirs(commit *git.Commit, dirs []string) (string, git.Entries
return workflowDir, ret, nil
}
func GetContentFromEntry(entry *git.TreeEntry) ([]byte, error) {
f, err := entry.Blob().DataAsync()
func GetContentFromEntry(gitRepo *git.Repository, entry *git.TreeEntry) ([]byte, error) {
f, err := entry.Blob(gitRepo).DataAsync()
if err != nil {
return nil, err
}
@@ -175,19 +176,20 @@ func ShouldEventCreateCommitStatus(event string) bool {
}
func DetectWorkflows(
ctx context.Context,
gitRepo *git.Repository,
commit *git.Commit,
triggedEvent webhook_module.HookEventType,
payload api.Payloader,
detectSchedule bool,
) (workflows, schedules, filtered []*DetectedWorkflow, err error) {
_, entries, err := ListWorkflows(commit)
_, entries, err := ListWorkflows(ctx, gitRepo, commit)
if err != nil {
return nil, nil, nil, err
}
for _, entry := range entries {
content, err := GetContentFromEntry(entry)
content, err := GetContentFromEntry(gitRepo, entry)
if err != nil {
return nil, nil, nil, err
}
@@ -229,15 +231,15 @@ func DetectWorkflows(
return workflows, schedules, filtered, nil
}
func DetectScheduledWorkflows(gitRepo *git.Repository, commit *git.Commit) ([]*DetectedWorkflow, error) {
_, entries, err := ListWorkflows(commit)
func DetectScheduledWorkflows(ctx context.Context, gitRepo *git.Repository, commit *git.Commit) ([]*DetectedWorkflow, error) {
_, entries, err := ListWorkflows(ctx, gitRepo, commit)
if err != nil {
return nil, err
}
wfs := make([]*DetectedWorkflow, 0, len(entries))
for _, entry := range entries {
content, err := GetContentFromEntry(entry)
content, err := GetContentFromEntry(gitRepo, entry)
if err != nil {
return nil, err
}
@@ -284,7 +286,7 @@ func detectWorkflowMatch(gitRepo *git.Repository, commit *git.Commit, triggedEve
case // push
webhook_module.HookEventPush:
return matchPushEvent(commit, payload.(*api.PushPayload), evt)
return matchPushEvent(gitRepo, commit, payload.(*api.PushPayload), evt)
case // issues
webhook_module.HookEventIssues,
@@ -357,7 +359,7 @@ func detectWorkflowMatch(gitRepo *git.Repository, commit *git.Commit, triggedEve
}
}
func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) detectResult {
func matchPushEvent(gitRepo *git.Repository, commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) detectResult {
// with no special filter parameters
if len(evt.Acts()) == 0 {
return detectMatched
@@ -423,7 +425,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
matchTimes++
break
}
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
filesChanged, err := commit.GetFilesChangedSinceCommit(gitRepo, pushPayload.Before)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
return detectNotApplicable
@@ -440,7 +442,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
matchTimes++
break
}
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
filesChanged, err := commit.GetFilesChangedSinceCommit(gitRepo, pushPayload.Before)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
return detectNotApplicable
@@ -590,7 +592,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
matchTimes++
}
case "paths":
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
filesChanged, err := headCommit.GetFilesChangedSinceCommit(gitRepo, prPayload.PullRequest.MergeBase)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
return detectNotApplicable
@@ -603,7 +605,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
matchTimes++
}
case "paths-ignore":
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
filesChanged, err := headCommit.GetFilesChangedSinceCommit(gitRepo, prPayload.PullRequest.MergeBase)
if err != nil {
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
return detectNotApplicable
+7 -3
View File
@@ -3,7 +3,11 @@
package fileicon
import "gitea.dev/modules/git"
import (
"context"
"gitea.dev/modules/git"
)
type EntryInfo struct {
BaseName string
@@ -12,10 +16,10 @@ type EntryInfo struct {
IsOpen bool
}
func EntryInfoFromGitTreeEntry(commit *git.Commit, fullPath string, gitEntry *git.TreeEntry) *EntryInfo {
func EntryInfoFromGitTreeEntry(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, fullPath string, gitEntry *git.TreeEntry) *EntryInfo {
ret := &EntryInfo{BaseName: gitEntry.Name(), EntryMode: gitEntry.Mode()}
if gitEntry.IsLink() {
if res, err := git.EntryFollowLink(commit, fullPath, gitEntry); err == nil && res.TargetEntry.IsDir() {
if res, err := git.EntryFollowLink(ctx, gitRepo, commit, fullPath, gitEntry); err == nil && res.TargetEntry.IsDir() {
ret.SymlinkToMode = res.TargetEntry.Mode()
}
}
+52 -43
View File
@@ -17,17 +17,17 @@ import (
// Commit represents a git commit.
type Commit struct {
Tree // FIXME: bad design, this field can be nil if the commit is from "last commit cache"
CommitMessage
ID ObjectID
TreeID ObjectID
Parents []ObjectID
Author *Signature // never nil
Committer *Signature // never nil
Signature *CommitSignature
Parents []ObjectID // ID strings
submoduleCache *ObjectCache[*SubModule]
treeCache *Tree
}
// CommitSignature represents a git commit signature part.
@@ -46,12 +46,12 @@ func (c *Commit) ParentID(n int) (ObjectID, error) {
}
// Parent returns n-th parent (0-based index) of the commit.
func (c *Commit) Parent(n int) (*Commit, error) {
func (c *Commit) Parent(gitRepo *Repository, n int) (*Commit, error) {
id, err := c.ParentID(n)
if err != nil {
return nil, err
}
parent, err := c.repo.getCommit(id)
parent, err := gitRepo.getCommit(id)
if err != nil {
return nil, err
}
@@ -65,25 +65,44 @@ func (c *Commit) ParentCount() int {
}
// GetCommitByPath return the commit of relative path object.
func (c *Commit) GetCommitByPath(relpath string) (*Commit, error) {
if c.repo.LastCommitCache != nil {
return c.repo.LastCommitCache.GetCommitByPath(c.ID.String(), relpath)
func (c *Commit) GetCommitByPath(gitRepo *Repository, relpath string) (*Commit, error) {
if gitRepo.LastCommitCache != nil {
return gitRepo.LastCommitCache.GetCommitByPath(c.ID.String(), relpath)
}
return c.repo.getCommitByPathWithID(c.ID, relpath)
return gitRepo.getCommitByPathWithID(c.ID, relpath)
}
func (c *Commit) Tree() *Tree {
if c.treeCache == nil {
c.treeCache = newTree(c.TreeID)
}
return c.treeCache
}
func (c *Commit) GetBlobByPath(ctx context.Context, gitRepo *Repository, relpath string) (*Blob, error) {
return c.Tree().GetBlobByPath(ctx, gitRepo, relpath)
}
func (c *Commit) GetTreeEntryByPath(ctx context.Context, gitRepo *Repository, relpath string) (_ *TreeEntry, err error) {
return c.Tree().GetTreeEntryByPath(ctx, gitRepo, relpath)
}
func (c *Commit) SubTree(ctx context.Context, gitRepo *Repository, relpath string) (*Tree, error) {
return c.Tree().SubTree(ctx, gitRepo, relpath)
}
// CommitsByRange returns the specific page commits before current revision, every page's number default by CommitsRangeSize
func (c *Commit) CommitsByRange(page, pageSize int, not, since, until string) ([]*Commit, error) {
return c.repo.commitsByRangeWithTime(c.ID, page, pageSize, not, since, until)
func (c *Commit) CommitsByRange(gitRepo *Repository, page, pageSize int, not, since, until string) ([]*Commit, error) {
return gitRepo.commitsByRangeWithTime(c.ID, page, pageSize, not, since, until)
}
// CommitsBefore returns all the commits before current revision
func (c *Commit) CommitsBefore() ([]*Commit, error) {
return c.repo.getCommitsBefore(c.ID)
func (c *Commit) CommitsBefore(gitRepo *Repository) ([]*Commit, error) {
return gitRepo.getCommitsBefore(c.ID)
}
// HasPreviousCommit returns true if a given commitHash is contained in commit's parents
func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) {
func (c *Commit) HasPreviousCommit(ctx context.Context, gitRepo *Repository, objectID ObjectID) (bool, error) {
this := c.ID.String()
that := objectID.String()
@@ -93,8 +112,8 @@ func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) {
_, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").
AddDynamicArguments(that, this).
WithDir(c.repo.Path).
RunStdString(c.repo.Ctx)
WithDir(gitRepo.Path).
RunStdString(ctx)
if err == nil {
return true, nil
}
@@ -108,8 +127,8 @@ func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) {
}
// IsForcePush returns true if a push from oldCommitHash to this is a force push
func (c *Commit) IsForcePush(oldCommitID string) (bool, error) {
objectFormat, err := c.repo.GetObjectFormat()
func (c *Commit) IsForcePush(ctx context.Context, gitRepo *Repository, oldCommitID string) (bool, error) {
objectFormat, err := gitRepo.GetObjectFormat()
if err != nil {
return false, err
}
@@ -117,22 +136,22 @@ func (c *Commit) IsForcePush(oldCommitID string) (bool, error) {
return false, nil
}
oldCommit, err := c.repo.GetCommit(oldCommitID)
oldCommit, err := gitRepo.GetCommit(oldCommitID)
if err != nil {
return false, err
}
hasPreviousCommit, err := c.HasPreviousCommit(oldCommit.ID)
hasPreviousCommit, err := c.HasPreviousCommit(ctx, gitRepo, oldCommit.ID)
return !hasPreviousCommit, err
}
// CommitsBeforeLimit returns num commits before current revision
func (c *Commit) CommitsBeforeLimit(num int) ([]*Commit, error) {
return c.repo.getCommitsBeforeLimit(c.ID, num)
func (c *Commit) CommitsBeforeLimit(gitRepo *Repository, num int) ([]*Commit, error) {
return gitRepo.getCommitsBeforeLimit(c.ID, num)
}
// CommitsBeforeUntil returns the commits in range "[cur, ref)"
func (c *Commit) CommitsBeforeUntil(ref RefName) ([]*Commit, error) {
return c.repo.CommitsBetween(c.ID.RefName(), ref, -1)
func (c *Commit) CommitsBeforeUntil(gitRepo *Repository, ref RefName) ([]*Commit, error) {
return gitRepo.CommitsBetween(c.ID.RefName(), ref, -1)
}
// SearchCommitsOptions specify the parameters for SearchCommits
@@ -175,39 +194,29 @@ func NewSearchCommitsOptions(searchString string, forAllRefs bool) SearchCommits
}
// SearchCommits returns the commits match the keyword before current revision
func (c *Commit) SearchCommits(opts SearchCommitsOptions) ([]*Commit, error) {
return c.repo.searchCommits(c.ID, opts)
func (c *Commit) SearchCommits(gitRepo *Repository, opts SearchCommitsOptions) ([]*Commit, error) {
return gitRepo.searchCommits(c.ID, opts)
}
// GetFilesChangedSinceCommit get all changed file names between pastCommit to current revision
func (c *Commit) GetFilesChangedSinceCommit(pastCommit string) ([]string, error) {
return c.repo.GetFilesChangedBetween(pastCommit, c.ID.String())
func (c *Commit) GetFilesChangedSinceCommit(gitRepo *Repository, pastCommit string) ([]string, error) {
return gitRepo.GetFilesChangedBetween(pastCommit, c.ID.String())
}
// FileChangedSinceCommit Returns true if the file given has changed since the past commit
// YOU MUST ENSURE THAT pastCommit is a valid commit ID.
func (c *Commit) FileChangedSinceCommit(filename, pastCommit string) (bool, error) {
return c.repo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String())
}
// HasFile returns true if the file given exists on this commit
// This does only mean it's there - it does not mean the file was changed during the commit.
func (c *Commit) HasFile(filename string) (bool, error) {
_, err := c.GetBlobByPath(filename)
if err != nil {
return false, err
}
return true, nil
func (c *Commit) FileChangedSinceCommit(gitRepo *Repository, filename, pastCommit string) (bool, error) {
return gitRepo.FileChangedBetweenCommits(filename, pastCommit, c.ID.String())
}
// GetFileContent reads a file content as a string or returns false if this was not possible
func (c *Commit) GetFileContent(filename string, limit int) (string, error) {
entry, err := c.GetTreeEntryByPath(filename)
func (c *Commit) GetFileContent(ctx context.Context, gitRepo *Repository, filename string, limit int) (string, error) {
entry, err := c.GetTreeEntryByPath(ctx, gitRepo, filename)
if err != nil {
return "", err
}
r, err := entry.Blob().DataAsync()
r, err := entry.Blob(gitRepo).DataAsync()
if err != nil {
return "", err
}
+4 -2
View File
@@ -3,6 +3,8 @@
package git
import "context"
// CommitInfo describes the first commit with the provided entry
type CommitInfo struct {
Entry *TreeEntry
@@ -10,8 +12,8 @@ type CommitInfo struct {
SubmoduleFile *CommitSubmoduleFile
}
func GetCommitInfoSubmoduleFile(repoLink, fullPath string, commit *Commit, refCommitID ObjectID) (*CommitSubmoduleFile, error) {
submodule, err := commit.GetSubModule(fullPath)
func GetCommitInfoSubmoduleFile(ctx context.Context, repoLink, fullPath string, gitRepo *Repository, commit *Commit, refCommitID ObjectID) (*CommitSubmoduleFile, error) {
submodule, err := commit.GetSubModule(ctx, gitRepo, fullPath)
if err != nil {
return nil, err
}
+25 -22
View File
@@ -17,7 +17,7 @@ import (
)
// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, gitRepo *Repository, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
entryPaths := make([]string, len(tes)+1)
// Get the commit for the treePath itself
entryPaths[0] = ""
@@ -25,25 +25,16 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
entryPaths[i+1] = entry.Name()
}
commitNodeIndex, commitGraphFile := commit.repo.CommitNodeIndex()
if commitGraphFile != nil {
defer commitGraphFile.Close()
}
c, err := commitNodeIndex.Get(plumbing.Hash(commit.ID.RawValue()))
if err != nil {
return nil, nil, err
}
var revs map[string]*Commit
if commit.repo.LastCommitCache != nil {
var err error
if gitRepo.LastCommitCache != nil {
var unHitPaths []string
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, gitRepo.LastCommitCache)
if err != nil {
return nil, nil, err
}
if len(unHitPaths) > 0 {
revs2, err := GetLastCommitForPaths(ctx, commit.repo.LastCommitCache, c, treePath, unHitPaths)
revs2, err := GetLastCommitForPaths(ctx, gitRepo, commit, treePath, unHitPaths)
if err != nil {
return nil, nil, err
}
@@ -51,13 +42,13 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
maps.Copy(revs, revs2)
}
} else {
revs, err = GetLastCommitForPaths(ctx, nil, c, treePath, entryPaths)
revs, err = GetLastCommitForPaths(ctx, gitRepo, commit, treePath, entryPaths)
}
if err != nil {
return nil, nil, err
}
commit.repo.gogitStorage.Close()
gitRepo.gogitStorage.Close()
commitsInfo := make([]CommitInfo, len(tes))
for i, entry := range tes {
@@ -72,7 +63,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
// If the entry is a submodule, add a submodule file for this
if entry.IsSubModule() {
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(repoLink, path.Join(treePath, entry.Name()), commit, entry.ID)
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(ctx, repoLink, path.Join(treePath, entry.Name()), gitRepo, commit, entry.ID)
if err != nil {
return nil, nil, err
}
@@ -83,11 +74,10 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
// get it for free during the tree traversal and it's used for listing
// pages to display information about newest commit for a given path.
var treeCommit *Commit
var ok bool
if treePath == "" {
treeCommit = commit
} else if treeCommit, ok = revs[""]; ok {
treeCommit.repo = commit.repo
} else {
treeCommit = revs[""]
}
return commitsInfo, treeCommit, nil
}
@@ -162,7 +152,20 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac
}
// GetLastCommitForPaths returns last commit information
func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, c cgobject.CommitNode, treePath string, paths []string) (map[string]*Commit, error) {
func GetLastCommitForPaths(ctx context.Context, gitRepo *Repository, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) {
commitNodeIndex, commitGraphFile := gitRepo.CommitNodeIndex()
if commitGraphFile != nil {
defer commitGraphFile.Close()
}
c, err := commitNodeIndex.Get(plumbing.Hash(commit.ID.RawValue()))
if err != nil {
return nil, err
}
return getLastCommitForPathsByCommitNode(ctx, gitRepo, c, treePath, paths)
}
func getLastCommitForPathsByCommitNode(ctx context.Context, gitRepo *Repository, c cgobject.CommitNode, treePath string, paths []string) (map[string]*Commit, error) {
refSha := c.ID().String()
// We do a tree traversal with nodes sorted by commit time
@@ -243,7 +246,7 @@ heaploop:
// match any of the hashes being merged. This is more common for directories,
// but it can also happen if a file is changed through conflict resolution.
resultNodes[pth] = current.commit
if err := cache.Put(refSha, path.Join(treePath, pth), current.commit.ID().String()); err != nil {
if err := gitRepo.LastCommitCache.Put(refSha, path.Join(treePath, pth), current.commit.ID().String()); err != nil {
return nil, err
}
}
+11 -12
View File
@@ -15,7 +15,7 @@ import (
)
// GetCommitsInfo gets information of all commits that are corresponding to these entries
func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, gitRepo *Repository, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
entryPaths := make([]string, len(tes)+1)
// Get the commit for the treePath itself
entryPaths[0] = ""
@@ -26,15 +26,15 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
var err error
var revs map[string]*Commit
if commit.repo.LastCommitCache != nil {
if gitRepo.LastCommitCache != nil {
var unHitPaths []string
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, gitRepo.LastCommitCache)
if err != nil {
return nil, nil, err
}
if len(unHitPaths) > 0 {
sort.Strings(unHitPaths)
commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths)
commits, err := GetLastCommitForPaths(ctx, gitRepo, commit, treePath, unHitPaths)
if err != nil {
return nil, nil, err
}
@@ -43,7 +43,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
}
} else {
sort.Strings(entryPaths)
revs, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
revs, err = GetLastCommitForPaths(ctx, gitRepo, commit, treePath, entryPaths)
}
if err != nil {
return nil, nil, err
@@ -64,7 +64,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
// If the entry is a submodule, add a submodule file for this
if entry.IsSubModule() {
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(repoLink, path.Join(treePath, entry.Name()), commit, entry.ID)
commitsInfo[i].SubmoduleFile, err = GetCommitInfoSubmoduleFile(ctx, repoLink, path.Join(treePath, entry.Name()), gitRepo, commit, entry.ID)
if err != nil {
return nil, nil, err
}
@@ -75,11 +75,10 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
// get it for free during the tree traversal, and it's used for listing
// pages to display information about the newest commit for a given path.
var treeCommit *Commit
var ok bool
if treePath == "" {
treeCommit = commit
} else if treeCommit, ok = revs[""]; ok {
treeCommit.repo = commit.repo
} else {
treeCommit = revs[""]
}
return commitsInfo, treeCommit, nil
}
@@ -104,9 +103,9 @@ func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cac
}
// GetLastCommitForPaths returns last commit information
func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) {
func GetLastCommitForPaths(ctx context.Context, gitRepo *Repository, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) {
// We read backwards from the commit to obtain all of the commits
revs, err := walkGitLog(ctx, commit.repo, commit, treePath, paths...)
revs, err := walkGitLog(ctx, gitRepo, commit, treePath, paths...)
if err != nil {
return nil, err
}
@@ -126,7 +125,7 @@ func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string,
continue
}
c, err := commit.repo.GetCommit(commitID) // Ensure the commit exists in the repository
c, err := gitRepo.GetCommit(commitID) // Ensure the commit exists in the repository
if err != nil {
return nil, err
}
+3 -3
View File
@@ -24,7 +24,7 @@ func TestEntries_GetCommitsInfo_ContextErr(t *testing.T) {
commit, err := repo.GetCommit("feaf4ba6bc635fec442f46ddd4512416ec43c2c2")
require.NoError(t, err)
entries, err := commit.Tree.ListEntries()
entries, err := commit.Tree().ListEntries(t.Context(), repo)
require.NoError(t, err)
countCommitInfosCommit := func(infos []CommitInfo) (nilCommits, nonNilCommits int) {
@@ -39,14 +39,14 @@ func TestEntries_GetCommitsInfo_ContextErr(t *testing.T) {
defer test.MockVariableValue(&walkGitLogDebugBeforeNext)()
walkGitLogDebugBeforeNext = cancel
commitInfos, _, err := entries.GetCommitsInfo(ctx, "/any/repo-link", commit, "")
commitInfos, _, err := entries.GetCommitsInfo(ctx, "/any/repo-link", repo, commit, "")
assert.NoError(t, err)
nilCommits, nonNilCommits := countCommitInfosCommit(commitInfos)
assert.Equal(t, 0, nonNilCommits) // no commit info due to canceled (or deadline-exceeded) context
assert.Equal(t, 3, nilCommits)
walkGitLogDebugBeforeNext = nil
commitInfos, _, err = entries.GetCommitsInfo(t.Context(), "/any/repo-link", commit, "")
commitInfos, _, err = entries.GetCommitsInfo(t.Context(), "/any/repo-link", repo, commit, "")
assert.NoError(t, err)
nilCommits, nonNilCommits = countCommitInfosCommit(commitInfos)
assert.Equal(t, 3, nonNilCommits)
+7 -58
View File
@@ -91,10 +91,9 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
continue
}
assert.NotNil(t, commit)
assert.NotNil(t, commit.Tree)
assert.NotNil(t, commit.Tree.repo)
assert.NotNil(t, commit.TreeID)
tree, err := commit.Tree.SubTree(testCase.Path)
tree, err := commit.SubTree(t.Context(), repo1, testCase.Path)
if err != nil {
assert.NoError(t, err, "Unable to get subtree: %s of commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
@@ -102,9 +101,8 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
}
assert.NotNil(t, tree, "tree is nil for testCase CommitID %s in Path %s", testCase.CommitID, testCase.Path)
assert.NotNil(t, tree.repo, "repo is nil for testCase CommitID %s in Path %s", testCase.CommitID, testCase.Path)
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(t.Context(), repo1)
if err != nil {
assert.NoError(t, err, "Unable to get entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
@@ -112,7 +110,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
}
// FIXME: Context.TODO() - if graceful has started we should use its Shutdown context otherwise use install signals in TestMain.
commitsInfo, treeCommit, err := entries.GetCommitsInfo(t.Context(), "/any/repo-link", commit, testCase.Path)
commitsInfo, treeCommit, err := entries.GetCommitsInfo(t.Context(), "/any/repo-link", repo1, commit, testCase.Path)
assert.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
if err != nil {
t.FailNow()
@@ -127,7 +125,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
continue
}
assert.Equal(t, expectedInfo.CommitID, commit.ID.String())
assert.Equal(t, expectedInfo.Size, entry.Size(), entry.Name())
assert.Equal(t, expectedInfo.Size, entry.GetSize(t.Context(), repo1), entry.Name())
}
}
}
@@ -155,9 +153,9 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
t.Run("NonExistingSubmoduleAsNil", func(t *testing.T) {
commit, err := bareRepo1.GetCommit("HEAD")
require.NoError(t, err)
treeEntry, err := commit.GetTreeEntryByPath("file1.txt")
treeEntry, err := commit.GetTreeEntryByPath(t.Context(), bareRepo1, "file1.txt")
require.NoError(t, err)
cisf, err := GetCommitInfoSubmoduleFile("/any/repo-link", "file1.txt", commit, treeEntry.ID)
cisf, err := GetCommitInfoSubmoduleFile(t.Context(), "/any/repo-link", "file1.txt", bareRepo1, commit, treeEntry.ID)
require.NoError(t, err)
assert.Equal(t, &CommitSubmoduleFile{
repoLink: "/any/repo-link",
@@ -169,52 +167,3 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
assert.Nil(t, cisf.SubmoduleWebLinkTree(t.Context()))
})
}
func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
type benchmarkType struct {
url string
name string
}
benchmarks := []benchmarkType{
{url: "https://github.com/go-gitea/gitea.git", name: "gitea"},
{url: "https://github.com/ethantkoenig/manyfiles.git", name: "manyfiles"},
{url: "https://github.com/moby/moby.git", name: "moby"},
{url: "https://github.com/golang/go.git", name: "go"},
{url: "https://github.com/torvalds/linux.git", name: "linux"},
}
doBenchmark := func(benchmark benchmarkType) {
var commit *Commit
var entries Entries
var repo *Repository
repoPath, err := cloneRepo(b, benchmark.url)
if err != nil {
b.Fatal(err)
}
if repo, err = OpenRepository(b.Context(), repoPath); err != nil {
b.Fatal(err)
}
defer repo.Close()
if commit, err = repo.GetBranchCommit("master"); err != nil {
b.Fatal(err)
} else if entries, err = commit.Tree.ListEntries(); err != nil {
b.Fatal(err)
}
b.ResetTimer()
b.Run(benchmark.name, func(b *testing.B) {
for b.Loop() {
_, _, err := entries.GetCommitsInfo(b.Context(), "/any/repo-link", commit, "")
if err != nil {
b.Fatal(err)
}
}
})
}
for _, benchmark := range benchmarks {
doBenchmark(benchmark)
}
}
+4 -4
View File
@@ -15,7 +15,7 @@ const (
commitHeaderGpgsigSha256 = "gpgsig-sha256"
)
func assignCommitFields(gitRepo *Repository, commit *Commit, headerKey string, headerValue []byte) error {
func assignCommitFields(commit *Commit, headerKey string, headerValue []byte) error {
if len(headerValue) > 0 && headerValue[len(headerValue)-1] == '\n' {
headerValue = headerValue[:len(headerValue)-1] // remove trailing newline
}
@@ -25,7 +25,7 @@ func assignCommitFields(gitRepo *Repository, commit *Commit, headerKey string, h
if err != nil {
return fmt.Errorf("invalid tree ID %q: %w", string(headerValue), err)
}
commit.Tree = *NewTree(gitRepo, objID)
commit.TreeID = objID
case "parent":
objID, err := NewIDFromString(string(headerValue))
if err != nil {
@@ -48,7 +48,7 @@ func assignCommitFields(gitRepo *Repository, commit *Commit, headerKey string, h
// We need this to interpret commits from cat-file or cat-file --batch
//
// If used as part of a cat-file --batch stream you need to limit the reader to the correct size
func CommitFromReader(gitRepo *Repository, objectID ObjectID, reader io.Reader) (*Commit, error) {
func CommitFromReader(objectID ObjectID, reader io.Reader) (*Commit, error) {
commit := &Commit{
ID: objectID,
Author: &Signature{},
@@ -74,7 +74,7 @@ func CommitFromReader(gitRepo *Repository, objectID ObjectID, reader io.Reader)
k, v, _ := bytes.Cut(line, []byte{' '})
if len(k) != 0 || !inHeader {
if headerKey != "" {
if err = assignCommitFields(gitRepo, commit, headerKey, headerValue); err != nil {
if err = assignCommitFields(commit, headerKey, headerValue); err != nil {
return nil, fmt.Errorf("unable to parse commit %q: %w", objectID.String(), err)
}
}
+5 -5
View File
@@ -65,7 +65,7 @@ signed commit`
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
commitFromReader, err := CommitFromReader(sha, strings.NewReader(commitString))
assert.NoError(t, err)
require.NotNil(t, commitFromReader)
assert.EqualValues(t, sha, commitFromReader.ID)
@@ -93,7 +93,7 @@ committer Adam Majer <amajer@suse.de> 1698676906 +0100
signed commit`, commitFromReader.Signature.Payload)
assert.Equal(t, "Adam Majer <amajer@suse.de>", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
commitFromReader2, err := CommitFromReader(sha, strings.NewReader(commitString+"\n\n"))
assert.NoError(t, err)
commitFromReader.CommitMessage.MessageRaw += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
@@ -118,15 +118,15 @@ func TestHasPreviousCommitSha256(t *testing.T) {
assert.Equal(t, objectFormat, parentSHA.Type())
assert.Equal(t, "sha256", objectFormat.Name())
haz, err := commit.HasPreviousCommit(parentSHA)
haz, err := commit.HasPreviousCommit(t.Context(), repo, parentSHA)
assert.NoError(t, err)
assert.True(t, haz)
hazNot, err := commit.HasPreviousCommit(notParentSHA)
hazNot, err := commit.HasPreviousCommit(t.Context(), repo, notParentSHA)
assert.NoError(t, err)
assert.False(t, hazNot)
selfNot, err := commit.HasPreviousCommit(commit.ID)
selfNot, err := commit.HasPreviousCommit(t.Context(), repo, commit.ID)
assert.NoError(t, err)
assert.False(t, selfNot)
}
+7 -5
View File
@@ -3,17 +3,19 @@
package git
import "context"
type SubmoduleWebLink struct {
RepoWebLink, CommitWebLink string
}
// GetSubModules get all the submodules of current revision git tree
func (c *Commit) GetSubModules() (*ObjectCache[*SubModule], error) {
func (c *Commit) GetSubModules(ctx context.Context, gitRepo *Repository) (*ObjectCache[*SubModule], error) {
if c.submoduleCache != nil {
return c.submoduleCache, nil
}
entry, err := c.GetTreeEntryByPath(".gitmodules")
entry, err := c.GetTreeEntryByPath(ctx, gitRepo, ".gitmodules")
if err != nil {
if _, ok := err.(ErrNotExist); ok {
return nil, nil //nolint:nilnil // return nil to indicate that the submodule does not exist
@@ -21,7 +23,7 @@ func (c *Commit) GetSubModules() (*ObjectCache[*SubModule], error) {
return nil, err
}
rd, err := entry.Blob().DataAsync()
rd, err := entry.Blob(gitRepo).DataAsync()
if err != nil {
return nil, err
}
@@ -37,8 +39,8 @@ func (c *Commit) GetSubModules() (*ObjectCache[*SubModule], error) {
// GetSubModule gets the submodule by the entry name.
// It returns "nil, nil" if the submodule does not exist, caller should always remember to check the "nil"
func (c *Commit) GetSubModule(entryName string) (*SubModule, error) {
modules, err := c.GetSubModules()
func (c *Commit) GetSubModule(ctx context.Context, gitRepo *Repository, entryName string) (*SubModule, error) {
modules, err := c.GetSubModules(ctx, gitRepo)
if err != nil {
return nil, err
}
+7 -7
View File
@@ -61,7 +61,7 @@ empty commit`
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
commitFromReader, err := CommitFromReader(sha, strings.NewReader(commitString))
assert.NoError(t, err)
require.NotNil(t, commitFromReader)
assert.EqualValues(t, sha, commitFromReader.ID)
@@ -89,7 +89,7 @@ committer silverwind <me@silverwind.io> 1563741793 +0200
empty commit`, commitFromReader.Signature.Payload)
assert.Equal(t, "silverwind <me@silverwind.io>", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
commitFromReader2, err := CommitFromReader(sha, strings.NewReader(commitString+"\n\n"))
assert.NoError(t, err)
commitFromReader.CommitMessage.MessageRaw += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
@@ -125,7 +125,7 @@ ISO-8859-1`
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
commitFromReader, err := CommitFromReader(sha, strings.NewReader(commitString))
assert.NoError(t, err)
require.NotNil(t, commitFromReader)
assert.EqualValues(t, sha, commitFromReader.ID)
@@ -152,7 +152,7 @@ encoding ISO-8859-1
ISO-8859-1`, commitFromReader.Signature.Payload)
assert.Equal(t, "KN4CK3R <admin@oldschoolhack.me>", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
commitFromReader2, err := CommitFromReader(sha, strings.NewReader(commitString+"\n\n"))
assert.NoError(t, err)
commitFromReader.CommitMessage.MessageRaw += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
@@ -172,15 +172,15 @@ func TestHasPreviousCommit(t *testing.T) {
parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2")
notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3")
haz, err := commit.HasPreviousCommit(parentSHA)
haz, err := commit.HasPreviousCommit(t.Context(), repo, parentSHA)
assert.NoError(t, err)
assert.True(t, haz)
hazNot, err := commit.HasPreviousCommit(notParentSHA)
hazNot, err := commit.HasPreviousCommit(t.Context(), repo, notParentSHA)
assert.NoError(t, err)
assert.False(t, hazNot)
selfNot, err := commit.HasPreviousCommit(commit.ID)
selfNot, err := commit.HasPreviousCommit(t.Context(), repo, commit.ID)
assert.NoError(t, err)
assert.False(t, selfNot)
}
+2 -2
View File
@@ -75,7 +75,7 @@ func getRepoRawDiffForFileCmd(_ context.Context, repo *Repository, startCommit,
} else if commit.ParentCount() == 0 {
cmd.AddArguments("show").AddDynamicArguments(endCommit).AddDashesAndList(files...)
} else {
c, err := commit.Parent(0)
c, err := commit.Parent(repo, 0)
if err != nil {
return nil, err
}
@@ -90,7 +90,7 @@ func getRepoRawDiffForFileCmd(_ context.Context, repo *Repository, startCommit,
} else if commit.ParentCount() == 0 {
cmd.AddArguments("format-patch", "--no-signature", "--stdout", "--root").AddDynamicArguments(endCommit).AddDashesAndList(files...)
} else {
c, err := commit.Parent(0)
c, err := commit.Parent(repo, 0)
if err != nil {
return nil, err
}
@@ -7,6 +7,7 @@ package languagestats
import (
"bytes"
"context"
"io"
"gitea.dev/modules/analyze"
@@ -21,7 +22,7 @@ import (
)
// GetLanguageStats calculates language stats for git repository at specified commit
func GetLanguageStats(repo *git_module.Repository, commitID string) (map[string]int64, error) {
func GetLanguageStats(_ context.Context, repo *git_module.Repository, commitID string) (map[string]int64, error) {
r, err := git.PlainOpen(repo.Path)
if err != nil {
return nil, err
@@ -7,6 +7,7 @@ package languagestats
import (
"bytes"
"context"
"io"
"gitea.dev/modules/analyze"
@@ -19,10 +20,10 @@ import (
)
// GetLanguageStats calculates language stats for git repository at specified commit
func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64, error) {
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(repo.Ctx)
batch, cancel, err := repo.CatFileBatch(ctx)
if err != nil {
return nil, err
}
@@ -43,7 +44,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
return nil, git.ErrNotExist{ID: commitID}
}
commit, err := git.CommitFromReader(repo, sha, io.LimitReader(batchReader, commitInfo.Size))
commit, err := git.CommitFromReader(sha, io.LimitReader(batchReader, commitInfo.Size))
if err != nil {
log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
return nil, err
@@ -52,9 +53,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
return nil, err
}
tree := commit.Tree
entries, err := tree.ListEntriesRecursiveWithSize()
entries, err := commit.Tree().ListEntriesRecursiveWithSize(ctx, repo)
if err != nil {
return nil, err
}
@@ -81,13 +80,15 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
select {
case <-repo.Ctx.Done():
return sizes, repo.Ctx.Err()
case <-ctx.Done():
return sizes, ctx.Err()
default:
}
contentBuf.Reset()
content = contentBuf.Bytes()
if f.Size() == 0 {
if f.GetSize(ctx, repo) == 0 {
continue
}
@@ -124,7 +125,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
}
// this language will always be added to the size
sizes[language] += f.Size()
sizes[language] += f.GetSize(ctx, repo)
continue
}
}
@@ -138,7 +139,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
// If content can not be read or file is too big just do detection by filename
if f.Size() <= bigFileSize {
if f.GetSize(ctx, repo) <= bigFileSize {
info, _, err := batch.QueryContent(f.ID.String())
if err != nil {
return nil, err
@@ -192,10 +193,10 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
includedLanguage[language] = included
}
if included || isDetectable.ValueOrDefault(false) {
sizes[language] += f.Size()
sizes[language] += f.GetSize(ctx, repo)
} else if len(sizes) == 0 && (firstExcludedLanguage == "" || firstExcludedLanguage == language) {
firstExcludedLanguage = language
firstExcludedLanguageSize += f.Size()
firstExcludedLanguageSize += f.GetSize(ctx, repo)
}
}
@@ -22,7 +22,7 @@ func TestRepository_GetLanguageStats(t *testing.T) {
require.NoError(t, err)
defer gitRepo.Close()
stats, err := GetLanguageStats(gitRepo, "8fee858da5796dfb37704761701bb8e800ad9ef3")
stats, err := GetLanguageStats(t.Context(), gitRepo, "8fee858da5796dfb37704761701bb8e800ad9ef3")
require.NoError(t, err)
assert.Equal(t, map[string]int64{
+9 -9
View File
@@ -13,26 +13,26 @@ import (
)
// CacheCommit will cache the commit from the gitRepository
func (c *Commit) CacheCommit(ctx context.Context) error {
if c.repo.LastCommitCache == nil {
func (c *Commit) CacheCommit(ctx context.Context, gitRepo *Repository) error {
if gitRepo.LastCommitCache == nil {
return nil
}
commitNodeIndex, _ := c.repo.CommitNodeIndex()
commitNodeIndex, _ := gitRepo.CommitNodeIndex()
index, err := commitNodeIndex.Get(plumbing.Hash(c.ID.RawValue()))
if err != nil {
return err
}
return c.recursiveCache(ctx, index, &c.Tree, "", 1)
return c.recursiveCache(ctx, gitRepo, index, c.Tree(), "", 1)
}
func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
func (c *Commit) recursiveCache(ctx context.Context, gitRepo *Repository, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
if level == 0 {
return nil
}
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
return err
}
@@ -44,18 +44,18 @@ func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode,
entryMap[entry.Name()] = entry
}
commits, err := GetLastCommitForPaths(ctx, c.repo.LastCommitCache, index, treePath, entryPaths)
commits, err := getLastCommitForPathsByCommitNode(ctx, gitRepo, index, treePath, entryPaths)
if err != nil {
return err
}
for entry := range commits {
if entryMap[entry].IsDir() {
subTree, err := tree.SubTree(entry)
subTree, err := tree.SubTree(ctx, gitRepo, entry)
if err != nil {
return err
}
if err := c.recursiveCache(ctx, index, subTree, entry, level-1); err != nil {
if err := c.recursiveCache(ctx, gitRepo, index, subTree, entry, level-1); err != nil {
return err
}
}
+8 -9
View File
@@ -10,19 +10,18 @@ import (
)
// CacheCommit will cache the commit from the gitRepository
func (c *Commit) CacheCommit(ctx context.Context) error {
if c.repo.LastCommitCache == nil {
func (c *Commit) CacheCommit(ctx context.Context, gitRepo *Repository) error {
if gitRepo.LastCommitCache == nil {
return nil
}
return c.recursiveCache(ctx, &c.Tree, "", 1)
return c.recursiveCache(ctx, gitRepo, c.Tree(), "", 1)
}
func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string, level int) error {
func (c *Commit) recursiveCache(ctx context.Context, gitRepo *Repository, tree *Tree, treePath string, level int) error {
if level == 0 {
return nil
}
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
return err
}
@@ -32,7 +31,7 @@ func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string
entryPaths[i] = entry.Name()
}
_, err = walkGitLog(ctx, c.repo, c, treePath, entryPaths...)
_, err = walkGitLog(ctx, gitRepo, c, treePath, entryPaths...)
if err != nil {
return err
}
@@ -40,11 +39,11 @@ func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string
for _, treeEntry := range entries {
// entryMap won't contain "" therefore skip this.
if treeEntry.IsDir() {
subTree, err := tree.SubTree(treeEntry.Name())
subTree, err := tree.SubTree(ctx, gitRepo, treeEntry.Name())
if err != nil {
return err
}
if err := c.recursiveCache(ctx, subTree, treeEntry.Name(), level-1); err != nil {
if err := c.recursiveCache(ctx, gitRepo, subTree, treeEntry.Name(), level-1); err != nil {
return err
}
}
+2 -3
View File
@@ -263,13 +263,12 @@ var walkGitLogDebugBeforeNext func() // is used to simulate various edge git pro
// walkGitLog walks the git log --name-status for the head commit in the provided treepath and files
func walkGitLog(ctx context.Context, repo *Repository, head *Commit, treepath string, paths ...string) (map[string]string, error) {
headRef := head.ID.String()
tree, err := head.SubTree(treepath)
tree, err := head.SubTree(ctx, repo, treepath)
if err != nil {
return nil, err
}
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, repo)
if err != nil {
return nil, err
}
+85
View File
@@ -3,6 +3,14 @@
package git
import (
"context"
"io"
"strings"
"gitea.dev/modules/log"
)
// NotesRef is the git ref where Gitea will look for git-notes data.
// The value ("refs/notes/commits") is the default ref used by git-notes.
const NotesRef = "refs/notes/commits"
@@ -12,3 +20,80 @@ type Note struct {
Message []byte
Commit *Commit
}
// GetNote retrieves the git-notes data for a given commit.
// FIXME: Add LastCommitCache support
func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
notes, err := repo.GetCommit(NotesRef)
if err != nil {
if IsErrNotExist(err) {
return err
}
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
return err
}
path := ""
tree := notes.Tree()
log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)
var entry *TreeEntry
originalCommitID := commitID
for len(commitID) > 2 {
entry, err = tree.GetTreeEntryByPath(ctx, repo, commitID)
if err == nil {
path += commitID
break
}
if IsErrNotExist(err) {
tree, err = tree.SubTree(ctx, repo, commitID[0:2])
path += commitID[0:2] + "/"
commitID = commitID[2:]
}
if err != nil {
// Err may have been updated by the SubTree we need to recheck if it's again an ErrNotExist
if !IsErrNotExist(err) {
log.Error("Unable to find git note corresponding to the commit %q. Error: %v", originalCommitID, err)
}
return err
}
}
blob := entry.Blob(repo)
dataRc, err := blob.DataAsync()
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
closed := false
defer func() {
if !closed {
_ = dataRc.Close()
}
}()
d, err := io.ReadAll(dataRc)
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
_ = dataRc.Close()
closed = true
note.Message = d
treePath := ""
if idx := strings.LastIndex(path, "/"); idx > -1 {
treePath = path[:idx]
path = path[idx+1:]
}
lastCommits, err := GetLastCommitForPaths(ctx, repo, notes, treePath, []string{path})
if err != nil {
log.Error("Unable to get the commit for the path %q. Error: %v", treePath, err)
return err
}
note.Commit = lastCommits[path]
return nil
}
-95
View File
@@ -1,95 +0,0 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build gogit
package git
import (
"context"
"fmt"
"io"
"strings"
"gitea.dev/modules/log"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
// GetNote retrieves the git-notes data for a given commit.
// FIXME: Add LastCommitCache support
func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
notes, err := repo.GetCommit(NotesRef)
if err != nil {
if IsErrNotExist(err) {
return err
}
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
return err
}
remainingCommitID := commitID
var path strings.Builder
currentTree, err := notes.Tree.gogitTreeObject()
if err != nil {
return fmt.Errorf("unable to get tree object for notes commit %q: %w", notes.ID.String(), err)
}
log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", currentTree.Entries[0].Name, commitID)
var file *object.File
for len(remainingCommitID) > 2 {
file, err = currentTree.File(remainingCommitID)
if err == nil {
path.WriteString(remainingCommitID)
break
}
if err == object.ErrFileNotFound {
currentTree, err = currentTree.Tree(remainingCommitID[0:2])
path.WriteString(remainingCommitID[0:2] + "/")
remainingCommitID = remainingCommitID[2:]
}
if err != nil {
if err == object.ErrDirectoryNotFound {
return ErrNotExist{ID: remainingCommitID, RelPath: path.String()}
}
log.Error("Unable to find git note corresponding to the commit %q. Error: %v", commitID, err)
return err
}
}
blob := file.Blob
dataRc, err := blob.Reader()
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
defer dataRc.Close()
d, err := io.ReadAll(dataRc)
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
note.Message = d
commitNodeIndex, commitGraphFile := repo.CommitNodeIndex()
if commitGraphFile != nil {
defer commitGraphFile.Close()
}
commitNode, err := commitNodeIndex.Get(plumbing.Hash(notes.ID.RawValue()))
if err != nil {
return err
}
lastCommits, err := GetLastCommitForPaths(ctx, nil, commitNode, "", []string{path.String()})
if err != nil {
log.Error("Unable to get the commit for the path %q. Error: %v", path.String(), err)
return err
}
note.Commit = lastCommits[path.String()]
return nil
}
-91
View File
@@ -1,91 +0,0 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
//go:build !gogit
package git
import (
"context"
"io"
"strings"
"gitea.dev/modules/log"
)
// GetNote retrieves the git-notes data for a given commit.
// FIXME: Add LastCommitCache support
func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
notes, err := repo.GetCommit(NotesRef)
if err != nil {
if IsErrNotExist(err) {
return err
}
log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
return err
}
path := ""
tree := &notes.Tree
log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)
var entry *TreeEntry
originalCommitID := commitID
for len(commitID) > 2 {
entry, err = tree.GetTreeEntryByPath(commitID)
if err == nil {
path += commitID
break
}
if IsErrNotExist(err) {
tree, err = tree.SubTree(commitID[0:2])
path += commitID[0:2] + "/"
commitID = commitID[2:]
}
if err != nil {
// Err may have been updated by the SubTree we need to recheck if it's again an ErrNotExist
if !IsErrNotExist(err) {
log.Error("Unable to find git note corresponding to the commit %q. Error: %v", originalCommitID, err)
}
return err
}
}
blob := entry.Blob()
dataRc, err := blob.DataAsync()
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
closed := false
defer func() {
if !closed {
_ = dataRc.Close()
}
}()
d, err := io.ReadAll(dataRc)
if err != nil {
log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
return err
}
_ = dataRc.Close()
closed = true
note.Message = d
treePath := ""
if idx := strings.LastIndex(path, "/"); idx > -1 {
treePath = path[:idx]
path = path[idx+1:]
}
lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
if err != nil {
log.Error("Unable to get the commit for the path %q. Error: %v", treePath, err)
return err
}
note.Commit = lastCommits[path]
return nil
}
+2 -2
View File
@@ -72,7 +72,7 @@ func findLFSFileFunc(repo *git.Repository, objectID git.ObjectID, revListReader
continue
case "commit":
// Read in the commit to get its tree and in case this is one of the last used commits
curCommit, err = git.CommitFromReader(repo, git.MustIDFromString(commitID), io.LimitReader(batchReader, info.Size))
curCommit, err = git.CommitFromReader(git.MustIDFromString(commitID), io.LimitReader(batchReader, info.Size))
if err != nil {
return nil, err
}
@@ -80,7 +80,7 @@ func findLFSFileFunc(repo *git.Repository, objectID git.ObjectID, revListReader
return nil, err
}
if info, _, err = batch.QueryContent(curCommit.Tree.ID.String()); err != nil {
if info, _, err = batch.QueryContent(curCommit.TreeID.String()); err != nil {
return nil, err
}
curPath = ""
+2 -3
View File
@@ -92,15 +92,14 @@ func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
}
commit := convertCommit(gogitCommit)
commit.repo = repo
tree, err := gogitCommit.Tree()
if err != nil {
return nil, err
}
commit.Tree.ID = ParseGogitHash(tree.Hash)
commit.Tree.resolvedGogitTreeObject = tree
commit.TreeID = ParseGogitHash(tree.Hash)
commit.Tree().resolvedGogitTreeObject = tree
return commit, nil
}
+1 -1
View File
@@ -88,7 +88,7 @@ func (repo *Repository) getCommitWithBatch(batch CatFileBatch, id ObjectID) (*Co
}
return repo.getCommitWithBatch(batch, tag.Object)
case "commit":
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, info.Size))
commit, err := CommitFromReader(id, io.LimitReader(rd, info.Size))
if err != nil {
return nil, err
}
+1 -1
View File
@@ -149,5 +149,5 @@ func (repo *Repository) WriteTree() (*Tree, error) {
if err != nil {
return nil, err
}
return NewTree(repo, id), nil
return newTree(id), nil
}
+1 -3
View File
@@ -25,7 +25,7 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
return nil, err
}
tree := NewTree(repo, id)
tree := newTree(id)
tree.resolvedGogitTreeObject = gogitTree
return tree, nil
}
@@ -53,7 +53,6 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) {
if err != nil {
return nil, err
}
resolvedID := id
commitObject, err := repo.gogitRepo.CommitObject(plumbing.Hash(id.RawValue()))
if err == nil {
id = ParseGogitHash(commitObject.TreeHash)
@@ -62,6 +61,5 @@ func (repo *Repository) GetTree(idStr string) (*Tree, error) {
if err != nil {
return nil, err
}
treeObject.ResolvedID = resolvedID
return treeObject, nil
}
+6 -8
View File
@@ -23,7 +23,6 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
switch info.Type {
case "tag":
resolvedID := id
data, err := io.ReadAll(io.LimitReader(rd, info.Size))
if err != nil {
return nil, err
@@ -37,21 +36,20 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
if err != nil {
return nil, err
}
commit.Tree.ResolvedID = resolvedID
return &commit.Tree, nil
tree := commit.Tree()
return tree, nil
case "commit":
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, info.Size))
commit, err := CommitFromReader(id, io.LimitReader(rd, info.Size))
if err != nil {
return nil, err
}
if _, err := rd.Discard(1); err != nil {
return nil, err
}
commit.Tree.ResolvedID = commit.ID
return &commit.Tree, nil
tree := commit.Tree()
return tree, nil
case "tree":
tree := NewTree(repo, id)
tree.ResolvedID = id
tree := newTree(id)
objectFormat, err := repo.GetObjectFormat()
if err != nil {
return nil, err
+7 -17
View File
@@ -6,31 +6,22 @@ package git
import (
"bytes"
"context"
"strings"
"gitea.dev/modules/git/gitcmd"
)
type TreeCommon struct {
ID ObjectID
ResolvedID ObjectID
repo *Repository
ptree *Tree // parent tree
ID ObjectID
}
// NewTree create a new tree according the repository and tree id
func NewTree(repo *Repository, id ObjectID) *Tree {
return &Tree{
TreeCommon: TreeCommon{
ID: id,
repo: repo,
},
}
func newTree(id ObjectID) *Tree {
return &Tree{TreeCommon: TreeCommon{ID: id}}
}
// SubTree get a subtree by the sub dir path
func (t *Tree) SubTree(rpath string) (*Tree, error) {
func (t *Tree) SubTree(ctx context.Context, gitRepo *Repository, rpath string) (*Tree, error) {
if len(rpath) == 0 {
return t, nil
}
@@ -43,16 +34,15 @@ func (t *Tree) SubTree(rpath string) (*Tree, error) {
te *TreeEntry
)
for _, name := range paths {
te, err = p.GetTreeEntryByPath(name)
te, err = p.GetTreeEntryByPath(ctx, gitRepo, name)
if err != nil {
return nil, err
}
g, err = t.repo.getTree(te.ID)
g, err = gitRepo.getTree(te.ID)
if err != nil {
return nil, err
}
g.ptree = p
p = g
}
return g, nil
+5 -3
View File
@@ -4,15 +4,17 @@
package git
import "context"
// GetBlobByPath get the blob object according the path
func (t *Tree) GetBlobByPath(relpath string) (*Blob, error) {
entry, err := t.GetTreeEntryByPath(relpath)
func (t *Tree) GetBlobByPath(ctx context.Context, gitRepo *Repository, relpath string) (*Blob, error) {
entry, err := t.GetTreeEntryByPath(ctx, gitRepo, relpath)
if err != nil {
return nil, err
}
if !entry.IsDir() && !entry.IsSubModule() {
return entry.Blob(), nil
return entry.Blob(gitRepo), nil
}
return nil, ErrNotExist{"", relpath}
+4 -3
View File
@@ -7,6 +7,7 @@
package git
import (
"context"
"path"
"strings"
@@ -14,7 +15,7 @@ import (
)
// GetTreeEntryByPath get the tree entries according the sub dir
func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
func (t *Tree) GetTreeEntryByPath(ctx context.Context, gitRepo *Repository, relpath string) (*TreeEntry, error) {
if len(relpath) == 0 {
return &TreeEntry{
ID: t.ID,
@@ -30,7 +31,7 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
tree := t
for i, name := range parts {
if i == len(parts)-1 {
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
if err == plumbing.ErrObjectNotFound {
return nil, ErrNotExist{
@@ -45,7 +46,7 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
}
}
} else {
tree, err = tree.SubTree(name)
tree, err = tree.SubTree(ctx, gitRepo, name)
if err != nil {
if err == plumbing.ErrObjectNotFound {
return nil, ErrNotExist{
+4 -3
View File
@@ -6,12 +6,13 @@
package git
import (
"context"
"path"
"strings"
)
// GetTreeEntryByPath get the tree entries according the sub dir
func (t *Tree) GetTreeEntryByPath(relpath string) (_ *TreeEntry, err error) {
func (t *Tree) GetTreeEntryByPath(ctx context.Context, gitRepo *Repository, relpath string) (_ *TreeEntry, err error) {
if len(relpath) == 0 {
return &TreeEntry{
ptree: t,
@@ -26,14 +27,14 @@ func (t *Tree) GetTreeEntryByPath(relpath string) (_ *TreeEntry, err error) {
tree := t
for _, name := range parts[:len(parts)-1] {
tree, err = tree.SubTree(name)
tree, err = tree.SubTree(ctx, gitRepo, name)
if err != nil {
return nil, err
}
}
name := parts[len(parts)-1]
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
return nil, err
}
+13 -14
View File
@@ -5,6 +5,7 @@
package git
import (
"context"
"path"
"slices"
"strings"
@@ -78,18 +79,18 @@ type EntryFollowResult struct {
TargetEntry *TreeEntry
}
func EntryFollowLink(commit *Commit, fullPath string, te *TreeEntry) (*EntryFollowResult, error) {
func EntryFollowLink(ctx context.Context, gitRepo *Repository, commit *Commit, fullPath string, te *TreeEntry) (*EntryFollowResult, error) {
if !te.IsLink() {
return nil, util.ErrorWrap(util.ErrUnprocessableContent, "%q is not a symlink", fullPath)
}
// git's filename max length is 4096, hopefully a link won't be longer than multiple of that
const maxSymlinkSize = 20 * 4096
if te.Blob().Size() > maxSymlinkSize {
if te.Blob(gitRepo).Size() > maxSymlinkSize {
return nil, util.ErrorWrap(util.ErrUnprocessableContent, "%q content exceeds symlink limit", fullPath)
}
link, err := te.Blob().GetBlobContent(maxSymlinkSize)
link, err := te.Blob(gitRepo).GetBlobContent(maxSymlinkSize)
if err != nil {
return nil, err
}
@@ -99,18 +100,18 @@ func EntryFollowLink(commit *Commit, fullPath string, te *TreeEntry) (*EntryFoll
}
targetFullPath := path.Join(path.Dir(fullPath), link)
targetEntry, err := commit.GetTreeEntryByPath(targetFullPath)
targetEntry, err := commit.GetTreeEntryByPath(ctx, gitRepo, targetFullPath)
if err != nil {
return &EntryFollowResult{SymlinkContent: link}, err
}
return &EntryFollowResult{SymlinkContent: link, TargetFullPath: targetFullPath, TargetEntry: targetEntry}, nil
}
func EntryFollowLinks(commit *Commit, firstFullPath string, firstTreeEntry *TreeEntry, optLimit ...int) (res *EntryFollowResult, err error) {
func EntryFollowLinks(ctx context.Context, gitRepo *Repository, commit *Commit, firstFullPath string, firstTreeEntry *TreeEntry, optLimit ...int) (res *EntryFollowResult, err error) {
limit := util.OptionalArg(optLimit, 10)
treeEntry, fullPath := firstTreeEntry, firstFullPath
for range limit {
res, err = EntryFollowLink(commit, fullPath, treeEntry)
res, err = EntryFollowLink(ctx, gitRepo, commit, fullPath, treeEntry)
if err != nil {
return res, err
}
@@ -125,28 +126,26 @@ func EntryFollowLinks(commit *Commit, firstFullPath string, firstTreeEntry *Tree
return res, nil
}
// returns the Tree pointed to by this TreeEntry, or nil if this is not a tree
func (te *TreeEntry) Tree() *Tree {
t, err := te.ptree.repo.getTree(te.ID)
func (te *TreeEntry) Tree(gitRepo *Repository) *Tree {
t, err := gitRepo.getTree(te.ID)
if err != nil {
return nil
}
t.ptree = te.ptree
return t
}
// GetSubJumpablePathName return the full path of subdirectory jumpable ( contains only one directory )
func (te *TreeEntry) GetSubJumpablePathName() string {
func (te *TreeEntry) GetSubJumpablePathName(ctx context.Context, gitRepo *Repository) string {
if te.IsSubModule() || !te.IsDir() {
return ""
}
tree, err := te.ptree.SubTree(te.Name())
tree, err := te.ptree.SubTree(ctx, gitRepo, te.Name())
if err != nil {
return te.Name()
}
entries, _ := tree.ListEntries()
entries, _ := tree.ListEntries(ctx, gitRepo)
if len(entries) == 1 && entries[0].IsDir() {
name := entries[0].GetSubJumpablePathName()
name := entries[0].GetSubJumpablePathName(ctx, gitRepo)
if name != "" {
return te.Name() + "/" + name
}
+10 -10
View File
@@ -23,12 +23,12 @@ func TestFollowLink(t *testing.T) {
// get the symlink
{
lnkFullPath := "foo/bar/link_to_hello"
lnk, err := commit.Tree.GetTreeEntryByPath("foo/bar/link_to_hello")
lnk, err := commit.Tree().GetTreeEntryByPath(t.Context(), r, "foo/bar/link_to_hello")
require.NoError(t, err)
assert.True(t, lnk.IsLink())
// should be able to dereference to target
res, err := EntryFollowLink(commit, lnkFullPath, lnk)
res, err := EntryFollowLink(t.Context(), r, commit, lnkFullPath, lnk)
require.NoError(t, err)
assert.Equal(t, "hello", res.TargetEntry.Name())
assert.Equal(t, "foo/nar/hello", res.TargetFullPath)
@@ -38,38 +38,38 @@ func TestFollowLink(t *testing.T) {
{
// should error when called on a normal file
entry, err := commit.Tree.GetTreeEntryByPath("file1.txt")
entry, err := commit.Tree().GetTreeEntryByPath(t.Context(), r, "file1.txt")
require.NoError(t, err)
res, err := EntryFollowLink(commit, "file1.txt", entry)
res, err := EntryFollowLink(t.Context(), r, commit, "file1.txt", entry)
assert.ErrorIs(t, err, util.ErrUnprocessableContent)
assert.Nil(t, res)
}
{
// should error for broken links
entry, err := commit.Tree.GetTreeEntryByPath("foo/broken_link")
entry, err := commit.Tree().GetTreeEntryByPath(t.Context(), r, "foo/broken_link")
require.NoError(t, err)
assert.True(t, entry.IsLink())
res, err := EntryFollowLink(commit, "foo/broken_link", entry)
res, err := EntryFollowLink(t.Context(), r, commit, "foo/broken_link", entry)
assert.ErrorIs(t, err, util.ErrNotExist)
assert.Equal(t, "nar/broken_link", res.SymlinkContent)
}
{
// should error for external links
entry, err := commit.Tree.GetTreeEntryByPath("foo/outside_repo")
entry, err := commit.Tree().GetTreeEntryByPath(t.Context(), r, "foo/outside_repo")
require.NoError(t, err)
assert.True(t, entry.IsLink())
res, err := EntryFollowLink(commit, "foo/outside_repo", entry)
res, err := EntryFollowLink(t.Context(), r, commit, "foo/outside_repo", entry)
assert.ErrorIs(t, err, util.ErrNotExist)
assert.Equal(t, "../../outside_repo", res.SymlinkContent)
}
{
// testing fix for short link bug
entry, err := commit.Tree.GetTreeEntryByPath("foo/link_short")
entry, err := commit.Tree().GetTreeEntryByPath(t.Context(), r, "foo/link_short")
require.NoError(t, err)
res, err := EntryFollowLink(commit, "foo/link_short", entry)
res, err := EntryFollowLink(t.Context(), r, commit, "foo/link_short", entry)
assert.ErrorIs(t, err, util.ErrNotExist)
assert.Equal(t, "a", res.SymlinkContent)
}
+7 -5
View File
@@ -7,6 +7,8 @@
package git
import (
"context"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/filemode"
"github.com/go-git/go-git/v5/plumbing/object"
@@ -29,15 +31,15 @@ func (te *TreeEntry) toGogitTreeEntry() *object.TreeEntry {
}
}
// Size returns the size of the entry
func (te *TreeEntry) Size() int64 {
// GetSize returns the size of the entry
func (te *TreeEntry) GetSize(ctx context.Context, gitRepo *Repository) int64 {
if te.IsDir() {
return 0
} else if te.sized {
return te.size
}
ptreeGogitTree, err := te.ptree.gogitTreeObject()
ptreeGogitTree, err := te.ptree.gogitTreeObject(gitRepo)
if err != nil {
return 0
}
@@ -52,10 +54,10 @@ func (te *TreeEntry) Size() int64 {
}
// Blob returns the blob object the entry
func (te *TreeEntry) Blob() *Blob {
func (te *TreeEntry) Blob(gitRepo *Repository) *Blob {
return &Blob{
ID: te.ID,
repo: te.ptree.repo,
repo: gitRepo,
name: te.Name(),
}
}
+11 -8
View File
@@ -5,25 +5,28 @@
package git
import "gitea.dev/modules/log"
import (
"context"
// Size returns the size of the entry
func (te *TreeEntry) Size() int64 {
"gitea.dev/modules/log"
)
func (te *TreeEntry) GetSize(ctx context.Context, gitRepo *Repository) int64 {
if te.IsDir() {
return 0
} else if te.sized {
return te.size
}
batch, cancel, err := te.ptree.repo.CatFileBatch(te.ptree.repo.Ctx)
batch, cancel, err := gitRepo.CatFileBatch(ctx)
if err != nil {
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), gitRepo.Path, err)
return 0
}
defer cancel()
info, err := batch.QueryInfo(te.ID.String())
if err != nil {
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), gitRepo.Path, err)
return 0
}
@@ -33,12 +36,12 @@ func (te *TreeEntry) Size() int64 {
}
// Blob returns the blob object the entry
func (te *TreeEntry) Blob() *Blob {
func (te *TreeEntry) Blob(gitRepo *Repository) *Blob {
return &Blob{
ID: te.ID,
name: te.Name(),
size: te.size,
gotSize: te.sized,
repo: te.ptree.repo,
repo: gitRepo,
}
}
+9 -8
View File
@@ -7,6 +7,7 @@
package git
import (
"context"
"io"
"github.com/go-git/go-git/v5/plumbing"
@@ -20,9 +21,9 @@ type Tree struct {
resolvedGogitTreeObject *object.Tree
}
func (t *Tree) gogitTreeObject() (_ *object.Tree, err error) {
func (t *Tree) gogitTreeObject(gitRepo *Repository) (_ *object.Tree, err error) {
if t.resolvedGogitTreeObject == nil {
t.resolvedGogitTreeObject, err = t.repo.gogitRepo.TreeObject(plumbing.Hash(t.ID.RawValue()))
t.resolvedGogitTreeObject, err = gitRepo.gogitRepo.TreeObject(plumbing.Hash(t.ID.RawValue()))
if err != nil {
return nil, err
}
@@ -31,8 +32,8 @@ func (t *Tree) gogitTreeObject() (_ *object.Tree, err error) {
}
// ListEntries returns all entries of current tree.
func (t *Tree) ListEntries() (Entries, error) {
gogitTree, err := t.gogitTreeObject()
func (t *Tree) ListEntries(_ context.Context, gitRepo *Repository) (Entries, error) {
gogitTree, err := t.gogitTreeObject(gitRepo)
if err != nil {
return nil, err
}
@@ -50,8 +51,8 @@ func (t *Tree) ListEntries() (Entries, error) {
}
// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees
func (t *Tree) ListEntriesRecursiveWithSize() (entries Entries, _ error) {
gogitTree, err := t.gogitTreeObject()
func (t *Tree) ListEntriesRecursiveWithSize(_ context.Context, gitRepo *Repository) (entries Entries, _ error) {
gogitTree, err := t.gogitTreeObject(gitRepo)
if err != nil {
return nil, err
}
@@ -76,6 +77,6 @@ func (t *Tree) ListEntriesRecursiveWithSize() (entries Entries, _ error) {
}
// ListEntriesRecursiveFast is the alias of ListEntriesRecursiveWithSize for the gogit version
func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
return t.ListEntriesRecursiveWithSize()
func (t *Tree) ListEntriesRecursiveFast(ctx context.Context, gitRepo *Repository) (Entries, error) {
return t.ListEntriesRecursiveWithSize(ctx, gitRepo)
}
+38 -40
View File
@@ -6,6 +6,7 @@
package git
import (
"context"
"io"
"gitea.dev/modules/git/gitcmd"
@@ -20,49 +21,47 @@ type Tree struct {
}
// ListEntries returns all entries of current tree.
func (t *Tree) ListEntries() (Entries, error) {
func (t *Tree) ListEntries(ctx context.Context, gitRepo *Repository) (Entries, error) {
if t.entriesParsed {
return t.entries, nil
}
if t.repo != nil {
batch, cancel, err := t.repo.CatFileBatch(t.repo.Ctx)
if err != nil {
batch, cancel, err := gitRepo.CatFileBatch(ctx)
if err != nil {
return nil, err
}
defer cancel()
info, rd, err := batch.QueryContent(t.ID.String())
if err != nil {
return nil, err
}
if info.Type == "commit" {
treeID, err := ReadTreeID(rd, info.Size)
if err != nil && err != io.EOF {
return nil, err
}
defer cancel()
info, rd, err := batch.QueryContent(t.ID.String())
info, rd, err = batch.QueryContent(treeID)
if err != nil {
return nil, err
}
if info.Type == "commit" {
treeID, err := ReadTreeID(rd, info.Size)
if err != nil && err != io.EOF {
return nil, err
}
info, rd, err = batch.QueryContent(treeID)
if err != nil {
return nil, err
}
}
if info.Type == "tree" {
t.entries, err = catBatchParseTreeEntries(t.ID.Type(), t, rd, info.Size)
if err != nil {
return nil, err
}
t.entriesParsed = true
return t.entries, nil
}
// Not a tree just use ls-tree instead
if err := DiscardFull(rd, info.Size+1); err != nil {
return nil, err
}
}
if info.Type == "tree" {
t.entries, err = catBatchParseTreeEntries(t.ID.Type(), t, rd, info.Size)
if err != nil {
return nil, err
}
t.entriesParsed = true
return t.entries, nil
}
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).WithDir(t.repo.Path).RunStdBytes(t.repo.Ctx)
// Not a tree just use ls-tree instead
if err := DiscardFull(rd, info.Size+1); err != nil {
return nil, err
}
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-l").AddDynamicArguments(t.ID.String()).WithDir(gitRepo.Path).RunStdBytes(ctx)
if runErr != nil {
if gitcmd.IsStderr(runErr, gitcmd.StderrNotValidObjectName) || gitcmd.IsStderr(runErr, gitcmd.StderrNotTreeObject) {
return nil, ErrNotExist{
@@ -72,7 +71,6 @@ func (t *Tree) ListEntries() (Entries, error) {
return nil, runErr
}
var err error
t.entries, err = parseTreeEntries(stdout, t)
if err == nil {
t.entriesParsed = true
@@ -83,12 +81,12 @@ func (t *Tree) ListEntries() (Entries, error) {
// listEntriesRecursive returns all entries of current tree recursively including all subtrees
// extraArgs could be "-l" to get the size, which is slower
func (t *Tree) listEntriesRecursive(extraArgs gitcmd.TrustedCmdArgs) (Entries, error) {
func (t *Tree) listEntriesRecursive(ctx context.Context, gitRepo *Repository, extraArgs gitcmd.TrustedCmdArgs) (Entries, error) {
stdout, _, runErr := gitcmd.NewCommand("ls-tree", "-t", "-r").
AddArguments(extraArgs...).
AddDynamicArguments(t.ID.String()).
WithDir(t.repo.Path).
RunStdBytes(t.repo.Ctx)
WithDir(gitRepo.Path).
RunStdBytes(ctx)
if runErr != nil {
return nil, runErr
}
@@ -99,11 +97,11 @@ func (t *Tree) listEntriesRecursive(extraArgs gitcmd.TrustedCmdArgs) (Entries, e
}
// ListEntriesRecursiveFast returns all entries of current tree recursively including all subtrees, no size
func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
return t.listEntriesRecursive(nil)
func (t *Tree) ListEntriesRecursiveFast(ctx context.Context, gitRepo *Repository) (Entries, error) {
return t.listEntriesRecursive(ctx, gitRepo, nil)
}
// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees, with size
func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
return t.listEntriesRecursive(gitcmd.TrustedCmdArgs{"--long"})
func (t *Tree) ListEntriesRecursiveWithSize(ctx context.Context, gitRepo *Repository) (Entries, error) {
return t.listEntriesRecursive(ctx, gitRepo, gitcmd.TrustedCmdArgs{"--long"})
}
+1 -1
View File
@@ -20,7 +20,7 @@ func TestSubTree_Issue29101(t *testing.T) {
// old code could produce a different error if called multiple times
for range 10 {
_, err = commit.SubTree("file1.txt")
_, err = commit.SubTree(t.Context(), repo, "file1.txt")
assert.Error(t, err)
assert.True(t, IsErrNotExist(err))
}
+5 -5
View File
@@ -139,7 +139,7 @@ func (r *BlameReader) cleanup() {
}
// CreateBlameReader creates reader for given repository, commit and file
func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, retErr error) {
func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo Repository, gitRepo *git.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, retErr error) {
defer func() {
if retErr != nil {
rd.cleanup()
@@ -158,7 +158,7 @@ func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo
rd.cleanupFuncs = append(rd.cleanupFuncs, stdoutReaderClose)
if git.DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
ignoreRevsFileName, ignoreRevsFileCleanup, err := tryCreateBlameIgnoreRevsFile(commit)
ignoreRevsFileName, ignoreRevsFileCleanup, err := tryCreateBlameIgnoreRevsFile(ctx, gitRepo, commit)
if err != nil && !git.IsErrNotExist(err) {
return nil, err
} else if err == nil {
@@ -180,13 +180,13 @@ func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo
return rd, nil
}
func tryCreateBlameIgnoreRevsFile(commit *git.Commit) (string, func(), error) {
entry, err := commit.GetTreeEntryByPath(".git-blame-ignore-revs")
func tryCreateBlameIgnoreRevsFile(ctx context.Context, gitRepo *git.Repository, commit *git.Commit) (string, func(), error) {
entry, err := commit.GetTreeEntryByPath(ctx, gitRepo, ".git-blame-ignore-revs")
if err != nil {
return "", nil, err
}
r, err := entry.Blob().DataAsync()
r, err := entry.Blob(gitRepo).DataAsync()
if err != nil {
return "", nil, err
}
+2 -2
View File
@@ -49,7 +49,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
}
for _, bypass := range []bool{false, true} {
blameReader, err := CreateBlameReader(ctx, git.Sha256ObjectFormat, storage, commit, "README.md", bypass)
blameReader, err := CreateBlameReader(ctx, git.Sha256ObjectFormat, storage, repo, commit, "README.md", bypass)
assert.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -134,7 +134,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
for _, c := range cases {
commit, err := repo.GetCommit(c.CommitID)
assert.NoError(t, err)
blameReader, err := CreateBlameReader(ctx, objectFormat, storage, commit, "blame.txt", c.Bypass)
blameReader, err := CreateBlameReader(ctx, objectFormat, storage, repo, commit, "blame.txt", c.Bypass)
assert.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
+2 -2
View File
@@ -43,7 +43,7 @@ func TestReadingBlameOutput(t *testing.T) {
}
for _, bypass := range []bool{false, true} {
blameReader, err := CreateBlameReader(ctx, git.Sha1ObjectFormat, storage, commit, "README.md", bypass)
blameReader, err := CreateBlameReader(ctx, git.Sha1ObjectFormat, storage, repo, commit, "README.md", bypass)
assert.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -129,7 +129,7 @@ func TestReadingBlameOutput(t *testing.T) {
commit, err := repo.GetCommit(c.CommitID)
assert.NoError(t, err)
blameReader, err := CreateBlameReader(ctx, objectFormat, storage, commit, "blame.txt", c.Bypass)
blameReader, err := CreateBlameReader(ctx, objectFormat, storage, repo, commit, "blame.txt", c.Bypass)
assert.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
+10 -10
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
}
+8 -1
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 {
+1 -1
View File
@@ -63,7 +63,7 @@ func (db *DBIndexer) Index(id int64) error {
}
// Calculate and save language statistics to database
stats, err := languagestats.GetLanguageStats(gitRepo, commitID)
stats, err := languagestats.GetLanguageStats(ctx, gitRepo, commitID)
if err != nil {
if !setting.IsInTesting {
log.Error("Unable to get language stats for ID %s for default branch %s in %s. Error: %v", commitID, repo.DefaultBranch, repo.FullName(), err)
+11 -10
View File
@@ -4,6 +4,7 @@
package template
import (
"context"
"fmt"
"path"
"strconv"
@@ -41,35 +42,35 @@ func Unmarshal(filename string, content []byte) (*api.IssueTemplate, error) {
}
// UnmarshalFromEntry parses out a valid template from the blob in entry
func UnmarshalFromEntry(entry *git.TreeEntry, dir string) (*api.IssueTemplate, error) {
return unmarshalFromEntry(entry, path.Join(dir, entry.Name())) // Filepaths in Git are ALWAYS '/' separated do not use filepath here
func UnmarshalFromEntry(gitRepo *git.Repository, entry *git.TreeEntry, dir string) (*api.IssueTemplate, error) {
return unmarshalFromEntry(gitRepo, entry, path.Join(dir, entry.Name())) // Filepaths in Git are ALWAYS '/' separated do not use filepath here
}
// UnmarshalFromCommit parses out a valid template from the commit
func UnmarshalFromCommit(commit *git.Commit, filename string) (*api.IssueTemplate, error) {
entry, err := commit.GetTreeEntryByPath(filename)
func UnmarshalFromCommit(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, filename string) (*api.IssueTemplate, error) {
entry, err := commit.GetTreeEntryByPath(ctx, gitRepo, filename)
if err != nil {
return nil, fmt.Errorf("get entry for %q: %w", filename, err)
}
return unmarshalFromEntry(entry, filename)
return unmarshalFromEntry(gitRepo, entry, filename)
}
// UnmarshalFromRepo parses out a valid template from the head commit of the branch
func UnmarshalFromRepo(repo *git.Repository, branch, filename string) (*api.IssueTemplate, error) {
func UnmarshalFromRepo(ctx context.Context, repo *git.Repository, branch, filename string) (*api.IssueTemplate, error) {
commit, err := repo.GetBranchCommit(branch)
if err != nil {
return nil, fmt.Errorf("get commit on branch %q: %w", branch, err)
}
return UnmarshalFromCommit(commit, filename)
return UnmarshalFromCommit(ctx, repo, commit, filename)
}
func unmarshalFromEntry(entry *git.TreeEntry, filename string) (*api.IssueTemplate, error) {
if size := entry.Blob().Size(); size > setting.UI.MaxDisplayFileSize {
func unmarshalFromEntry(gitRepo *git.Repository, entry *git.TreeEntry, filename string) (*api.IssueTemplate, error) {
if size := entry.Blob(gitRepo).Size(); size > setting.UI.MaxDisplayFileSize {
return nil, fmt.Errorf("too large: %v > MaxDisplayFileSize", size)
}
r, err := entry.Blob().DataAsync()
r, err := entry.Blob(gitRepo).DataAsync()
if err != nil {
return nil, fmt.Errorf("data async: %w", err)
}
+1 -1
View File
@@ -235,7 +235,7 @@ func GetAllCommits(ctx *context.APIContext) {
}
// Query commits
commits, err = baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize, not, since, until)
commits, err = baseCommit.CommitsByRange(ctx.Repo.GitRepo, listOptions.Page, listOptions.PageSize, not, since, until)
if err != nil {
ctx.APIErrorInternal(err)
return
+3 -3
View File
@@ -202,7 +202,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
}
func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEntry, lastModified *time.Time) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
if git.IsErrNotExist(err) {
ctx.APIErrorNotFound()
@@ -224,7 +224,7 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn
}
when := &latestCommit.Committer.When
return entry.Blob(), entry, when
return entry.Blob(ctx.Repo.GitRepo), entry, when
}
// GetArchive get archive of a repository
@@ -299,7 +299,7 @@ func GetEditorconfig(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
ec, _, err := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
ec, _, err := ctx.Repo.GetEditorconfig(ctx, ctx.Repo.Commit)
if err != nil {
ctx.APIErrorAuto(err)
return
+3 -3
View File
@@ -1200,7 +1200,7 @@ func GetIssueTemplates(ctx *context.APIContext) {
// "$ref": "#/responses/IssueTemplates"
// "404":
// "$ref": "#/responses/notFound"
ret := issue.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
ret := issue.ParseTemplatesFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
if cnt := len(ret.TemplateErrors); cnt != 0 {
ctx.Resp.Header().Add("X-Gitea-Warning", "error occurs when parsing issue template: count="+strconv.Itoa(cnt))
}
@@ -1230,7 +1230,7 @@ func GetIssueConfig(ctx *context.APIContext) {
// "$ref": "#/responses/RepoIssueConfig"
// "404":
// "$ref": "#/responses/notFound"
issueConfig, _ := issue.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
issueConfig, _ := issue.GetTemplateConfigFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.JSON(http.StatusOK, issueConfig)
}
@@ -1257,7 +1257,7 @@ func ValidateIssueConfig(ctx *context.APIContext) {
// "$ref": "#/responses/RepoIssueConfigValidation"
// "404":
// "$ref": "#/responses/notFound"
_, err := issue.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
_, err := issue.GetTemplateConfigFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
if err == nil {
ctx.JSON(http.StatusOK, api.IssueConfigValidation{Valid: true, Message: ""})
+1 -1
View File
@@ -62,7 +62,7 @@ func GetTree(ctx *context.APIContext) {
return
}
if tree, err := files_service.GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, sha, ctx.FormInt("page"), ctx.FormInt("per_page"), ctx.FormBool("recursive")); err != nil {
ctx.APIError(http.StatusBadRequest, err.Error())
ctx.APIErrorAuto(err)
} else {
ctx.SetTotalCountHeader(int64(tree.TotalCount))
ctx.JSON(http.StatusOK, tree)
+13 -13
View File
@@ -177,17 +177,17 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi
}
// lookup filename in wiki - get filecontent, real filename
content, pageFilename := wikiContentsByName(ctx, commit, wikiName, false)
content, pageFilename := wikiContentsByName(ctx, wikiRepo, commit, wikiName, false)
if ctx.Written() {
return nil
}
sidebarContent, _ := wikiContentsByName(ctx, commit, "_Sidebar", true)
sidebarContent, _ := wikiContentsByName(ctx, wikiRepo, commit, "_Sidebar", true)
if ctx.Written() {
return nil
}
footerContent, _ := wikiContentsByName(ctx, commit, "_Footer", true)
footerContent, _ := wikiContentsByName(ctx, wikiRepo, commit, "_Footer", true)
if ctx.Written() {
return nil
}
@@ -303,7 +303,7 @@ func ListWikiPages(ctx *context.APIContext) {
skip := (page - 1) * limit
maxNum := page * limit
entries, err := commit.ListEntries()
entries, err := commit.Tree().ListEntries(ctx, wikiRepo)
if err != nil {
ctx.APIErrorInternal(err)
return
@@ -420,7 +420,7 @@ func ListPageRevisions(ctx *context.APIContext) {
}
// lookup filename in wiki - get filecontent, gitTree entry , real filename
_, pageFilename := wikiContentsByName(ctx, commit, pageName, false)
_, pageFilename := wikiContentsByName(ctx, wikiRepo, commit, pageName, false)
if ctx.Written() {
return
}
@@ -448,8 +448,8 @@ func ListPageRevisions(ctx *context.APIContext) {
}
// findEntryForFile finds the tree entry for a target filepath.
func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
entry, err := commit.GetTreeEntryByPath(target)
func findEntryForFile(ctx *context.APIContext, wikiRepo *git.Repository, commit *git.Commit, target string) (*git.TreeEntry, error) {
entry, err := commit.GetTreeEntryByPath(ctx, wikiRepo, target)
if err != nil {
return nil, err
}
@@ -462,7 +462,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
if unescapedTarget, err = url.QueryUnescape(target); err != nil {
return nil, err
}
return commit.GetTreeEntryByPath(unescapedTarget)
return commit.GetTreeEntryByPath(ctx, wikiRepo, unescapedTarget)
}
// findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error.
@@ -484,8 +484,8 @@ func findWikiRepoCommit(ctx *context.APIContext) (*git.Repository, *git.Commit)
// wikiContentsByEntry returns the contents of the wiki page referenced by the
// given tree entry, encoded with base64. Writes to ctx if an error occurs.
func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) string {
blob := entry.Blob()
func wikiContentsByEntry(ctx *context.APIContext, wikiRepo *git.Repository, entry *git.TreeEntry) string {
blob := entry.Blob(wikiRepo)
if blob.Size() > setting.API.DefaultMaxBlobSize {
return ""
}
@@ -499,9 +499,9 @@ func wikiContentsByEntry(ctx *context.APIContext, entry *git.TreeEntry) string {
// wikiContentsByName returns the contents of a wiki page, along with a boolean
// indicating whether the page exists. Writes to ctx if an error occurs.
func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wiki_service.WebPath, isSidebarOrFooter bool) (string, string) {
func wikiContentsByName(ctx *context.APIContext, wikiRepo *git.Repository, commit *git.Commit, wikiName wiki_service.WebPath, isSidebarOrFooter bool) (string, string) {
gitFilename := wiki_service.WebPathToGitPath(wikiName)
entry, err := findEntryForFile(commit, gitFilename)
entry, err := findEntryForFile(ctx, wikiRepo, commit, gitFilename)
if err != nil {
if git.IsErrNotExist(err) {
if !isSidebarOrFooter {
@@ -512,5 +512,5 @@ func wikiContentsByName(ctx *context.APIContext, commit *git.Commit, wikiName wi
}
return "", ""
}
return wikiContentsByEntry(ctx, entry), gitFilename
return wikiContentsByEntry(ctx, wikiRepo, entry), gitFilename
}
+1 -1
View File
@@ -64,7 +64,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
return cmd.WithEnv(env).
WithDir(repo.Path).
WithPipelineFunc(func(ctx gitcmd.Context) error {
commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
commit, err := git.CommitFromReader(commitID, stdoutReader)
if err != nil {
return err
}
+1 -1
View File
@@ -21,7 +21,7 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri
var commits []*git.Commit
var err error
if ctx.Repo.Commit != nil {
commits, err = ctx.Repo.Commit.CommitsByRange(0, 10, "", "", "")
commits, err = ctx.Repo.Commit.CommitsByRange(ctx.Repo.GitRepo, 0, 10, "", "", "")
if err != nil {
ctx.ServerError("ShowBranchFeed", err)
return
+2 -2
View File
@@ -206,7 +206,7 @@ func WorkflowDispatchInputs(ctx *context.Context) {
func prepareWorkflowTemplate(ctx *context.Context, commit *git.Commit) (workflows []WorkflowInfo, curWorkflowID string) {
curWorkflowID = ctx.FormString("workflow")
_, entries, err := actions.ListWorkflows(commit)
_, entries, err := actions.ListWorkflows(ctx, ctx.Repo.GitRepo, commit)
if err != nil {
ctx.ServerError("ListWorkflows", err)
return nil, ""
@@ -215,7 +215,7 @@ func prepareWorkflowTemplate(ctx *context.Context, commit *git.Commit) (workflow
workflows = make([]WorkflowInfo, 0, len(entries))
for _, entry := range entries {
workflow := WorkflowInfo{EntryName: entry.Name()}
content, err := actions.GetContentFromEntry(entry)
content, err := actions.GetContentFromEntry(ctx.Repo.GitRepo, entry)
if err != nil {
ctx.ServerError("GetContentFromEntry", err)
return nil, ""
+2 -2
View File
@@ -257,7 +257,7 @@ func ViewWorkflowFile(ctx *context_module.Context) {
}, err)
return
}
rpath, entries, err := actions.ListWorkflows(commit)
rpath, entries, err := actions.ListWorkflows(ctx, ctx.Repo.GitRepo, commit)
if err != nil {
ctx.ServerError("ListWorkflows", err)
return
@@ -1414,7 +1414,7 @@ func viewScopedWorkflowFile(ctx *context_module.Context, run *actions_model.Acti
}, err)
return
}
rpath, entries, err := actions.ListScopedWorkflows(commit)
rpath, entries, err := actions.ListScopedWorkflows(ctx, sourceGitRepo, commit)
if err != nil {
ctx.ServerError("ListScopedWorkflows", err)
return
+10 -7
View File
@@ -13,7 +13,6 @@ import (
"strconv"
"gitea.dev/models/gituser"
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/charset"
"gitea.dev/modules/git"
"gitea.dev/modules/git/languagestats"
@@ -51,13 +50,13 @@ func RefBlame(ctx *context.Context) {
ctx.NotFound(nil)
return
}
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
return
}
blob := entry.Blob()
blob := entry.Blob(ctx.Repo.GitRepo)
fileSize := blob.Size()
ctx.Data["FileSize"] = fileSize
ctx.Data["FileTreePath"] = ctx.Repo.TreePath
@@ -81,7 +80,7 @@ func RefBlame(ctx *context.Context) {
}
bypassBlameIgnore, _ := strconv.ParseBool(ctx.FormString("bypass-blame-ignore"))
result, err := performBlame(ctx, ctx.Repo.Repository, ctx.Repo.Commit, ctx.Repo.TreePath, bypassBlameIgnore)
result, err := performBlame(ctx, bypassBlameIgnore)
if err != nil {
ctx.NotFound(err)
return
@@ -106,10 +105,14 @@ type blameResult struct {
FaultyIgnoreRevsFile bool
}
func performBlame(ctx *context.Context, repo *repo_model.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) {
func performBlame(ctx *context.Context, bypassBlameIgnore bool) (*blameResult, error) {
repo := ctx.Repo.Repository
gitRepo := ctx.Repo.GitRepo
commit := ctx.Repo.Commit
file := ctx.Repo.TreePath
objectFormat := ctx.Repo.GetObjectFormat()
blameReader, err := gitrepo.CreateBlameReader(ctx, objectFormat, repo, commit, file, bypassBlameIgnore)
blameReader, err := gitrepo.CreateBlameReader(ctx, objectFormat, repo, gitRepo, commit, file, bypassBlameIgnore)
if err != nil {
return nil, err
}
@@ -125,7 +128,7 @@ func performBlame(ctx *context.Context, repo *repo_model.Repository, commit *git
if len(r.Parts) == 0 && r.UsesIgnoreRevs {
// try again without ignored revs
blameReader, err = gitrepo.CreateBlameReader(ctx, objectFormat, repo, commit, file, true)
blameReader, err = gitrepo.CreateBlameReader(ctx, objectFormat, repo, gitRepo, commit, file, true)
if err != nil {
return nil, err
}
+2 -2
View File
@@ -76,7 +76,7 @@ func Commits(ctx *context.Context) {
}
// Both `git log branchName` and `git log commitId` work.
commits, err := ctx.Repo.Commit.CommitsByRange(page, pageSize, "", "", "")
commits, err := ctx.Repo.Commit.CommitsByRange(ctx.Repo.GitRepo, page, pageSize, "", "", "")
if err != nil {
ctx.ServerError("CommitsByRange", err)
return
@@ -189,7 +189,7 @@ func SearchCommits(ctx *context.Context) {
all := ctx.FormBool("all")
opts := git.NewSearchCommitsOptions(query, all)
commits, err := ctx.Repo.Commit.SearchCommits(opts)
commits, err := ctx.Repo.Commit.SearchCommits(ctx.Repo.GitRepo, opts)
if err != nil {
ctx.ServerError("SearchCommits", err)
return
+2 -2
View File
@@ -61,7 +61,7 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner
return nil
}
blob, err := commit.GetBlobByPath(path)
blob, err := commit.GetBlobByPath(ctx, ctx.Repo.GitRepo, path)
if err != nil {
return nil
}
@@ -773,7 +773,7 @@ func ExcerptBlob(ctx *context.Context) {
ctx.ServerError("GetCommit", err)
return
}
blob, err := commit.Tree.GetBlobByPath(filePath)
blob, err := commit.GetBlobByPath(ctx, ctx.Repo.GitRepo, filePath)
if err != nil {
ctx.ServerError("GetBlobByPath", err)
return
+2 -2
View File
@@ -67,7 +67,7 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
}
func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(err)
@@ -89,7 +89,7 @@ func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
}
lastModified := &latestCommit.Committer.When
return entry.Blob(), lastModified
return entry.Blob(ctx.Repo.GitRepo), lastModified
}
// SingleDownload download a file by repos path
+4 -4
View File
@@ -224,7 +224,7 @@ func redirectForCommitChoice[T any](ctx *context.Context, parsed *preparedEditor
}
func editFileOpenExisting(ctx *context.Context) (prefetch []byte, dataRc io.ReadCloser, fInfo *fileInfo) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "GetTreeEntryByPath", err)
return nil, nil, nil
@@ -236,7 +236,7 @@ func editFileOpenExisting(ctx *context.Context) (prefetch []byte, dataRc io.Read
return nil, nil, nil
}
blob := entry.Blob()
blob := entry.Blob(ctx.Repo.GitRepo)
buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob)
if err != nil {
if git.IsErrNotExist(err) {
@@ -403,7 +403,7 @@ func DeleteFilePost(ctx *context.Context) {
}
// Check if the path is a directory
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, treePath)
if err != nil {
ctx.NotFoundOrServerError("GetTreeEntryByPath", git.IsErrNotExist, err)
return
@@ -442,7 +442,7 @@ func DeleteFilePost(ctx *context.Context) {
} else {
ctx.Flash.Success(ctx.Tr("repo.editor.file_delete_success", treePath))
}
redirectTreePath := getClosestParentWithFiles(ctx.Repo.GitRepo, parsed.NewBranchName, treePath)
redirectTreePath := getClosestParentWithFiles(ctx, ctx.Repo.GitRepo, parsed.NewBranchName, treePath)
redirectForCommitChoice(ctx, parsed, redirectTreePath)
}
+2 -2
View File
@@ -19,7 +19,7 @@ func DiffPreviewPost(ctx *context.Context) {
return
}
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, treePath)
if err != nil {
ctx.ServerError("GetTreeEntryByPath", err)
return
@@ -28,7 +28,7 @@ func DiffPreviewPost(ctx *context.Context) {
return
}
oldContent, err := entry.Blob().GetBlobContent(setting.UI.MaxDisplayFileSize)
oldContent, err := entry.Blob(ctx.Repo.GitRepo).GetBlobContent(setting.UI.MaxDisplayFileSize)
if err != nil {
ctx.ServerError("GetBlobContent", err)
return
+2 -2
View File
@@ -23,9 +23,9 @@ func TestEditorUtils(t *testing.T) {
t.Run("getClosestParentWithFiles", func(t *testing.T) {
gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo)
defer gitRepo.Close()
treePath := getClosestParentWithFiles(gitRepo, "sub-home-md-img-check", "docs/foo/bar")
treePath := getClosestParentWithFiles(t.Context(), gitRepo, "sub-home-md-img-check", "docs/foo/bar")
assert.Equal(t, "docs", treePath)
treePath = getClosestParentWithFiles(gitRepo, "sub-home-md-img-check", "any/other")
treePath = getClosestParentWithFiles(t.Context(), gitRepo, "sub-home-md-img-check", "any/other")
assert.Empty(t, treePath)
})
}
+4 -4
View File
@@ -43,16 +43,16 @@ func getUniquePatchBranchName(ctx context.Context, prefixName string, repo *repo
// getClosestParentWithFiles Recursively gets the closest path of parent in a tree that has files when a file in a tree is
// deleted. It returns "" for the tree root if no parents other than the root have files.
func getClosestParentWithFiles(gitRepo *git.Repository, branchName, originTreePath string) string {
func getClosestParentWithFiles(ctx context.Context, gitRepo *git.Repository, branchName, originTreePath string) string {
var f func(treePath string, commit *git.Commit) string
f = func(treePath string, commit *git.Commit) string {
if treePath == "" || treePath == "." {
return ""
}
// see if the tree has entries
if tree, err := commit.SubTree(treePath); err != nil {
if tree, err := commit.SubTree(ctx, gitRepo, treePath); err != nil {
return f(path.Dir(treePath), commit) // failed to get the tree, going up a dir
} else if entries, err := tree.ListEntries(); err != nil || len(entries) == 0 {
} else if entries, err := tree.ListEntries(ctx, gitRepo); err != nil || len(entries) == 0 {
return f(path.Dir(treePath), commit) // no files in this dir, going up a dir
}
return treePath
@@ -87,7 +87,7 @@ func getCodeEditorConfigByEditorconfig(ctx *context_service.Context, treePath st
ret.LineWrapExtensions = setting.Repository.Editor.LineWrapExtensions
ret.LineWrap = util.SliceContainsString(ret.LineWrapExtensions, path.Ext(treePath), true)
ret.Previewable = util.SliceContainsString(ret.PreviewableExtensions, path.Ext(treePath), true)
ec, _, err := ctx.Repo.GetEditorconfig()
ec, _, err := ctx.Repo.GetEditorconfig(ctx)
if err == nil {
def, err := ec.GetDefinitionForFilename(treePath)
if err == nil {
+1 -1
View File
@@ -754,7 +754,7 @@ func Issues(ctx *context.Context) {
}
ctx.Data["Title"] = ctx.Tr("repo.issues")
ctx.Data["PageIsIssueList"] = true
ctx.Data["NewIssueChooseTemplate"] = issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["NewIssueChooseTemplate"] = issue_service.HasTemplatesOrContactLinks(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
}
projectIDs := parseProjectIDsFromQuery(ctx)
+9 -9
View File
@@ -51,10 +51,10 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
templateErrs := map[string]error{}
for _, filename := range templateCandidates {
if ok, _ := commit.HasFile(filename); !ok {
template, err := issue_template.UnmarshalFromCommit(ctx, ctx.Repo.GitRepo, commit, filename)
if errors.Is(err, util.ErrNotExist) {
continue
}
template, err := issue_template.UnmarshalFromCommit(commit, filename)
if err != nil {
templateErrs[filename] = err
continue
@@ -98,8 +98,8 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
// NewIssue render creating issue page
func NewIssue(ctx *context.Context) {
issueConfig, _ := issue_service.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
hasTemplates := issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo)
issueConfig, _ := issue_service.GetTemplateConfigFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
hasTemplates := issue_service.HasTemplatesOrContactLinks(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
ctx.Data["PageIsIssueList"] = true
@@ -134,7 +134,7 @@ func NewIssue(ctx *context.Context) {
}
ctx.Data["Tags"] = tags
ret := issue_service.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
ret := issue_service.ParseTemplatesFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
templateLoaded, errs := setTemplateIfExists(ctx, issueTemplateKey, IssueTemplateCandidates, pageMetaData)
maps.Copy(ret.TemplateErrors, errs)
if ctx.Written() {
@@ -186,20 +186,20 @@ func NewIssueChooseTemplate(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.issues.new")
ctx.Data["PageIsIssueList"] = true
ret := issue_service.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
ret := issue_service.ParseTemplatesFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["IssueTemplates"] = ret.IssueTemplates
if len(ret.TemplateErrors) > 0 {
ctx.Flash.Warning(renderErrorOfTemplates(ctx, ret.TemplateErrors), true)
}
if !issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo) {
if !issue_service.HasTemplatesOrContactLinks(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo) {
// The "issues/new" and "issues/new/choose" share the same query parameters "project" and "milestone", if no template here, just redirect to the "issues/new" page with these parameters.
ctx.Redirect(fmt.Sprintf("%s/issues/new?%s", ctx.Repo.Repository.Link(), ctx.Req.URL.RawQuery), http.StatusSeeOther)
return
}
issueConfig, err := issue_service.GetTemplateConfigFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
issueConfig, err := issue_service.GetTemplateConfigFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["IssueConfig"] = issueConfig
ctx.Data["IssueConfigError"] = err // ctx.Flash.Err makes problems here
@@ -358,7 +358,7 @@ func NewIssuePost(ctx *context.Context) {
content := form.Content
if filename := ctx.Req.Form.Get("template-file"); filename != "" {
if template, err := issue_template.UnmarshalFromRepo(ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil {
if template, err := issue_template.UnmarshalFromRepo(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil {
content = issue_template.RenderToMarkdown(template, ctx.Req.Form)
}
}
+1 -1
View File
@@ -334,7 +334,7 @@ func ViewIssue(ctx *context.Context) {
return
}
ctx.Data["PageIsIssueList"] = true
ctx.Data["NewIssueChooseTemplate"] = issue_service.HasTemplatesOrContactLinks(ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["NewIssueChooseTemplate"] = issue_service.HasTemplatesOrContactLinks(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
}
ctx.Data["IsProjectsEnabled"] = ctx.Repo.Permission.CanRead(unit.TypeProjects)
+1 -1
View File
@@ -22,7 +22,7 @@ func SetEditorconfigIfExists(ctx *context.Context) {
return
}
ec, _, err := ctx.Repo.GetEditorconfig()
ec, _, err := ctx.Repo.GetEditorconfig(ctx)
if err != nil {
// it used to check `!git.IsErrNotExist(err)` and create a system notice, but it is quite annoying and useless
// because network errors also happen frequently, so we just ignore it
+1 -1
View File
@@ -262,7 +262,7 @@ func MilestoneIssuesAndPulls(ctx *context.Context) {
prepareIssueFilterAndList(ctx, milestoneID, projectIDs, optional.None[bool]())
ret := issue.ParseTemplatesFromDefaultBranch(ctx.Repo.Repository, ctx.Repo.GitRepo)
ret := issue.ParseTemplatesFromDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo)
ctx.Data["NewIssueChooseTemplate"] = len(ret.IssueTemplates) > 0
ctx.Data["CanWriteIssues"] = ctx.Repo.Permission.CanWriteIssuesOrPulls(false)
+2 -2
View File
@@ -744,7 +744,7 @@ func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) {
var beforeCommit *git.Commit
if isSingleCommit {
beforeCommit, err = afterCommit.Parent(0)
beforeCommit, err = afterCommit.Parent(ctx.Repo.GitRepo, 0)
if err != nil {
ctx.ServerError("afterCommit.Parent", err)
return
@@ -1377,7 +1377,7 @@ func CompareAndPullRequestPost(ctx *context.Context) {
content := form.Content
if filename := ctx.Req.Form.Get("template-file"); filename != "" {
if template, err := issue_template.UnmarshalFromRepo(ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil {
if template, err := issue_template.UnmarshalFromRepo(ctx, ctx.Repo.GitRepo, ctx.Repo.Repository.DefaultBranch, filename); err == nil {
content = issue_template.RenderToMarkdown(template, ctx.Req.Form)
}
}
+1 -1
View File
@@ -19,7 +19,7 @@ func RenderFile(ctx *context.Context) {
var blob *git.Blob
var err error
if ctx.Repo.TreePath != "" {
blob, err = ctx.Repo.Commit.GetBlobByPath(ctx.Repo.TreePath)
blob, err = ctx.Repo.Commit.GetBlobByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
} else {
blob, err = ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha"))
}
+3 -3
View File
@@ -22,13 +22,13 @@ import (
// TreeList get all files' entries of a repository
func TreeList(ctx *context.Context) {
tree, err := ctx.Repo.Commit.SubTree("/")
tree, err := ctx.Repo.Commit.SubTree(ctx, ctx.Repo.GitRepo, "/")
if err != nil {
ctx.ServerError("Repo.Commit.SubTree", err)
return
}
entries, err := tree.ListEntriesRecursiveFast()
entries, err := tree.ListEntriesRecursiveFast(ctx, ctx.Repo.GitRepo)
if err != nil {
ctx.ServerError("ListEntriesRecursiveFast", err)
return
@@ -144,7 +144,7 @@ func transformDiffTreeForWeb(renderedIconPool *fileicon.RenderedIconPool, diffTr
func TreeViewNodes(ctx *context.Context) {
renderedIconPool := fileicon.NewRenderedIconPool()
results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.RepoLink, renderedIconPool, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path"))
results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.RepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path"))
if err != nil {
ctx.ServerError("GetTreeViewNodes", err)
return
+8 -5
View File
@@ -260,7 +260,7 @@ func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) {
fileIcons := map[string]template.HTML{}
for _, f := range files {
fullPath := path.Join(ctx.Repo.TreePath, f.Entry.Name())
entryInfo := fileicon.EntryInfoFromGitTreeEntry(ctx.Repo.Commit, fullPath, f.Entry)
entryInfo := fileicon.EntryInfoFromGitTreeEntry(ctx, ctx.Repo.GitRepo, ctx.Repo.Commit, fullPath, f.Entry)
fileIcons[f.Entry.Name()] = fileicon.RenderEntryIconHTML(renderedIconPool, entryInfo)
}
fileIcons[".."] = fileicon.RenderEntryIconHTML(renderedIconPool, fileicon.EntryInfoFolder())
@@ -269,7 +269,7 @@ func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) {
}
func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entries {
tree, err := ctx.Repo.Commit.SubTree(ctx.Repo.TreePath)
tree, err := ctx.Repo.Commit.SubTree(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "Repo.Commit.SubTree", err)
return nil
@@ -280,7 +280,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
ctx.Data["LastCommitLoaderURL"] = lastCommitLoaderURL + "?refSubUrl=" + url.QueryEscape(ctx.Repo.RefTypeNameSubURL())
// Get current entry user currently looking at.
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
return nil
@@ -291,7 +291,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
return nil
}
allEntries, err := tree.ListEntries()
allEntries, err := tree.ListEntries(ctx, ctx.Repo.GitRepo)
if err != nil {
ctx.ServerError("ListEntries", err)
return nil
@@ -305,7 +305,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
defer cancel()
}
files, latestCommit, err := allEntries.GetCommitsInfo(commitInfoCtx, ctx.Repo.RepoLink, ctx.Repo.Commit, ctx.Repo.TreePath)
files, latestCommit, err := allEntries.GetCommitsInfo(commitInfoCtx, ctx.Repo.RepoLink, ctx.Repo.GitRepo, ctx.Repo.Commit, ctx.Repo.TreePath)
if err != nil {
ctx.ServerError("GetCommitsInfo", err)
return nil
@@ -328,6 +328,9 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
}
ctx.Data["Files"] = files
ctx.Data["GetSubJumpablePathName"] = func(entry *git.TreeEntry) string {
return entry.GetSubJumpablePathName(ctx, ctx.Repo.GitRepo)
}
prepareDirectoryFileIcons(ctx, files)
for _, f := range files {
if f.Commit == nil {
+5 -5
View File
@@ -29,7 +29,7 @@ import (
)
func prepareLatestCommitInfo(ctx *context.Context) bool {
commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath)
commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
ctx.ServerError("GetCommitByPath", err)
return false
@@ -161,7 +161,7 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) {
return
}
blob := entry.Blob()
blob := entry.Blob(ctx.Repo.GitRepo)
ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+ctx.Repo.TreePath, ctx.Repo.RefFullName.ShortName())
ctx.Data["FileIsSymlink"] = entry.IsLink()
@@ -169,7 +169,7 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
if ctx.Repo.TreePath == ".editorconfig" {
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx, ctx.Repo.Commit)
if editorconfigWarning != nil {
ctx.Data["FileWarning"] = strings.TrimSpace(editorconfigWarning.Error())
}
@@ -177,12 +177,12 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileError"] = strings.TrimSpace(editorconfigErr.Error())
}
} else if issue_service.IsTemplateConfig(ctx.Repo.TreePath) {
_, issueConfigErr := issue_service.GetTemplateConfig(ctx.Repo.GitRepo, ctx.Repo.TreePath, ctx.Repo.Commit)
_, issueConfigErr := issue_service.GetTemplateConfig(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath, ctx.Repo.Commit)
if issueConfigErr != nil {
ctx.Data["FileError"] = strings.TrimSpace(issueConfigErr.Error())
}
} else if actions.IsWorkflow(ctx.Repo.TreePath) {
content, err := actions.GetContentFromEntry(entry)
content, err := actions.GetContentFromEntry(ctx.Repo.GitRepo, entry)
if err != nil {
log.Error("actions.GetContentFromEntry: %v", err)
}
+6 -6
View File
@@ -100,12 +100,12 @@ func prepareHomeSidebarCitationFile(entry *git.TreeEntry) func(ctx *context.Cont
if entry.Name() != "" {
return
}
tree, err := ctx.Repo.Commit.SubTree(ctx.Repo.TreePath)
tree, err := ctx.Repo.Commit.SubTree(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "Repo.Commit.SubTree", err)
return
}
allEntries, err := tree.ListEntries()
allEntries, err := tree.ListEntries(ctx, ctx.Repo.GitRepo)
if err != nil {
ctx.ServerError("ListEntries", err)
return
@@ -113,7 +113,7 @@ func prepareHomeSidebarCitationFile(entry *git.TreeEntry) func(ctx *context.Cont
for _, entry := range allEntries {
if entry.Name() == "CITATION.cff" || entry.Name() == "CITATION.bib" {
// Read Citation file contents
if content, err := entry.Blob().GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
if content, err := entry.Blob(ctx.Repo.GitRepo).GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("checkCitationFile: GetBlobContent: %v", err)
} else {
ctx.Data["CitiationExist"] = true
@@ -290,7 +290,7 @@ func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.Comm
func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) {
return func(ctx *context.Context) {
if entry.IsSubModule() {
commitSubmoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.Commit, entry.ID)
commitSubmoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx, ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.GitRepo, ctx.Repo.Commit, entry.ID)
if err != nil {
HandleGitError(ctx, "prepareToRenderDirOrFile: GetCommitInfoSubmoduleFile", err)
return
@@ -351,7 +351,7 @@ func redirectFollowSymlink(ctx *context.Context, treePathEntry *git.TreeEntry) b
return false
}
if treePathEntry.IsLink() {
if res, err := git.EntryFollowLinks(ctx.Repo.Commit, ctx.Repo.TreePath, treePathEntry); err == nil {
if res, err := git.EntryFollowLinks(ctx, ctx.Repo.GitRepo, ctx.Repo.Commit, ctx.Repo.TreePath, treePathEntry); err == nil {
redirect := ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(res.TargetFullPath) + "?" + ctx.Req.URL.RawQuery
ctx.Redirect(redirect)
return true
@@ -425,7 +425,7 @@ func Home(ctx *context.Context) {
prepareHomeTreeSideBarSwitch(ctx)
// get the current git entry which doer user is currently looking at.
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx, ctx.Repo.GitRepo, ctx.Repo.TreePath)
if err != nil {
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
return
+6 -6
View File
@@ -66,9 +66,9 @@ func findReadmeFileInEntries(ctx *context.Context, parentDir string, entries []*
for _, entry := range entries {
if i, ok := util.IsReadmeFileExtension(entry.Name(), exts...); ok {
fullPath := path.Join(parentDir, entry.Name())
if readmeFiles[i] == nil || base.NaturalSortCompare(readmeFiles[i].Name(), entry.Blob().Name()) < 0 {
if readmeFiles[i] == nil || base.NaturalSortCompare(readmeFiles[i].Name(), entry.Blob(ctx.Repo.GitRepo).Name()) < 0 {
if entry.IsLink() {
res, err := git.EntryFollowLinks(ctx.Repo.Commit, fullPath, entry)
res, err := git.EntryFollowLinks(ctx, ctx.Repo.GitRepo, ctx.Repo.Commit, fullPath, entry)
if err == nil && (res.TargetEntry.IsExecutable() || res.TargetEntry.IsRegular()) {
readmeFiles[i] = entry
}
@@ -92,12 +92,12 @@ func findReadmeFileInEntries(ctx *context.Context, parentDir string, entries []*
if subTreeEntry == nil {
continue
}
subTree := subTreeEntry.Tree()
subTree := subTreeEntry.Tree(ctx.Repo.GitRepo)
if subTree == nil {
// this should be impossible; if subTreeEntry exists so should this.
continue
}
childEntries, err := subTree.ListEntries()
childEntries, err := subTree.ListEntries(ctx, ctx.Repo.GitRepo)
if err != nil {
return "", nil, err
}
@@ -145,7 +145,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
readmeFullPath := path.Join(ctx.Repo.TreePath, subfolder, readmeFile.Name())
readmeTargetEntry := readmeFile
if readmeFile.IsLink() {
if res, err := git.EntryFollowLinks(ctx.Repo.Commit, readmeFullPath, readmeFile); err == nil {
if res, err := git.EntryFollowLinks(ctx, ctx.Repo.GitRepo, ctx.Repo.Commit, readmeFullPath, readmeFile); err == nil {
readmeTargetEntry = res.TargetEntry
} else {
readmeTargetEntry = nil // if we cannot resolve the symlink, we cannot render the readme, ignore the error
@@ -160,7 +160,7 @@ func prepareToRenderReadmeFile(ctx *context.Context, subfolder string, readmeFil
ctx.Data["ReadmeExist"] = true
ctx.Data["FileIsSymlink"] = readmeFile.IsLink()
buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, readmeTargetEntry.Blob())
buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, readmeTargetEntry.Blob(ctx.Repo.GitRepo))
if err != nil {
ctx.ServerError("getFileReader", err)
return
+3 -2
View File
@@ -48,11 +48,12 @@ data 12
commit, err := gitRepo.GetBranchCommit("master")
require.NoError(t, err)
entries, err := commit.ListEntries()
entries, err := commit.Tree().ListEntries(t.Context(), gitRepo)
require.NoError(t, err)
ctx, _ := contexttest.MockContext(t, "/")
ctx.Repo.Commit = commit
ctx.Repo.GitRepo = gitRepo
foundDir, foundReadme, err := findReadmeFileInEntries(ctx, "", entries, true)
require.NoError(t, err)
require.NotNil(t, foundReadme)
@@ -62,7 +63,7 @@ data 12
assert.True(t, foundReadme.IsLink())
// Verify that it can follow the link
res, err := git.EntryFollowLinks(commit, path.Join(foundDir, foundReadme.Name()), foundReadme)
res, err := git.EntryFollowLinks(t.Context(), gitRepo, commit, path.Join(foundDir, foundReadme.Name()), foundReadme)
require.NoError(t, err)
assert.Equal(t, "target.md", res.TargetFullPath)
})
+29 -28
View File
@@ -6,6 +6,7 @@ package repo
import (
"bytes"
gocontext "context"
"html/template"
"io"
"net/http"
@@ -78,8 +79,8 @@ type PageMeta struct {
}
// findEntryForFile finds the tree entry for a target filepath.
func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error) {
entry, err := commit.GetTreeEntryByPath(target)
func findEntryForFile(ctx gocontext.Context, wikiRepo *git.Repository, commit *git.Commit, target string) (*git.TreeEntry, error) {
entry, err := commit.GetTreeEntryByPath(ctx, wikiRepo, target)
if err != nil && !git.IsErrNotExist(err) {
return nil, err
}
@@ -92,7 +93,7 @@ func findEntryForFile(commit *git.Commit, target string) (*git.TreeEntry, error)
if unescapedTarget, err = url.QueryUnescape(target); err != nil {
return nil, err
}
return commit.GetTreeEntryByPath(unescapedTarget)
return commit.GetTreeEntryByPath(ctx, wikiRepo, unescapedTarget)
}
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
@@ -126,8 +127,8 @@ func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, err
// wikiContentsByEntry returns the contents of the wiki page referenced by the
// given tree entry. Writes to ctx if an error occurs.
func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
reader, err := entry.Blob().DataAsync()
func wikiContentsByEntry(ctx *context.Context, wikiRepo *git.Repository, entry *git.TreeEntry) []byte {
reader, err := entry.Blob(wikiRepo).DataAsync()
if err != nil {
ctx.ServerError("Blob.Data", err)
return nil
@@ -144,10 +145,10 @@ func wikiContentsByEntry(ctx *context.Context, entry *git.TreeEntry) []byte {
// wikiEntryByName returns the entry of a wiki page, along with a boolean
// indicating whether the entry exists. Writes to ctx if an error occurs.
// The last return value indicates whether the file should be returned as a raw file
func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) (*git.TreeEntry, string, bool, bool) {
func wikiEntryByName(ctx *context.Context, wikiRepo *git.Repository, commit *git.Commit, wikiName wiki_service.WebPath) (*git.TreeEntry, string, bool, bool) {
isRaw := false
gitFilename := wiki_service.WebPathToGitPath(wikiName)
entry, err := findEntryForFile(commit, gitFilename)
entry, err := findEntryForFile(ctx, wikiRepo, commit, gitFilename)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findEntryForFile", err)
return nil, "", false, false
@@ -155,7 +156,7 @@ func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_ser
if entry == nil {
// check if the file without ".md" suffix exists
gitFilename := strings.TrimSuffix(gitFilename, ".md")
entry, err = findEntryForFile(commit, gitFilename)
entry, err = findEntryForFile(ctx, wikiRepo, commit, gitFilename)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findEntryForFile", err)
return nil, "", false, false
@@ -170,12 +171,12 @@ func wikiEntryByName(ctx *context.Context, commit *git.Commit, wikiName wiki_ser
// wikiContentsByName returns the contents of a wiki page, along with a boolean
// indicating whether the page exists. Writes to ctx if an error occurs.
func wikiContentsByName(ctx *context.Context, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) {
entry, gitFilename, noEntry, _ := wikiEntryByName(ctx, commit, wikiName)
func wikiContentsByName(ctx *context.Context, wikiRepo *git.Repository, commit *git.Commit, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) {
entry, gitFilename, noEntry, _ := wikiEntryByName(ctx, wikiRepo, commit, wikiName)
if entry == nil {
return nil, nil, "", true
}
return wikiContentsByEntry(ctx, entry), entry, gitFilename, noEntry
return wikiContentsByEntry(ctx, wikiRepo, entry), entry, gitFilename, noEntry
}
func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
@@ -188,7 +189,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
// get the wiki pages list.
entries, err := commit.ListEntries()
entries, err := commit.Tree().ListEntries(ctx, wikiGitRepo)
if err != nil {
ctx.ServerError("ListEntries", err)
return nil, nil
@@ -233,7 +234,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
isFooter := pageName == "_Footer"
// lookup filename in wiki - get gitTree entry , real filename
entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
entry, pageFilename, noEntry, isRaw := wikiEntryByName(ctx, wikiGitRepo, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
@@ -245,7 +246,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
// get page content
data := wikiContentsByEntry(ctx, entry)
data := wikiContentsByEntry(ctx, wikiGitRepo, entry)
if ctx.Written() {
return nil, nil
}
@@ -283,7 +284,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
if !isSideBar {
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
sidebarContent, _, _, _ := wikiContentsByName(ctx, wikiGitRepo, commit, "_Sidebar")
if ctx.Written() {
return nil, nil
}
@@ -295,7 +296,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
}
if !isFooter {
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
footerContent, _, _, _ := wikiContentsByName(ctx, wikiGitRepo, commit, "_Footer")
if ctx.Written() {
return nil, nil
}
@@ -335,7 +336,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
ctx.Data["title"] = displayName
// lookup filename in wiki - get page content, gitTree entry , real filename
_, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
_, entry, pageFilename, noEntry := wikiContentsByName(ctx, wikiGitRepo, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
@@ -375,7 +376,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
}
func renderEditPage(ctx *context.Context) {
_, commit, err := findWikiRepoCommit(ctx)
wikiGitRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil {
if !git.IsErrNotExist(err) {
ctx.ServerError("GetBranchCommit", err)
@@ -396,7 +397,7 @@ func renderEditPage(ctx *context.Context) {
ctx.Data["title"] = displayName
// lookup filename in wiki - gitTree entry , real filename
entry, _, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
entry, _, noEntry, isRaw := wikiEntryByName(ctx, wikiGitRepo, commit, pageName)
if noEntry {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
}
@@ -408,7 +409,7 @@ func renderEditPage(ctx *context.Context) {
}
// get wiki page content
data := wikiContentsByEntry(ctx, entry)
data := wikiContentsByEntry(ctx, wikiGitRepo, entry)
if ctx.Written() {
return
}
@@ -543,27 +544,27 @@ func WikiPages(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
ctx.Data["CanWriteWiki"] = ctx.Repo.Permission.CanWrite(unit.TypeWiki) && !ctx.Repo.Repository.IsArchived
_, commit, err := findWikiRepoCommit(ctx)
wikiGitRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil {
ctx.Redirect(ctx.Repo.RepoLink + "/wiki")
return
}
treePath := "" // To support list sub folders' pages in the future
tree, err := commit.SubTree(treePath)
tree, err := commit.SubTree(ctx, wikiGitRepo, treePath)
if err != nil {
ctx.ServerError("SubTree", err)
return
}
allEntries, err := tree.ListEntries()
allEntries, err := tree.ListEntries(ctx, wikiGitRepo)
if err != nil {
ctx.ServerError("ListEntries", err)
return
}
allEntries.CustomSort(base.NaturalSortCompare)
entries, _, err := allEntries.GetCommitsInfo(ctx, ctx.Repo.RepoLink, commit, treePath)
entries, _, err := allEntries.GetCommitsInfo(ctx, ctx.Repo.RepoLink, wikiGitRepo, commit, treePath)
if err != nil {
ctx.ServerError("GetCommitsInfo", err)
return
@@ -597,7 +598,7 @@ func WikiPages(ctx *context.Context) {
// WikiRaw outputs raw blob requested by user (image for example)
func WikiRaw(ctx *context.Context) {
_, commit, err := findWikiRepoCommit(ctx)
wikiGitRepo, commit, err := findWikiRepoCommit(ctx)
if err != nil {
if git.IsErrNotExist(err) {
ctx.NotFound(nil)
@@ -612,7 +613,7 @@ func WikiRaw(ctx *context.Context) {
var entry *git.TreeEntry
if commit != nil {
// Try to find a file with that name
entry, err = findEntryForFile(commit, providedGitPath)
entry, err = findEntryForFile(ctx, wikiGitRepo, commit, providedGitPath)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findFile", err)
return
@@ -621,7 +622,7 @@ func WikiRaw(ctx *context.Context) {
if entry == nil {
// Try to find a wiki page with that name
providedGitPath = strings.TrimSuffix(providedGitPath, ".md")
entry, err = findEntryForFile(commit, providedGitPath)
entry, err = findEntryForFile(ctx, wikiGitRepo, commit, providedGitPath)
if err != nil && !git.IsErrNotExist(err) {
ctx.ServerError("findFile", err)
return
@@ -630,7 +631,7 @@ func WikiRaw(ctx *context.Context) {
}
if entry != nil {
if err = common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, entry.Blob(), nil); err != nil {
if err = common.ServeBlob(ctx.Base, ctx.Repo.Repository, ctx.Repo.TreePath, entry.Blob(wikiGitRepo), nil); err != nil {
ctx.ServerError("ServeBlob", err)
}
return
+13 -9
View File
@@ -28,28 +28,30 @@ const (
message = "Wiki commit message for unit tests"
)
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry {
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) (*git.Repository, *git.TreeEntry) {
wikiRepo, err := gitrepo.OpenRepository(t.Context(), repo.WikiStorageRepo())
assert.NoError(t, err)
defer wikiRepo.Close()
t.Cleanup(func() {
defer wikiRepo.Close()
})
commit, err := wikiRepo.GetBranchCommit("master")
assert.NoError(t, err)
entries, err := commit.ListEntries()
entries, err := commit.Tree().ListEntries(t.Context(), wikiRepo)
assert.NoError(t, err)
for _, entry := range entries {
if entry.Name() == wiki_service.WebPathToGitPath(wikiName) {
return entry
return wikiRepo, entry
}
}
return nil
return wikiRepo, nil
}
func wikiContent(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) string {
entry := wikiEntry(t, repo, wikiName)
wikiRepo, entry := wikiEntry(t, repo, wikiName)
if !assert.NotNil(t, entry) {
return ""
}
reader, err := entry.Blob().DataAsync()
reader, err := entry.Blob(wikiRepo).DataAsync()
assert.NoError(t, err)
defer reader.Close()
bytes, err := io.ReadAll(reader)
@@ -58,11 +60,13 @@ func wikiContent(t *testing.T, repo *repo_model.Repository, wikiName wiki_servic
}
func assertWikiExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) {
assert.NotNil(t, wikiEntry(t, repo, wikiName))
_, entry := wikiEntry(t, repo, wikiName)
assert.NotNil(t, entry)
}
func assertWikiNotExists(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) {
assert.Nil(t, wikiEntry(t, repo, wikiName))
_, entry := wikiEntry(t, repo, wikiName)
assert.Nil(t, entry)
}
func assertPagesMetas(t *testing.T, expectedNames []string, metas any) {
+1 -1
View File
@@ -122,7 +122,7 @@ func FindOwnerProfileReadme(ctx *context.Context, doer *user_model.User, optProf
return nil, nil
}
profileReadmeBlob, _ = commit.GetBlobByPath("README.md") // no need to handle this error
profileReadmeBlob, _ = commit.GetBlobByPath(ctx, profileGitRepo, "README.md") // no need to handle this error
return profileDbRepo, profileReadmeBlob
}
+4 -3
View File
@@ -185,7 +185,7 @@ func notify(ctx context.Context, input *notifyInput) error {
var detectedWorkflows []*actions_module.DetectedWorkflow
var filteredWorkflows []*actions_module.DetectedWorkflow
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()
workflows, schedules, filtered, err := actions_module.DetectWorkflows(gitRepo, commit,
workflows, schedules, filtered, err := actions_module.DetectWorkflows(ctx, gitRepo, commit,
input.Event,
input.Payload,
shouldDetectSchedules,
@@ -231,7 +231,7 @@ func notify(ctx context.Context, input *notifyInput) error {
if err != nil {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
baseWorkflows, _, baseFiltered, err := actions_module.DetectWorkflows(gitRepo, baseCommit, input.Event, input.Payload, false)
baseWorkflows, _, baseFiltered, err := actions_module.DetectWorkflows(ctx, gitRepo, baseCommit, input.Event, input.Payload, false)
if err != nil {
return fmt.Errorf("DetectWorkflows: %w", err)
}
@@ -602,7 +602,7 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
if err != nil {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
scheduleWorkflows, err := actions_module.DetectScheduledWorkflows(gitRepo, commit)
scheduleWorkflows, err := actions_module.DetectScheduledWorkflows(ctx, gitRepo, commit)
if err != nil {
return fmt.Errorf("detect schedule workflows: %w", err)
}
@@ -743,6 +743,7 @@ func detectScopedWorkflowsForSource(
sourceRepo *repo_model.Repository,
) (sourceCommitSHA string, detected, filtered []*actions_module.DetectedWorkflow, err error) {
// scoped workflow content is always taken from the source repo's default branch; the parse is cached per (source, default-branch SHA) and reused across consuming repos/events
sourceCommitSHA, parsed, err := LoadParsedScopedWorkflows(ctx, sourceRepo)
if err != nil {
return "", nil, nil, err
+1 -1
View File
@@ -89,7 +89,7 @@ func readWorkflowFromRepo(ctx context.Context, repo *repo_model.Repository, refO
if err != nil {
return nil, "", fmt.Errorf("get commit %q in %s: %w", refOrSHA, repo.FullName(), err)
}
str, err := commit.GetFileContent(path, 1024*1024)
str, err := commit.GetFileContent(ctx, gitRepo, path, 1024*1024)
if err != nil {
return nil, "", fmt.Errorf("read %s@%s:%s: %w", repo.FullName(), refOrSHA, path, err)
}
+1 -1
View File
@@ -60,7 +60,7 @@ func LoadParsedScopedWorkflows(ctx context.Context, sourceRepo *repo_model.Repos
if err != nil {
return "", nil, fmt.Errorf("get source commit %s: %w", sha, err)
}
parsed, err = actions_module.ParseScopedWorkflows(sourceCommit)
parsed, err = actions_module.ParseScopedWorkflows(ctx, sourceGitRepo, sourceCommit)
if err != nil {
return "", nil, err
}
+4 -4
View File
@@ -119,7 +119,7 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
}
// resolve the workflow content and record its source on the run (scoped runs read from the source repo)
content, err := resolveDispatchWorkflowContent(ctx, repo, runTargetCommit, workflowID, scopedWorkflowSourceRepoID, isScoped, run)
content, err := resolveDispatchWorkflowContent(ctx, repo, gitRepo, runTargetCommit, workflowID, scopedWorkflowSourceRepoID, isScoped, run)
if err != nil {
return 0, err
}
@@ -172,18 +172,18 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
// resolveDispatchWorkflowContent returns the YAML for a dispatched workflow and records its source on the run.
// - Repo-level: from the consumer's runTargetCommit.
// - Scoped: from the source repo's default branch.
func resolveDispatchWorkflowContent(ctx reqctx.RequestContext, repo *repo_model.Repository, runTargetCommit *git.Commit, workflowID string, sourceRepoID int64, isScoped bool, run *actions_model.ActionRun) ([]byte, error) {
func resolveDispatchWorkflowContent(ctx reqctx.RequestContext, repo *repo_model.Repository, gitRepo *git.Repository, runTargetCommit *git.Commit, workflowID string, sourceRepoID int64, isScoped bool, run *actions_model.ActionRun) ([]byte, error) {
if isScoped {
return resolveScopedDispatchContent(ctx, repo, sourceRepoID, workflowID, run)
}
_, entries, err := actions.ListWorkflows(runTargetCommit)
_, entries, err := actions.ListWorkflows(ctx, gitRepo, runTargetCommit)
if err != nil {
return nil, err
}
for _, e := range entries {
if e.Name() == workflowID {
return actions.GetContentFromEntry(e)
return actions.GetContentFromEntry(gitRepo, e)
}
}
return nil, util.ErrorWrapTranslatable(
+2 -2
View File
@@ -37,7 +37,7 @@ func TestParseCommitWithSSHSignature(t *testing.T) {
require.NoError(t, err)
t.Run("UserSSHKey", func(t *testing.T) {
commit, err := git.CommitFromReader(nil, git.Sha1ObjectFormat.EmptyObjectID(), strings.NewReader(`tree a3b1fad553e0f9a2b4a58327bebde36c7da75aa2
commit, err := git.CommitFromReader(git.Sha1ObjectFormat.EmptyObjectID(), strings.NewReader(`tree a3b1fad553e0f9a2b4a58327bebde36c7da75aa2
author user2 <user2@example.com> 1752194028 -0700
committer user2 <user2@example.com> 1752194028 -0700
gpgsig -----BEGIN SSH SIGNATURE-----
@@ -68,7 +68,7 @@ init project
defer test.MockVariableValue(&setting.Repository.Signing.SigningEmail, "gitea@fake.local")()
defer test.MockVariableValue(&setting.Repository.Signing.TrustedSSHKeys, []string{"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH6Y4idVaW3E+bLw1uqoAfJD7o5Siu+HqS51E9oQLPE9"})()
commit, err := git.CommitFromReader(nil, git.Sha1ObjectFormat.EmptyObjectID(), strings.NewReader(`tree 9a93ffa76e8b72bdb6431910b3a506fa2b39f42e
commit, err := git.CommitFromReader(git.Sha1ObjectFormat.EmptyObjectID(), strings.NewReader(`tree 9a93ffa76e8b72bdb6431910b3a506fa2b39f42e
author User Two <user2@example.com> 1749230009 +0200
committer User Two <user2@example.com> 1749230009 +0200
gpgsig -----BEGIN SSH SIGNATURE-----
+1 -1
View File
@@ -365,7 +365,7 @@ func AllHeadCommitsVerified(ctx context.Context, pr *issues_model.PullRequest, g
if err != nil {
return false, err
}
commitList, err := headCommit.CommitsBeforeUntil(git.RefNameFromCommit(mergeBaseCommit))
commitList, err := headCommit.CommitsBeforeUntil(gitRepo, git.RefNameFromCommit(mergeBaseCommit))
if err != nil {
return false, err
}
+4 -4
View File
@@ -291,7 +291,7 @@ func (r *Repository) RefTypeNameSubURL() string {
// GetEditorconfig returns the .editorconfig definition if found in the
// HEAD of the default repo branch.
func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) {
func (r *Repository) GetEditorconfig(ctx context.Context, optCommit ...*git.Commit) (cfg *editorconfig.Editorconfig, warning, err error) {
if r.GitRepo == nil {
return nil, nil, nil
}
@@ -306,14 +306,14 @@ func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfi
return nil, nil, err
}
}
treeEntry, err := commit.GetTreeEntryByPath(".editorconfig")
treeEntry, err := commit.GetTreeEntryByPath(ctx, r.GitRepo, ".editorconfig")
if err != nil {
return nil, nil, err
}
if treeEntry.Blob().Size() >= setting.UI.MaxDisplayFileSize {
if treeEntry.Blob(r.GitRepo).Size() >= setting.UI.MaxDisplayFileSize {
return nil, nil, git.ErrNotExist{ID: "", RelPath: ".editorconfig"}
}
reader, err := treeEntry.Blob().DataAsync()
reader, err := treeEntry.Blob(r.GitRepo).DataAsync()
if err != nil {
return nil, nil, err
}
+13 -13
View File
@@ -523,7 +523,7 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
}, nil
}
func getActionWorkflowEntry(ctx context.Context, repo *repo_model.Repository, commit *git.Commit, refName git.RefName, folder string, entry *git.TreeEntry) *api.ActionWorkflow {
func getActionWorkflowEntry(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, refName git.RefName, folder string, entry *git.TreeEntry) *api.ActionWorkflow {
cfgUnit := repo.MustGetUnit(ctx, unit.TypeActions)
cfg := cfgUnit.ActionsConfig()
@@ -554,7 +554,7 @@ func getActionWorkflowEntry(ctx context.Context, repo *repo_model.Repository, co
createdAt := commit.Author.When
updatedAt := commit.Author.When
content, err := actions.GetContentFromEntry(entry)
content, err := actions.GetContentFromEntry(gitRepo, entry)
name := entry.Name()
if err == nil {
workflow, err := model.ReadWorkflow(bytes.NewReader(content))
@@ -589,26 +589,26 @@ func ListActionWorkflows(ctx context.Context, gitrepo *git.Repository, repo *rep
return nil, err
}
folder, entries, err := actions.ListWorkflows(defaultBranchCommit)
folder, entries, err := actions.ListWorkflows(ctx, gitrepo, defaultBranchCommit)
if err != nil {
return nil, err
}
workflows := make([]*api.ActionWorkflow, len(entries))
for i, entry := range entries {
workflows[i] = getActionWorkflowEntry(ctx, repo, defaultBranchCommit, git.RefNameFromBranch(repo.DefaultBranch), folder, entry)
workflows[i] = getActionWorkflowEntry(ctx, repo, gitrepo, defaultBranchCommit, git.RefNameFromBranch(repo.DefaultBranch), folder, entry)
}
return workflows, nil
}
func GetActionWorkflow(ctx context.Context, gitrepo *git.Repository, repo *repo_model.Repository, workflowID string) (*api.ActionWorkflow, error) {
defaultBranchCommit, err := gitrepo.GetBranchCommit(repo.DefaultBranch)
func GetActionWorkflow(ctx context.Context, gitRepo *git.Repository, repo *repo_model.Repository, workflowID string) (*api.ActionWorkflow, error) {
defaultBranchCommit, err := gitRepo.GetBranchCommit(repo.DefaultBranch)
if err != nil {
return nil, err
}
return getActionWorkflowFromCommit(ctx, repo, defaultBranchCommit, git.RefNameFromBranch(repo.DefaultBranch), workflowID)
return getActionWorkflowFromCommit(ctx, repo, gitRepo, defaultBranchCommit, git.RefNameFromBranch(repo.DefaultBranch), workflowID)
}
func GetActionWorkflowByRef(ctx context.Context, gitrepo *git.Repository, repo *repo_model.Repository, workflowID string, ref git.RefName) (*api.ActionWorkflow, error) {
@@ -625,18 +625,18 @@ func GetActionWorkflowByRef(ctx context.Context, gitrepo *git.Repository, repo *
return nil, err
}
return getActionWorkflowFromCommit(ctx, repo, refCommit, ref, workflowID)
return getActionWorkflowFromCommit(ctx, repo, gitrepo, refCommit, ref, workflowID)
}
func getActionWorkflowFromCommit(ctx context.Context, repo *repo_model.Repository, commit *git.Commit, refName git.RefName, workflowID string) (*api.ActionWorkflow, error) {
folder, entries, err := actions.ListWorkflows(commit)
func getActionWorkflowFromCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, refName git.RefName, workflowID string) (*api.ActionWorkflow, error) {
folder, entries, err := actions.ListWorkflows(ctx, gitRepo, commit)
if err != nil {
return nil, err
}
for _, entry := range entries {
if entry.Name() == workflowID {
return getActionWorkflowEntry(ctx, repo, commit, refName, folder, entry), nil
return getActionWorkflowEntry(ctx, repo, gitRepo, commit, refName, folder, entry), nil
}
}
@@ -650,7 +650,7 @@ func GetScopedActionWorkflow(ctx context.Context, sourceGitRepo *git.Repository,
return nil, err
}
folder, entries, err := actions.ListScopedWorkflows(commit)
folder, entries, err := actions.ListScopedWorkflows(ctx, sourceGitRepo, commit)
if err != nil {
return nil, err
}
@@ -658,7 +658,7 @@ func GetScopedActionWorkflow(ctx context.Context, sourceGitRepo *git.Repository,
for _, entry := range entries {
if entry.Name() == workflowID {
// An empty ref pins HTMLURL to commit (the run's WorkflowCommitSHA) rather than the moving default branch.
wf := getActionWorkflowEntry(ctx, sourceRepo, commit, git.RefName(""), folder, entry)
wf := getActionWorkflowEntry(ctx, sourceRepo, sourceGitRepo, commit, "", folder, entry)
// TODO: a scoped workflow has no repo-level representation on the source: the workflow API scans WORKFLOW_DIRS (not SCOPED_WORKFLOW_DIRS),
// and the badge only reflects the source's repo-level runs, so neither link resolves a scoped workflow.
// Blank them for now and populate once a scoped-aware workflow/badge endpoint exists.
+1 -1
View File
@@ -100,7 +100,7 @@ func validateGitDiffTreeArguments(gitRepo *git.Repository, useMergeBase bool, ba
return false, objectFormat.EmptyTree().String(), headCommitID, nil
}
baseCommit, err := headCommit.Parent(0)
baseCommit, err := headCommit.Parent(gitRepo, 0)
if err != nil {
return false, "", "", fmt.Errorf("baseSha is '', attempted to use parent of commit %s, got error: %v", headCommit.ID.String(), err)
}
+11 -11
View File
@@ -477,17 +477,17 @@ type DiffLimitedContent struct {
}
// GetTailSectionAndLimitedContent creates a fake DiffLineSection if the last section is not the end of the file
func (diffFile *DiffFile) GetTailSectionAndLimitedContent(leftCommit, rightCommit *git.Commit) (_ *DiffSection, diffLimitedContent DiffLimitedContent) {
func (diffFile *DiffFile) GetTailSectionAndLimitedContent(ctx context.Context, gitRepo *git.Repository, leftCommit, rightCommit *git.Commit) (_ *DiffSection, diffLimitedContent DiffLimitedContent) {
var leftLineCount, rightLineCount int
diffLimitedContent = DiffLimitedContent{}
if diffFile.IsBin || diffFile.IsLFSFile {
return nil, diffLimitedContent
}
if (diffFile.Type == DiffFileDel || diffFile.Type == DiffFileChange) && leftCommit != nil {
leftLineCount, diffLimitedContent.LeftContent = getCommitFileLineCountAndLimitedContent(leftCommit, diffFile.OldName)
leftLineCount, diffLimitedContent.LeftContent = getCommitFileLineCountAndLimitedContent(ctx, gitRepo, leftCommit, diffFile.OldName)
}
if (diffFile.Type == DiffFileAdd || diffFile.Type == DiffFileChange) && rightCommit != nil {
rightLineCount, diffLimitedContent.RightContent = getCommitFileLineCountAndLimitedContent(rightCommit, diffFile.OldName)
rightLineCount, diffLimitedContent.RightContent = getCommitFileLineCountAndLimitedContent(ctx, gitRepo, rightCommit, diffFile.OldName)
}
if len(diffFile.Sections) == 0 || diffFile.Type != DiffFileChange {
return nil, diffLimitedContent
@@ -577,8 +577,8 @@ func (l *limitByteWriter) Write(p []byte) (n int, err error) {
return l.buf.Write(p)
}
func getCommitFileLineCountAndLimitedContent(commit *git.Commit, filePath string) (lineCount int, limitWriter *limitByteWriter) {
blob, err := commit.GetBlobByPath(filePath)
func getCommitFileLineCountAndLimitedContent(ctx context.Context, gitRepo *git.Repository, commit *git.Commit, filePath string) (lineCount int, limitWriter *limitByteWriter) {
blob, err := commit.GetBlobByPath(ctx, gitRepo, filePath)
if err != nil {
return 0, nil
}
@@ -1256,7 +1256,7 @@ func guessBeforeCommitForDiff(gitRepo *git.Repository, beforeCommitID string, af
actualBeforeCommitID = commitObjectFormat.EmptyTree()
} else {
if isBeforeCommitIDEmpty {
actualBeforeCommit, err = afterCommit.Parent(0)
actualBeforeCommit, err = afterCommit.Parent(gitRepo, 0)
} else {
actualBeforeCommit, err = gitRepo.GetCommit(beforeCommitID)
}
@@ -1360,7 +1360,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
// Populate Submodule URLs
if diffFile.SubmoduleDiffInfo != nil {
diffFile.SubmoduleDiffInfo.PopulateURL(repoLink, diffFile, beforeCommit, afterCommit)
diffFile.SubmoduleDiffInfo.PopulateURL(ctx, repoLink, gitRepo, diffFile, beforeCommit, afterCommit)
}
if !isVendored.Has() {
@@ -1372,7 +1372,7 @@ func GetDiffForRender(ctx context.Context, repoLink string, gitRepo *git.Reposit
isGenerated = optional.Some(analyze.IsGenerated(diffFile.Name))
}
diffFile.IsGenerated = isGenerated.Value()
tailSection, limitedContent := diffFile.GetTailSectionAndLimitedContent(beforeCommit, afterCommit)
tailSection, limitedContent := diffFile.GetTailSectionAndLimitedContent(ctx, gitRepo, beforeCommit, afterCommit)
if tailSection != nil {
diffFile.Sections = append(diffFile.Sections, tailSection)
}
@@ -1542,18 +1542,18 @@ func CommentAsDiff(ctx context.Context, c *issues_model.Comment) (*Diff, error)
}
// GeneratePatchForUnchangedLine creates a patch showing code context for an unchanged line
func GeneratePatchForUnchangedLine(gitRepo *git.Repository, commitID, treePath string, line int64, contextLines int) (string, error) {
func GeneratePatchForUnchangedLine(ctx context.Context, gitRepo *git.Repository, commitID, treePath string, line int64, contextLines int) (string, error) {
commit, err := gitRepo.GetCommit(commitID)
if err != nil {
return "", fmt.Errorf("GetCommit: %w", err)
}
entry, err := commit.GetTreeEntryByPath(treePath)
entry, err := commit.GetTreeEntryByPath(ctx, gitRepo, treePath)
if err != nil {
return "", fmt.Errorf("GetTreeEntryByPath: %w", err)
}
blob := entry.Blob()
blob := entry.Blob(gitRepo)
dataRc, err := blob.DataAsync()
if err != nil {
return "", fmt.Errorf("DataAsync: %w", err)
+2 -2
View File
@@ -20,7 +20,7 @@ type SubmoduleDiffInfo struct {
PreviousRefID string
}
func (si *SubmoduleDiffInfo) PopulateURL(repoLink string, diffFile *DiffFile, leftCommit, rightCommit *git.Commit) {
func (si *SubmoduleDiffInfo) PopulateURL(ctx context.Context, repoLink string, gitRepo *git.Repository, diffFile *DiffFile, leftCommit, rightCommit *git.Commit) {
si.SubmoduleName = diffFile.Name
submoduleCommit := rightCommit // If the submodule is added or updated, check at the right commit
if diffFile.IsDeleted {
@@ -31,7 +31,7 @@ func (si *SubmoduleDiffInfo) PopulateURL(repoLink string, diffFile *DiffFile, le
}
submoduleFullPath := diffFile.GetDiffFileName()
submodule, err := submoduleCommit.GetSubModule(submoduleFullPath)
submodule, err := submoduleCommit.GetSubModule(ctx, gitRepo, submoduleFullPath)
if err != nil {
log.Error("Unable to PopulateURL for submodule %q: GetSubModule: %v", submoduleFullPath, err)
return // ignore the error, do not cause 500 errors for end users
+1 -1
View File
@@ -68,7 +68,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
var data string
for _, file := range codeOwnerFiles {
if blob, err := commit.GetBlobByPath(file); err == nil {
if blob, err := commit.GetBlobByPath(ctx, repo, file); err == nil {
data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
if err == nil {
break
+16 -15
View File
@@ -4,6 +4,7 @@
package issue
import (
"context"
"fmt"
"net/url"
"path"
@@ -47,17 +48,17 @@ func GetDefaultTemplateConfig() api.IssueConfig {
// GetTemplateConfig loads the given issue config file.
// It never returns a nil config.
func GetTemplateConfig(gitRepo *git.Repository, path string, commit *git.Commit) (api.IssueConfig, error) {
func GetTemplateConfig(ctx context.Context, gitRepo *git.Repository, path string, commit *git.Commit) (api.IssueConfig, error) {
if gitRepo == nil {
return GetDefaultTemplateConfig(), nil
}
treeEntry, err := commit.GetTreeEntryByPath(path)
treeEntry, err := commit.GetTreeEntryByPath(ctx, gitRepo, path)
if err != nil {
return GetDefaultTemplateConfig(), err
}
reader, err := treeEntry.Blob().DataAsync()
reader, err := treeEntry.Blob(gitRepo).DataAsync()
if err != nil {
log.Debug("DataAsync: %v", err)
return GetDefaultTemplateConfig(), nil
@@ -109,7 +110,7 @@ func IsTemplateConfig(path string) bool {
// ParseTemplatesFromDefaultBranch parses the issue templates in the repo's default branch,
// returns valid templates and the errors of invalid template files (the errors map is guaranteed to be non-nil).
func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repository) (ret struct {
func ParseTemplatesFromDefaultBranch(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) (ret struct {
IssueTemplates []*api.IssueTemplate
TemplateErrors map[string]error
},
@@ -125,12 +126,12 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
}
for _, dirName := range templateDirCandidates {
tree, err := commit.SubTree(dirName)
tree, err := commit.SubTree(ctx, gitRepo, dirName)
if err != nil {
log.Debug("get sub tree of %s: %v", dirName, err)
continue
}
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
log.Debug("list entries in %s: %v", dirName, err)
return ret
@@ -140,7 +141,7 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
continue
}
fullName := path.Join(dirName, entry.Name())
if it, err := template.UnmarshalFromEntry(entry, dirName); err != nil {
if it, err := template.UnmarshalFromEntry(gitRepo, entry, dirName); err != nil {
ret.TemplateErrors[fullName] = err
} else {
if !strings.HasPrefix(it.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
@@ -155,7 +156,7 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
// GetTemplateConfigFromDefaultBranch returns the issue config for this repo.
// It never returns a nil config.
func GetTemplateConfigFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repository) (api.IssueConfig, error) {
func GetTemplateConfigFromDefaultBranch(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) (api.IssueConfig, error) {
if repo.IsEmpty {
return GetDefaultTemplateConfig(), nil
}
@@ -166,24 +167,24 @@ func GetTemplateConfigFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repo
}
for _, configName := range templateConfigCandidates {
if _, err := commit.GetTreeEntryByPath(configName + ".yaml"); err == nil {
return GetTemplateConfig(gitRepo, configName+".yaml", commit)
if _, err := commit.GetTreeEntryByPath(ctx, gitRepo, configName+".yaml"); err == nil {
return GetTemplateConfig(ctx, gitRepo, configName+".yaml", commit)
}
if _, err := commit.GetTreeEntryByPath(configName + ".yml"); err == nil {
return GetTemplateConfig(gitRepo, configName+".yml", commit)
if _, err := commit.GetTreeEntryByPath(ctx, gitRepo, configName+".yml"); err == nil {
return GetTemplateConfig(ctx, gitRepo, configName+".yml", commit)
}
}
return GetDefaultTemplateConfig(), nil
}
func HasTemplatesOrContactLinks(repo *repo.Repository, gitRepo *git.Repository) bool {
ret := ParseTemplatesFromDefaultBranch(repo, gitRepo)
func HasTemplatesOrContactLinks(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) bool {
ret := ParseTemplatesFromDefaultBranch(ctx, repo, gitRepo)
if len(ret.IssueTemplates) > 0 {
return true
}
issueConfig, _ := GetTemplateConfigFromDefaultBranch(repo, gitRepo)
issueConfig, _ := GetTemplateConfigFromDefaultBranch(ctx, repo, gitRepo)
return len(issueConfig.ContactLinks) > 0
}
+1 -1
View File
@@ -62,7 +62,7 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie
}
language, _ := languagestats.GetFileLanguage(ctx, gitRepo, opts.CommitID, opts.FilePath)
blob, err := commit.GetBlobByPath(opts.FilePath)
blob, err := commit.GetBlobByPath(ctx, gitRepo, opts.FilePath)
if err != nil {
return "", err
}
+1 -1
View File
@@ -72,7 +72,7 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue
if err != nil {
return "", "", err
}
templateContent, err := commit.GetFileContent(templateFilepath, setting.Repository.PullRequest.DefaultMergeMessageSize)
templateContent, err := commit.GetFileContent(ctx, baseGitRepo, templateFilepath, setting.Repository.PullRequest.DefaultMergeMessageSize)
if err != nil {
if !git.IsErrNotExist(err) {
return "", "", err
+1 -1
View File
@@ -1046,7 +1046,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, br
return false, err
}
}
return baseCommit.HasPreviousCommit(headCommit.ID)
return baseCommit.HasPreviousCommit(ctx, baseGitRepo, headCommit.ID)
}
type CommitInfo struct {
+1 -1
View File
@@ -284,7 +284,7 @@ func createCodeComment(ctx context.Context, doer *user_model.User, repo *repo_mo
// If patch is still empty (unchanged line), generate code context
if patch == "" && commitID != "" {
patch, err = gitdiff.GeneratePatchForUnchangedLine(gitRepo, commitID, treePath, line, setting.UI.CodeCommentLines)
patch, err = gitdiff.GeneratePatchForUnchangedLine(ctx, gitRepo, commitID, treePath, line, setting.UI.CodeCommentLines)
if err != nil {
// Log the error but don't fail comment creation
log.Debug("Unable to generate patch for unchanged line (file=%s, line=%d, commit=%s): %v", treePath, line, commitID, err)
+2 -2
View File
@@ -526,7 +526,7 @@ func UpdateBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git
return nil
}
isForcePush, err := newCommit.IsForcePush(branch.CommitID)
isForcePush, err := newCommit.IsForcePush(ctx, gitRepo, branch.CommitID)
if err != nil {
return err
}
@@ -811,7 +811,7 @@ func GetBranchDivergingInfo(ctx reqctx.RequestContext, baseRepo *repo_model.Repo
if err != nil {
return nil, err
}
hasPreviousCommit, _ := headCommit.HasPreviousCommit(baseCommitID)
hasPreviousCommit, _ := headCommit.HasPreviousCommit(ctx, headGitRepo, baseCommitID)
info.BaseHasNewCommits = !hasPreviousCommit
return info, nil
}
+1 -1
View File
@@ -29,5 +29,5 @@ func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
gitRepo.LastCommitCache = git.NewLastCommitCache(commitsCount, repo.FullName(), gitRepo, cache.GetCache())
}
return commit.CacheCommit(ctx)
return commit.CacheCommit(ctx, gitRepo)
}
+1 -1
View File
@@ -147,7 +147,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
return nil, err
}
fileCommitResponse, _ := GetFileCommitResponse(repo, commit) // ok if fails, then will be nil
fileCommitResponse, _ := GetFileCommitResponse(repo, gitRepo, commit) // ok if fails, then will be nil
verification := GetPayloadCommitVerification(ctx, commit)
fileResponse := &structs.FileResponse{
Commit: fileCommitResponse,

Some files were not shown because too many files have changed in this diff Show More