mirror of
https://github.com/go-gitea/gitea.git
synced 2026-08-06 19:08:57 +09:00
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:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 := ¬es.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
|
||||
}
|
||||
@@ -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 = ""
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,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(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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"})
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: ""})
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ""
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"))
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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-----
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user