mirror of
https://github.com/go-gitea/gitea.git
synced 2025-10-27 05:55:21 +08:00
Merge 61032b8b08 into bc50431e8b
This commit is contained in:
commit
c9940ab157
@ -44,12 +44,12 @@ func IsWorkflow(path string) bool {
|
||||
return strings.HasPrefix(path, ".gitea/workflows") || strings.HasPrefix(path, ".github/workflows")
|
||||
}
|
||||
|
||||
func ListWorkflows(commit *git.Commit) (string, git.Entries, error) {
|
||||
func ListWorkflows(rootTree *git.Tree) (string, git.Entries, error) {
|
||||
rpath := ".gitea/workflows"
|
||||
tree, err := commit.SubTree(rpath)
|
||||
tree, err := rootTree.SubTree(rpath)
|
||||
if _, ok := err.(git.ErrNotExist); ok {
|
||||
rpath = ".github/workflows"
|
||||
tree, err = commit.SubTree(rpath)
|
||||
tree, err = rootTree.SubTree(rpath)
|
||||
}
|
||||
if _, ok := err.(git.ErrNotExist); ok {
|
||||
return "", nil, nil
|
||||
@ -105,7 +105,7 @@ func DetectWorkflows(
|
||||
payload api.Payloader,
|
||||
detectSchedule bool,
|
||||
) ([]*DetectedWorkflow, []*DetectedWorkflow, error) {
|
||||
_, entries, err := ListWorkflows(commit)
|
||||
_, entries, err := ListWorkflows(git.NewTree(gitRepo, commit.TreeID))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -150,7 +150,7 @@ func DetectWorkflows(
|
||||
}
|
||||
|
||||
func DetectScheduledWorkflows(gitRepo *git.Repository, commit *git.Commit) ([]*DetectedWorkflow, error) {
|
||||
_, entries, err := ListWorkflows(commit)
|
||||
_, entries, err := ListWorkflows(git.NewTree(gitRepo, commit.TreeID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -204,7 +204,7 @@ func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent web
|
||||
|
||||
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,
|
||||
@ -256,7 +256,7 @@ func detectMatched(gitRepo *git.Repository, commit *git.Commit, triggedEvent web
|
||||
}
|
||||
}
|
||||
|
||||
func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool {
|
||||
func matchPushEvent(gitRepo *git.Repository, commit *git.Commit, pushPayload *api.PushPayload, evt *jobparser.Event) bool {
|
||||
// with no special filter parameters
|
||||
if len(evt.Acts()) == 0 {
|
||||
return true
|
||||
@ -322,7 +322,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
|
||||
filesChanged, err := gitRepo.GetFilesChangedBetween(pushPayload.Before, commit.ID.String())
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
@ -339,7 +339,7 @@ func matchPushEvent(commit *git.Commit, pushPayload *api.PushPayload, evt *jobpa
|
||||
matchTimes++
|
||||
break
|
||||
}
|
||||
filesChanged, err := commit.GetFilesChangedSinceCommit(pushPayload.Before)
|
||||
filesChanged, err := gitRepo.GetFilesChangedBetween(pushPayload.Before, commit.ID.String())
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", commit.ID.String(), err)
|
||||
} else {
|
||||
@ -486,7 +486,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
|
||||
matchTimes++
|
||||
}
|
||||
case "paths":
|
||||
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
|
||||
filesChanged, err := gitRepo.GetFilesChangedBetween(prPayload.PullRequest.MergeBase, headCommit.ID.String())
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
|
||||
} else {
|
||||
@ -499,7 +499,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa
|
||||
}
|
||||
}
|
||||
case "paths-ignore":
|
||||
filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase)
|
||||
filesChanged, err := gitRepo.GetFilesChangedBetween(prPayload.PullRequest.MergeBase, headCommit.ID.String())
|
||||
if err != nil {
|
||||
log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err)
|
||||
} else {
|
||||
|
||||
@ -12,10 +12,10 @@ type EntryInfo struct {
|
||||
IsOpen bool
|
||||
}
|
||||
|
||||
func EntryInfoFromGitTreeEntry(commit *git.Commit, fullPath string, gitEntry *git.TreeEntry) *EntryInfo {
|
||||
func EntryInfoFromGitTreeEntry(tree *git.Tree, 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(tree, fullPath, gitEntry); err == nil && res.TargetEntry.IsDir() {
|
||||
ret.SymlinkToMode = res.TargetEntry.Mode()
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ func (r *BlameReader) Close() error {
|
||||
}
|
||||
|
||||
// CreateBlameReader creates reader for given repository, commit and file
|
||||
func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, err error) {
|
||||
func CreateBlameReader(ctx context.Context, repo *Repository, objectFormat ObjectFormat, repoPath string, commit *Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, err error) {
|
||||
var ignoreRevsFileName string
|
||||
var ignoreRevsFileCleanup func()
|
||||
defer func() {
|
||||
@ -145,7 +145,8 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
|
||||
cmd := gitcmd.NewCommand("blame", "--porcelain")
|
||||
|
||||
if DefaultFeatures().CheckVersionAtLeast("2.23") && !bypassBlameIgnore {
|
||||
ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(commit)
|
||||
tree := NewTree(repo, commit.TreeID)
|
||||
ignoreRevsFileName, ignoreRevsFileCleanup, err = tryCreateBlameIgnoreRevsFile(tree)
|
||||
if err != nil && !IsErrNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
@ -190,8 +191,8 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
|
||||
}, nil
|
||||
}
|
||||
|
||||
func tryCreateBlameIgnoreRevsFile(commit *Commit) (string, func(), error) {
|
||||
entry, err := commit.GetTreeEntryByPath(".git-blame-ignore-revs")
|
||||
func tryCreateBlameIgnoreRevsFile(tree *Tree) (string, func(), error) {
|
||||
entry, err := tree.GetTreeEntryByPath(".git-blame-ignore-revs")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, bypass := range []bool{false, true} {
|
||||
blameReader, err := CreateBlameReader(ctx, Sha256ObjectFormat, "./tests/repos/repo5_pulls_sha256", commit, "README.md", bypass)
|
||||
blameReader, err := CreateBlameReader(ctx, repo, Sha256ObjectFormat, "./tests/repos/repo5_pulls_sha256", commit, "README.md", bypass)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, blameReader)
|
||||
defer blameReader.Close()
|
||||
@ -131,7 +131,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, "./tests/repos/repo6_blame_sha256", commit, "blame.txt", c.Bypass)
|
||||
blameReader, err := CreateBlameReader(ctx, repo, objectFormat, "./tests/repos/repo6_blame_sha256", commit, "blame.txt", c.Bypass)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, blameReader)
|
||||
defer blameReader.Close()
|
||||
|
||||
@ -42,7 +42,7 @@ func TestReadingBlameOutput(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, bypass := range []bool{false, true} {
|
||||
blameReader, err := CreateBlameReader(ctx, Sha1ObjectFormat, "./tests/repos/repo5_pulls", commit, "README.md", bypass)
|
||||
blameReader, err := CreateBlameReader(ctx, repo, Sha1ObjectFormat, "./tests/repos/repo5_pulls", commit, "README.md", bypass)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, blameReader)
|
||||
defer blameReader.Close()
|
||||
@ -127,7 +127,7 @@ func TestReadingBlameOutput(t *testing.T) {
|
||||
commit, err := repo.GetCommit(c.CommitID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
blameReader, err := CreateBlameReader(ctx, objectFormat, "./tests/repos/repo6_blame", commit, "blame.txt", c.Bypass)
|
||||
blameReader, err := CreateBlameReader(ctx, repo, objectFormat, "./tests/repos/repo6_blame", commit, "blame.txt", c.Bypass)
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, blameReader)
|
||||
defer blameReader.Close()
|
||||
|
||||
@ -8,9 +8,7 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -21,16 +19,13 @@ 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"
|
||||
|
||||
ID ObjectID
|
||||
TreeID ObjectID
|
||||
Parents []ObjectID // ID strings
|
||||
Author *Signature // never nil
|
||||
Committer *Signature // never nil
|
||||
CommitMessage string
|
||||
Signature *CommitSignature
|
||||
|
||||
Parents []ObjectID // ID strings
|
||||
submoduleCache *ObjectCache[*SubModule]
|
||||
}
|
||||
|
||||
// CommitSignature represents a git commit signature part.
|
||||
@ -59,33 +54,12 @@ func (c *Commit) ParentID(n int) (ObjectID, error) {
|
||||
return c.Parents[n], nil
|
||||
}
|
||||
|
||||
// Parent returns n-th parent (0-based index) of the commit.
|
||||
func (c *Commit) Parent(n int) (*Commit, error) {
|
||||
id, err := c.ParentID(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parent, err := c.repo.getCommit(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
// ParentCount returns number of parents of the commit.
|
||||
// 0 if this is the root commit, otherwise 1,2, etc.
|
||||
func (c *Commit) ParentCount() int {
|
||||
return len(c.Parents)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
return c.repo.getCommitByPathWithID(c.ID, relpath)
|
||||
}
|
||||
|
||||
// AddChanges marks local changes to be ready for commit.
|
||||
func AddChanges(ctx context.Context, repoPath string, all bool, files ...string) error {
|
||||
cmd := gitcmd.NewCommand().AddArguments("add")
|
||||
@ -181,81 +155,6 @@ func CommitsCount(ctx context.Context, opts CommitsCountOptions) (int64, error)
|
||||
return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64)
|
||||
}
|
||||
|
||||
// CommitsCount returns number of total commits of until current revision.
|
||||
func (c *Commit) CommitsCount() (int64, error) {
|
||||
return CommitsCount(c.repo.Ctx, CommitsCountOptions{
|
||||
RepoPath: c.repo.Path,
|
||||
Revision: []string{c.ID.String()},
|
||||
})
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
|
||||
// CommitsBefore returns all the commits before current revision
|
||||
func (c *Commit) CommitsBefore() ([]*Commit, error) {
|
||||
return c.repo.getCommitsBefore(c.ID)
|
||||
}
|
||||
|
||||
// HasPreviousCommit returns true if a given commitHash is contained in commit's parents
|
||||
func (c *Commit) HasPreviousCommit(objectID ObjectID) (bool, error) {
|
||||
this := c.ID.String()
|
||||
that := objectID.String()
|
||||
|
||||
if this == that {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
_, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").
|
||||
AddDynamicArguments(that, this).
|
||||
WithDir(c.repo.Path).
|
||||
RunStdString(c.repo.Ctx)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
var exitError *exec.ExitError
|
||||
if errors.As(err, &exitError) {
|
||||
if exitError.ProcessState.ExitCode() == 1 && len(exitError.Stderr) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 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()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if oldCommitID == objectFormat.EmptyObjectID().String() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
oldCommit, err := c.repo.GetCommit(oldCommitID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
hasPreviousCommit, err := c.HasPreviousCommit(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)
|
||||
}
|
||||
|
||||
// CommitsBeforeUntil returns the commits between commitID to current revision
|
||||
func (c *Commit) CommitsBeforeUntil(commitID string) ([]*Commit, error) {
|
||||
endCommit, err := c.repo.GetCommit(commitID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.repo.CommitsBetween(c, endCommit)
|
||||
}
|
||||
|
||||
// SearchCommitsOptions specify the parameters for SearchCommits
|
||||
type SearchCommitsOptions struct {
|
||||
Keywords []string
|
||||
@ -295,82 +194,6 @@ 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)
|
||||
}
|
||||
|
||||
// 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())
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// 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)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
r, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
if limit > 0 {
|
||||
bs := make([]byte, limit)
|
||||
n, err := util.ReadAtMost(r, bs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bs[:n]), nil
|
||||
}
|
||||
|
||||
bytes, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
|
||||
func (c *Commit) GetBranchName() (string, error) {
|
||||
cmd := gitcmd.NewCommand("name-rev")
|
||||
if DefaultFeatures().CheckVersionAtLeast("2.13.0") {
|
||||
cmd.AddArguments("--exclude", "refs/tags/*")
|
||||
}
|
||||
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
||||
data, _, err := cmd.WithDir(c.repo.Path).RunStdString(c.repo.Ctx)
|
||||
if err != nil {
|
||||
// handle special case where git can not describe commit
|
||||
if strings.Contains(err.Error(), "cannot describe") {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
// name-rev commitID output will be "master" or "master~12"
|
||||
return strings.SplitN(strings.TrimSpace(data), "~", 2)[0], nil
|
||||
}
|
||||
|
||||
// CommitFileStatus represents status of files in a commit.
|
||||
type CommitFileStatus struct {
|
||||
Added []string
|
||||
@ -465,14 +288,6 @@ func GetFullCommitID(ctx context.Context, repoPath, shortID string) (string, err
|
||||
return strings.TrimSpace(commitID), nil
|
||||
}
|
||||
|
||||
// GetRepositoryDefaultPublicGPGKey returns the default public key for this commit
|
||||
func (c *Commit) GetRepositoryDefaultPublicGPGKey(forceUpdate bool) (*GPGSettings, error) {
|
||||
if c.repo == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return c.repo.GetDefaultPublicGPGKey(forceUpdate)
|
||||
}
|
||||
|
||||
func IsStringLikelyCommitID(objFmt ObjectFormat, s string, minLength ...int) bool {
|
||||
maxLen := 64 // sha256
|
||||
if objFmt != nil {
|
||||
|
||||
@ -66,6 +66,7 @@ func convertPGPSignature(c *object.Commit) *CommitSignature {
|
||||
func convertCommit(c *object.Commit) *Commit {
|
||||
return &Commit{
|
||||
ID: ParseGogitHash(c.Hash),
|
||||
TreeID: ParseGogitHash(c.TreeHash),
|
||||
CommitMessage: c.Message,
|
||||
Committer: &c.Committer,
|
||||
Author: &c.Author,
|
||||
|
||||
@ -7,17 +7,17 @@ package git
|
||||
type CommitInfo struct {
|
||||
Entry *TreeEntry
|
||||
Commit *Commit
|
||||
SubmoduleFile *CommitSubmoduleFile
|
||||
SubmoduleFile *SubmoduleFile
|
||||
}
|
||||
|
||||
func GetCommitInfoSubmoduleFile(repoLink, fullPath string, commit *Commit, refCommitID ObjectID) (*CommitSubmoduleFile, error) {
|
||||
submodule, err := commit.GetSubModule(fullPath)
|
||||
func GetCommitInfoSubmoduleFile(gitRepo *Repository, repoLink, fullPath string, treeID, refCommitID ObjectID) (*SubmoduleFile, error) {
|
||||
submodule, err := NewTree(gitRepo, treeID).GetSubModule(fullPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if submodule == nil {
|
||||
// unable to find submodule from ".gitmodules" file
|
||||
return NewCommitSubmoduleFile(repoLink, fullPath, "", refCommitID.String()), nil
|
||||
return NewSubmoduleFile(repoLink, fullPath, "", refCommitID.String()), nil
|
||||
}
|
||||
return NewCommitSubmoduleFile(repoLink, fullPath, submodule.URL, refCommitID.String()), nil
|
||||
return NewSubmoduleFile(repoLink, fullPath, submodule.URL, refCommitID.String()), nil
|
||||
}
|
||||
|
||||
@ -16,7 +16,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, gitRepo *Repository, repoLink string, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
|
||||
entryPaths := make([]string, len(tes)+1)
|
||||
// Get the commit for the treePath itself
|
||||
entryPaths[0] = ""
|
||||
@ -24,7 +24,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
|
||||
entryPaths[i+1] = entry.Name()
|
||||
}
|
||||
|
||||
commitNodeIndex, commitGraphFile := commit.repo.CommitNodeIndex()
|
||||
commitNodeIndex, commitGraphFile := gitRepo.CommitNodeIndex()
|
||||
if commitGraphFile != nil {
|
||||
defer commitGraphFile.Close()
|
||||
}
|
||||
@ -35,14 +35,14 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
|
||||
}
|
||||
|
||||
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 {
|
||||
revs2, err := GetLastCommitForPaths(ctx, commit.repo.LastCommitCache, c, treePath, unHitPaths)
|
||||
revs2, err := GetLastCommitForPaths(ctx, gitRepo.LastCommitCache, c, treePath, unHitPaths)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -58,7 +58,7 @@ func (tes Entries) GetCommitsInfo(ctx context.Context, repoLink string, commit *
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
commit.repo.gogitStorage.Close()
|
||||
gitRepo.gogitStorage.Close()
|
||||
|
||||
commitsInfo := make([]CommitInfo, len(tes))
|
||||
for i, entry := range tes {
|
||||
@ -73,7 +73,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(gitRepo, repoLink, path.Join(treePath, entry.Name()), commit.TreeID, entry.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@ -84,11 +84,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
|
||||
}
|
||||
|
||||
@ -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, gitRepo *Repository, repoLink string, 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(gitRepo, repoLink, path.Join(treePath, entry.Name()), commit.TreeID, 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
|
||||
}
|
||||
|
||||
@ -62,10 +62,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 := NewTree(repo1, commit.TreeID).SubTree(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.
|
||||
@ -83,7 +82,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(), repo1, "/any/repo-link", 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()
|
||||
@ -125,11 +124,12 @@ 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")
|
||||
tree := NewTree(bareRepo1, commit.TreeID)
|
||||
treeEntry, err := tree.GetTreeEntryByPath("file1.txt")
|
||||
require.NoError(t, err)
|
||||
cisf, err := GetCommitInfoSubmoduleFile("/any/repo-link", "file1.txt", commit, treeEntry.ID)
|
||||
cisf, err := GetCommitInfoSubmoduleFile(bareRepo1, "/any/repo-link", "file1.txt", commit.TreeID, treeEntry.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, &CommitSubmoduleFile{
|
||||
assert.Equal(t, &SubmoduleFile{
|
||||
repoLink: "/any/repo-link",
|
||||
fullPath: "file1.txt",
|
||||
refURL: "",
|
||||
@ -170,14 +170,14 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
|
||||
|
||||
if commit, err = repo.GetBranchCommit("master"); err != nil {
|
||||
b.Fatal(err)
|
||||
} else if entries, err = commit.Tree.ListEntries(); err != nil {
|
||||
} else if entries, err = NewTree(repo, commit.TreeID).ListEntries(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
entries.Sort()
|
||||
b.ResetTimer()
|
||||
b.Run(benchmark.name, func(b *testing.B) {
|
||||
for b.Loop() {
|
||||
_, _, err := entries.GetCommitsInfo(b.Context(), "/any/repo-link", commit, "")
|
||||
_, _, err := entries.GetCommitsInfo(b.Context(), repo, "/any/repo-link", commit, "")
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,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)
|
||||
@ -120,7 +120,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 += "\n\n"
|
||||
commitFromReader.Signature.Payload += "\n\n"
|
||||
@ -145,15 +145,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 := repo.HasPreviousCommit(commit, parentSHA)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, haz)
|
||||
|
||||
hazNot, err := commit.HasPreviousCommit(notParentSHA)
|
||||
hazNot, err := repo.HasPreviousCommit(commit, notParentSHA)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hazNot)
|
||||
|
||||
selfNot, err := commit.HasPreviousCommit(commit.ID)
|
||||
selfNot, err := repo.HasPreviousCommit(commit, commit.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, selfNot)
|
||||
}
|
||||
|
||||
@ -1,52 +0,0 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package git
|
||||
|
||||
type SubmoduleWebLink struct {
|
||||
RepoWebLink, CommitWebLink string
|
||||
}
|
||||
|
||||
// GetSubModules get all the submodules of current revision git tree
|
||||
func (c *Commit) GetSubModules() (*ObjectCache[*SubModule], error) {
|
||||
if c.submoduleCache != nil {
|
||||
return c.submoduleCache, nil
|
||||
}
|
||||
|
||||
entry, err := c.GetTreeEntryByPath(".gitmodules")
|
||||
if err != nil {
|
||||
if _, ok := err.(ErrNotExist); ok {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rd, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rd.Close()
|
||||
|
||||
// at the moment we do not strictly limit the size of the .gitmodules file because some users would have huge .gitmodules files (>1MB)
|
||||
c.submoduleCache, err = configParseSubModules(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.submoduleCache, nil
|
||||
}
|
||||
|
||||
// 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()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if modules != nil {
|
||||
if module, has := modules.Get(entryName); has {
|
||||
return module, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@ -88,7 +88,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)
|
||||
@ -116,7 +116,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 += "\n\n"
|
||||
commitFromReader.Signature.Payload += "\n\n"
|
||||
@ -152,7 +152,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)
|
||||
@ -179,7 +179,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 += "\n\n"
|
||||
commitFromReader.Signature.Payload += "\n\n"
|
||||
@ -199,15 +199,15 @@ func TestHasPreviousCommit(t *testing.T) {
|
||||
parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2")
|
||||
notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3")
|
||||
|
||||
haz, err := commit.HasPreviousCommit(parentSHA)
|
||||
haz, err := repo.HasPreviousCommit(commit, parentSHA)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, haz)
|
||||
|
||||
hazNot, err := commit.HasPreviousCommit(notParentSHA)
|
||||
hazNot, err := repo.HasPreviousCommit(commit, notParentSHA)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hazNot)
|
||||
|
||||
selfNot, err := commit.HasPreviousCommit(commit.ID)
|
||||
selfNot, err := repo.HasPreviousCommit(commit, commit.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, selfNot)
|
||||
}
|
||||
|
||||
@ -65,7 +65,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
|
||||
} else if commit.ParentCount() == 0 {
|
||||
cmd.AddArguments("show").AddDynamicArguments(endCommit).AddDashesAndList(files...)
|
||||
} else {
|
||||
c, err := commit.Parent(0)
|
||||
c, err := repo.ParentCommit(commit, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,7 +78,7 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
|
||||
} 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 := repo.ParentCommit(commit, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -48,7 +48,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, size))
|
||||
commit, err := git.CommitFromReader(sha, io.LimitReader(batchReader, size))
|
||||
if err != nil {
|
||||
log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
|
||||
return nil, err
|
||||
@ -57,7 +57,7 @@ func GetLanguageStats(repo *git.Repository, commitID string) (map[string]int64,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tree := commit.Tree
|
||||
tree := git.NewTree(repo, commit.TreeID)
|
||||
|
||||
entries, err := tree.ListEntriesRecursiveWithSize()
|
||||
if err != nil {
|
||||
|
||||
@ -13,21 +13,21 @@ import (
|
||||
)
|
||||
|
||||
// CacheCommit will cache the commit from the gitRepository
|
||||
func (c *Commit) CacheCommit(ctx context.Context) error {
|
||||
if c.repo.LastCommitCache == nil {
|
||||
func (repo *Repository) CacheCommit(ctx context.Context, c *Commit) error {
|
||||
if repo.LastCommitCache == nil {
|
||||
return nil
|
||||
}
|
||||
commitNodeIndex, _ := c.repo.CommitNodeIndex()
|
||||
commitNodeIndex, _ := repo.CommitNodeIndex()
|
||||
|
||||
index, err := commitNodeIndex.Get(plumbing.Hash(c.ID.RawValue()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.recursiveCache(ctx, index, &c.Tree, "", 1)
|
||||
return repo.recursiveCache(ctx, c, index, NewTree(repo, c.TreeID), "", 1)
|
||||
}
|
||||
|
||||
func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
|
||||
func (repo *Repository) recursiveCache(ctx context.Context, c *Commit, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
|
||||
if level == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -44,7 +44,7 @@ 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 := GetLastCommitForPaths(ctx, repo.LastCommitCache, index, treePath, entryPaths)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -55,7 +55,7 @@ func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.recursiveCache(ctx, index, subTree, entry, level-1); err != nil {
|
||||
if err := repo.recursiveCache(ctx, c, index, subTree, entry, level-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,14 +10,14 @@ import (
|
||||
)
|
||||
|
||||
// CacheCommit will cache the commit from the gitRepository
|
||||
func (c *Commit) CacheCommit(ctx context.Context) error {
|
||||
if c.repo.LastCommitCache == nil {
|
||||
func (repo *Repository) CacheCommit(ctx context.Context, c *Commit) error {
|
||||
if repo.LastCommitCache == nil {
|
||||
return nil
|
||||
}
|
||||
return c.recursiveCache(ctx, &c.Tree, "", 1)
|
||||
return repo.recursiveCache(ctx, c, NewTree(repo, c.TreeID), "", 1)
|
||||
}
|
||||
|
||||
func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string, level int) error {
|
||||
func (repo *Repository) recursiveCache(ctx context.Context, c *Commit, tree *Tree, treePath string, level int) error {
|
||||
if level == 0 {
|
||||
return nil
|
||||
}
|
||||
@ -32,7 +32,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, repo, c, treePath, entryPaths...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,7 +44,7 @@ func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := c.recursiveCache(ctx, subTree, treeEntry.Name(), level-1); err != nil {
|
||||
if err := repo.recursiveCache(ctx, c, subTree, treeEntry.Name(), level-1); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +298,7 @@ func (g *LogNameStatusRepoParser) Close() {
|
||||
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 := NewTree(repo, head.TreeID).SubTree(treepath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -30,7 +30,13 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
|
||||
|
||||
remainingCommitID := commitID
|
||||
path := ""
|
||||
currentTree := notes.Tree.gogitTree
|
||||
tree := NewTree(repo, notes.TreeID)
|
||||
if err := tree.loadTreeObject(); err != nil {
|
||||
log.Error("Unable to get git tree for notes commit %q. Error: %v", notes.ID, err)
|
||||
return err
|
||||
}
|
||||
currentTree := tree.gogitTree
|
||||
|
||||
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 {
|
||||
|
||||
@ -28,7 +28,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
|
||||
|
||||
path := ""
|
||||
|
||||
tree := ¬es.Tree
|
||||
tree := NewTree(repo, notes.TreeID)
|
||||
log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)
|
||||
|
||||
var entry *TreeEntry
|
||||
@ -80,7 +80,7 @@ func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note)
|
||||
path = path[idx+1:]
|
||||
}
|
||||
|
||||
lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
|
||||
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
|
||||
|
||||
@ -100,7 +100,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
||||
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(string(commitID)), io.LimitReader(batchReader, size))
|
||||
curCommit, err = git.CommitFromReader(git.MustIDFromString(string(commitID)), io.LimitReader(batchReader, size))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -108,7 +108,7 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := batchStdinWriter.Write([]byte(curCommit.Tree.ID.String() + "\n")); err != nil {
|
||||
if _, err := batchStdinWriter.Write([]byte(curCommit.TreeID.String() + "\n")); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
curPath = ""
|
||||
|
||||
@ -6,8 +6,10 @@ package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -77,8 +79,8 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com
|
||||
return repo.getCommit(id)
|
||||
}
|
||||
|
||||
// GetCommitByPath returns the last commit of relative path.
|
||||
func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
|
||||
// GetCommitByPathDefaultBranch returns the last commit of relative path.
|
||||
func (repo *Repository) GetCommitByPathDefaultBranch(relpath string) (*Commit, error) {
|
||||
stdout, _, runErr := gitcmd.NewCommand("log", "-1", prettyLogFormat).
|
||||
AddDashesAndList(relpath).
|
||||
WithDir(repo.Path).
|
||||
@ -97,8 +99,8 @@ func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
|
||||
return commits[0], nil
|
||||
}
|
||||
|
||||
// commitsByRangeWithTime returns the specific page commits before current revision, with not, since, until support
|
||||
func (repo *Repository) commitsByRangeWithTime(id ObjectID, page, pageSize int, not, since, until string) ([]*Commit, error) {
|
||||
// CommitsByRangeWithTime returns the specific page commits before current revision, with not, since, until support
|
||||
func (repo *Repository) CommitsByRangeWithTime(id ObjectID, page, pageSize int, not, since, until string) ([]*Commit, error) {
|
||||
cmd := gitcmd.NewCommand("log").
|
||||
AddOptionFormat("--skip=%d", (page-1)*pageSize).
|
||||
AddOptionFormat("--max-count=%d", pageSize).
|
||||
@ -123,7 +125,8 @@ func (repo *Repository) commitsByRangeWithTime(id ObjectID, page, pageSize int,
|
||||
return repo.parsePrettyFormatLogToList(stdout)
|
||||
}
|
||||
|
||||
func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([]*Commit, error) {
|
||||
// SearchCommits returns the commits match the keyword before current revision
|
||||
func (repo *Repository) SearchCommits(id ObjectID, opts SearchCommitsOptions) ([]*Commit, error) {
|
||||
// add common arguments to git command
|
||||
addCommonSearchArgs := func(c *gitcmd.Command) {
|
||||
// ignore case
|
||||
@ -487,11 +490,13 @@ func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error)
|
||||
return commits, nil
|
||||
}
|
||||
|
||||
func (repo *Repository) getCommitsBefore(id ObjectID) ([]*Commit, error) {
|
||||
// CommitsBefore returns all the commits before current revision
|
||||
func (repo *Repository) CommitsBefore(id ObjectID) ([]*Commit, error) {
|
||||
return repo.commitsBefore(id, 0)
|
||||
}
|
||||
|
||||
func (repo *Repository) getCommitsBeforeLimit(id ObjectID, num int) ([]*Commit, error) {
|
||||
// CommitsBeforeLimit returns num commits before current revision
|
||||
func (repo *Repository) CommitsBeforeLimit(id ObjectID, num int) ([]*Commit, error) {
|
||||
return repo.commitsBefore(id, num)
|
||||
}
|
||||
|
||||
@ -567,11 +572,7 @@ func (repo *Repository) IsCommitInBranch(commitID, branch string) (r bool, err e
|
||||
func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error {
|
||||
if repo.LastCommitCache == nil {
|
||||
commitsCount, err := cache.GetInt64(cacheKey, func() (int64, error) {
|
||||
commit, err := repo.GetCommit(sha)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return commit.CommitsCount()
|
||||
return repo.CommitsCount(sha)
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@ -611,3 +612,104 @@ func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID s
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Parent returns n-th parent (0-based index) of the commit.
|
||||
func (repo *Repository) ParentCommit(c *Commit, n int) (*Commit, error) {
|
||||
id, err := c.ParentID(n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parent, err := repo.getCommit(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
// GetCommitByPath return the commit of relative path object.
|
||||
func (repo *Repository) GetCommitByPath(commitID ObjectID, relpath string) (*Commit, error) {
|
||||
if repo.LastCommitCache != nil {
|
||||
return repo.LastCommitCache.GetCommitByPath(commitID.String(), relpath)
|
||||
}
|
||||
return repo.getCommitByPathWithID(commitID, relpath)
|
||||
}
|
||||
|
||||
// CommitsCount returns number of total commits of until current revision.
|
||||
func (repo *Repository) CommitsCount(commitID string) (int64, error) {
|
||||
return CommitsCount(repo.Ctx, CommitsCountOptions{
|
||||
RepoPath: repo.Path,
|
||||
Revision: []string{commitID},
|
||||
})
|
||||
}
|
||||
|
||||
// HasPreviousCommit returns true if a given commitHash is contained in commit's parents
|
||||
func (repo *Repository) HasPreviousCommit(c *Commit, objectID ObjectID) (bool, error) {
|
||||
this := c.ID.String()
|
||||
that := objectID.String()
|
||||
|
||||
if this == that {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
_, _, err := gitcmd.NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(that, this).
|
||||
WithDir(repo.Path).
|
||||
RunStdString(repo.Ctx)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
var exitError *exec.ExitError
|
||||
if errors.As(err, &exitError) {
|
||||
if exitError.ProcessState.ExitCode() == 1 && len(exitError.Stderr) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
// IsForcePush returns true if a push from oldCommitHash to this is a force push
|
||||
func (repo *Repository) IsForcePush(c *Commit, oldCommitID string) (bool, error) {
|
||||
objectFormat, err := repo.GetObjectFormat()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if oldCommitID == objectFormat.EmptyObjectID().String() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
oldCommit, err := repo.GetCommit(oldCommitID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
hasPreviousCommit, err := repo.HasPreviousCommit(c, oldCommit.ID)
|
||||
return !hasPreviousCommit, err
|
||||
}
|
||||
|
||||
// CommitsBeforeUntil returns the commits between commitID to current revision
|
||||
func (repo *Repository) CommitsBeforeUntil(c *Commit, commitID string) ([]*Commit, error) {
|
||||
endCommit, err := repo.GetCommit(commitID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return repo.CommitsBetween(c, endCommit)
|
||||
}
|
||||
|
||||
// GetClosestBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
|
||||
func (repo *Repository) GetClosestBranchName(c *Commit) (string, error) {
|
||||
cmd := gitcmd.NewCommand("name-rev")
|
||||
if DefaultFeatures().CheckVersionAtLeast("2.13.0") {
|
||||
cmd.AddArguments("--exclude", "refs/tags/*")
|
||||
}
|
||||
cmd.AddArguments("--name-only", "--no-undefined").AddDynamicArguments(c.ID.String())
|
||||
data, _, err := cmd.WithDir(repo.Path).RunStdString(repo.Ctx)
|
||||
if err != nil {
|
||||
// handle special case where git can not describe commit
|
||||
if strings.Contains(err.Error(), "cannot describe") {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
// name-rev commitID output will be "master" or "master~12"
|
||||
return strings.SplitN(strings.TrimSpace(data), "~", 2)[0], nil
|
||||
}
|
||||
|
||||
@ -98,16 +98,5 @@ func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commit := convertCommit(gogitCommit)
|
||||
commit.repo = repo
|
||||
|
||||
tree, err := gogitCommit.Tree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
commit.Tree.ID = ParseGogitHash(tree.Hash)
|
||||
commit.Tree.gogitTree = tree
|
||||
|
||||
return commit, nil
|
||||
return convertCommit(gogitCommit), nil
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.
|
||||
|
||||
return commit, nil
|
||||
case "commit":
|
||||
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
||||
commit, err := CommitFromReader(id, io.LimitReader(rd, size))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -43,18 +43,20 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
commit.Tree.ResolvedID = resolvedID
|
||||
return &commit.Tree, nil
|
||||
tree := NewTree(repo, commit.TreeID)
|
||||
tree.ResolvedID = resolvedID
|
||||
return tree, nil
|
||||
case "commit":
|
||||
commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
|
||||
commit, err := CommitFromReader(id, io.LimitReader(rd, 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 := NewTree(repo, commit.TreeID)
|
||||
tree.ResolvedID = commit.ID
|
||||
return tree, nil
|
||||
case "tree":
|
||||
tree := NewTree(repo, id)
|
||||
tree.ResolvedID = id
|
||||
|
||||
@ -3,65 +3,50 @@
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
type TemplateSubmoduleCommit struct {
|
||||
Path string
|
||||
Commit string
|
||||
type SubmoduleWebLink struct {
|
||||
RepoWebLink, CommitWebLink string
|
||||
}
|
||||
|
||||
// GetTemplateSubmoduleCommits returns a list of submodules paths and their commits from a repository
|
||||
// This function is only for generating new repos based on existing template, the template couldn't be too large.
|
||||
func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submoduleCommits []TemplateSubmoduleCommit, _ error) {
|
||||
stdoutReader, stdoutWriter, err := os.Pipe()
|
||||
// GetSubModules get all the submodules of current revision git tree
|
||||
func (t *Tree) GetSubModules() (*ObjectCache[*SubModule], error) {
|
||||
if t.submoduleCache != nil {
|
||||
return t.submoduleCache, nil
|
||||
}
|
||||
|
||||
entry, err := t.GetTreeEntryByPath(".gitmodules")
|
||||
if err != nil {
|
||||
if _, ok := err.(ErrNotExist); ok {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rd, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rd.Close()
|
||||
|
||||
// at the moment we do not strictly limit the size of the .gitmodules file because some users would have huge .gitmodules files (>1MB)
|
||||
t.submoduleCache, err = configParseSubModules(rd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return t.submoduleCache, nil
|
||||
}
|
||||
|
||||
// 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 (t *Tree) GetSubModule(entryName string) (*SubModule, error) {
|
||||
modules, err := t.GetSubModules()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD").
|
||||
WithDir(repoPath).
|
||||
WithStdout(stdoutWriter).
|
||||
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||
_ = stdoutWriter.Close()
|
||||
defer stdoutReader.Close()
|
||||
|
||||
scanner := bufio.NewScanner(stdoutReader)
|
||||
for scanner.Scan() {
|
||||
entry, err := parseLsTreeLine(scanner.Bytes())
|
||||
if err != nil {
|
||||
cancel()
|
||||
return err
|
||||
}
|
||||
if entry.EntryMode == EntryModeCommit {
|
||||
submoduleCommits = append(submoduleCommits, TemplateSubmoduleCommit{Path: entry.Name, Commit: entry.ID.String()})
|
||||
}
|
||||
}
|
||||
return scanner.Err()
|
||||
}).
|
||||
Run(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err)
|
||||
}
|
||||
return submoduleCommits, nil
|
||||
}
|
||||
|
||||
// AddTemplateSubmoduleIndexes Adds the given submodules to the git index.
|
||||
// It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir.
|
||||
func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error {
|
||||
for _, submodule := range submodules {
|
||||
cmd := gitcmd.NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path)
|
||||
if stdout, _, err := cmd.WithDir(repoPath).RunStdString(ctx); err != nil {
|
||||
log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err)
|
||||
return err
|
||||
if modules != nil {
|
||||
if module, has := modules.Get(entryName); has {
|
||||
return module, nil
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// CommitSubmoduleFile represents a file with submodule type.
|
||||
type CommitSubmoduleFile struct {
|
||||
// SubmoduleFile represents a file with submodule type.
|
||||
type SubmoduleFile struct {
|
||||
repoLink string
|
||||
fullPath string
|
||||
refURL string
|
||||
@ -24,20 +24,20 @@ type CommitSubmoduleFile struct {
|
||||
parsedTargetLink string
|
||||
}
|
||||
|
||||
// NewCommitSubmoduleFile create a new submodule file
|
||||
func NewCommitSubmoduleFile(repoLink, fullPath, refURL, refID string) *CommitSubmoduleFile {
|
||||
return &CommitSubmoduleFile{repoLink: repoLink, fullPath: fullPath, refURL: refURL, refID: refID}
|
||||
// NewSubmoduleFile create a new submodule file
|
||||
func NewSubmoduleFile(repoLink, fullPath, refURL, refID string) *SubmoduleFile {
|
||||
return &SubmoduleFile{repoLink: repoLink, fullPath: fullPath, refURL: refURL, refID: refID}
|
||||
}
|
||||
|
||||
// RefID returns the commit ID of the submodule, it returns empty string for nil receiver
|
||||
func (sf *CommitSubmoduleFile) RefID() string {
|
||||
func (sf *SubmoduleFile) RefID() string {
|
||||
if sf == nil {
|
||||
return ""
|
||||
}
|
||||
return sf.refID
|
||||
}
|
||||
|
||||
func (sf *CommitSubmoduleFile) getWebLinkInTargetRepo(ctx context.Context, moreLinkPath string) *SubmoduleWebLink {
|
||||
func (sf *SubmoduleFile) getWebLinkInTargetRepo(ctx context.Context, moreLinkPath string) *SubmoduleWebLink {
|
||||
if sf == nil || sf.refURL == "" {
|
||||
return nil
|
||||
}
|
||||
@ -58,12 +58,12 @@ func (sf *CommitSubmoduleFile) getWebLinkInTargetRepo(ctx context.Context, moreL
|
||||
|
||||
// SubmoduleWebLinkTree tries to make the submodule's tree link in its own repo, it also works on "nil" receiver
|
||||
// It returns nil if the submodule does not have a valid URL or is nil
|
||||
func (sf *CommitSubmoduleFile) SubmoduleWebLinkTree(ctx context.Context, optCommitID ...string) *SubmoduleWebLink {
|
||||
func (sf *SubmoduleFile) SubmoduleWebLinkTree(ctx context.Context, optCommitID ...string) *SubmoduleWebLink {
|
||||
return sf.getWebLinkInTargetRepo(ctx, "/tree/"+util.OptionalArg(optCommitID, sf.RefID()))
|
||||
}
|
||||
|
||||
// SubmoduleWebLinkCompare tries to make the submodule's compare link in its own repo, it also works on "nil" receiver
|
||||
// It returns nil if the submodule does not have a valid URL or is nil
|
||||
func (sf *CommitSubmoduleFile) SubmoduleWebLinkCompare(ctx context.Context, commitID1, commitID2 string) *SubmoduleWebLink {
|
||||
func (sf *SubmoduleFile) SubmoduleWebLinkCompare(ctx context.Context, commitID1, commitID2 string) *SubmoduleWebLink {
|
||||
return sf.getWebLinkInTargetRepo(ctx, "/compare/"+commitID1+"..."+commitID2)
|
||||
}
|
||||
@ -9,14 +9,14 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCommitSubmoduleLink(t *testing.T) {
|
||||
assert.Nil(t, (*CommitSubmoduleFile)(nil).SubmoduleWebLinkTree(t.Context()))
|
||||
assert.Nil(t, (*CommitSubmoduleFile)(nil).SubmoduleWebLinkCompare(t.Context(), "", ""))
|
||||
assert.Nil(t, (&CommitSubmoduleFile{}).SubmoduleWebLinkTree(t.Context()))
|
||||
assert.Nil(t, (&CommitSubmoduleFile{}).SubmoduleWebLinkCompare(t.Context(), "", ""))
|
||||
func TestSubmoduleLink(t *testing.T) {
|
||||
assert.Nil(t, (*SubmoduleFile)(nil).SubmoduleWebLinkTree(t.Context()))
|
||||
assert.Nil(t, (*SubmoduleFile)(nil).SubmoduleWebLinkCompare(t.Context(), "", ""))
|
||||
assert.Nil(t, (&SubmoduleFile{}).SubmoduleWebLinkTree(t.Context()))
|
||||
assert.Nil(t, (&SubmoduleFile{}).SubmoduleWebLinkCompare(t.Context(), "", ""))
|
||||
|
||||
t.Run("GitHubRepo", func(t *testing.T) {
|
||||
sf := NewCommitSubmoduleFile("/any/repo-link", "full-path", "git@github.com:user/repo.git", "aaaa")
|
||||
sf := NewSubmoduleFile("/any/repo-link", "full-path", "git@github.com:user/repo.git", "aaaa")
|
||||
wl := sf.SubmoduleWebLinkTree(t.Context())
|
||||
assert.Equal(t, "https://github.com/user/repo", wl.RepoWebLink)
|
||||
assert.Equal(t, "https://github.com/user/repo/tree/aaaa", wl.CommitWebLink)
|
||||
@ -27,12 +27,12 @@ func TestCommitSubmoduleLink(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("RelativePath", func(t *testing.T) {
|
||||
sf := NewCommitSubmoduleFile("/subpath/any/repo-home-link", "full-path", "../../user/repo", "aaaa")
|
||||
sf := NewSubmoduleFile("/subpath/any/repo-home-link", "full-path", "../../user/repo", "aaaa")
|
||||
wl := sf.SubmoduleWebLinkTree(t.Context())
|
||||
assert.Equal(t, "/subpath/user/repo", wl.RepoWebLink)
|
||||
assert.Equal(t, "/subpath/user/repo/tree/aaaa", wl.CommitWebLink)
|
||||
|
||||
sf = NewCommitSubmoduleFile("/subpath/any/repo-home-link", "dir/submodule", "../../user/repo", "aaaa")
|
||||
sf = NewSubmoduleFile("/subpath/any/repo-home-link", "dir/submodule", "../../user/repo", "aaaa")
|
||||
wl = sf.SubmoduleWebLinkCompare(t.Context(), "1111", "2222")
|
||||
assert.Equal(t, "/subpath/user/repo", wl.RepoWebLink)
|
||||
assert.Equal(t, "/subpath/user/repo/compare/1111...2222", wl.CommitWebLink)
|
||||
67
modules/git/submodule_template.go
Normal file
67
modules/git/submodule_template.go
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package git
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
type TemplateSubmoduleCommit struct {
|
||||
Path string
|
||||
Commit string
|
||||
}
|
||||
|
||||
// GetTemplateSubmoduleCommits returns a list of submodules paths and their commits from a repository
|
||||
// This function is only for generating new repos based on existing template, the template couldn't be too large.
|
||||
func GetTemplateSubmoduleCommits(ctx context.Context, repoPath string) (submoduleCommits []TemplateSubmoduleCommit, _ error) {
|
||||
stdoutReader, stdoutWriter, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = gitcmd.NewCommand("ls-tree", "-r", "--", "HEAD").
|
||||
WithDir(repoPath).
|
||||
WithStdout(stdoutWriter).
|
||||
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||
_ = stdoutWriter.Close()
|
||||
defer stdoutReader.Close()
|
||||
|
||||
scanner := bufio.NewScanner(stdoutReader)
|
||||
for scanner.Scan() {
|
||||
entry, err := parseLsTreeLine(scanner.Bytes())
|
||||
if err != nil {
|
||||
cancel()
|
||||
return err
|
||||
}
|
||||
if entry.EntryMode == EntryModeCommit {
|
||||
submoduleCommits = append(submoduleCommits, TemplateSubmoduleCommit{Path: entry.Name, Commit: entry.ID.String()})
|
||||
}
|
||||
}
|
||||
return scanner.Err()
|
||||
}).
|
||||
Run(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("GetTemplateSubmoduleCommits: error running git ls-tree: %v", err)
|
||||
}
|
||||
return submoduleCommits, nil
|
||||
}
|
||||
|
||||
// AddTemplateSubmoduleIndexes Adds the given submodules to the git index.
|
||||
// It is only for generating new repos based on existing template, requires the .gitmodules file to be already present in the work dir.
|
||||
func AddTemplateSubmoduleIndexes(ctx context.Context, repoPath string, submodules []TemplateSubmoduleCommit) error {
|
||||
for _, submodule := range submodules {
|
||||
cmd := gitcmd.NewCommand("update-index", "--add", "--cacheinfo", "160000").AddDynamicArguments(submodule.Commit, submodule.Path)
|
||||
if stdout, _, err := cmd.WithDir(repoPath).RunStdString(ctx); err != nil {
|
||||
log.Error("Unable to add %s as submodule to repo %s: stdout %s\nError: %v", submodule.Path, repoPath, stdout, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -6,9 +6,11 @@ package git
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/modules/git/gitcmd"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
// NewTree create a new tree according the repository and tree id
|
||||
@ -76,3 +78,32 @@ func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Comm
|
||||
}
|
||||
return repo.GetCommit(strings.TrimSpace(stdout))
|
||||
}
|
||||
|
||||
// GetFileContent reads a file content as a string or returns false if this was not possible
|
||||
func (t *Tree) GetFileContent(filename string, limit int) (string, error) {
|
||||
entry, err := t.GetTreeEntryByPath(filename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
r, err := entry.Blob().DataAsync()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
if limit > 0 {
|
||||
bs := make([]byte, limit)
|
||||
n, err := util.ReadAtMost(r, bs)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bs[:n]), nil
|
||||
}
|
||||
|
||||
bytes, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(bytes), nil
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ type EntryFollowResult struct {
|
||||
TargetEntry *TreeEntry
|
||||
}
|
||||
|
||||
func EntryFollowLink(commit *Commit, fullPath string, te *TreeEntry) (*EntryFollowResult, error) {
|
||||
func EntryFollowLink(tree *Tree, fullPath string, te *TreeEntry) (*EntryFollowResult, error) {
|
||||
if !te.IsLink() {
|
||||
return nil, util.ErrorWrap(util.ErrUnprocessableContent, "%q is not a symlink", fullPath)
|
||||
}
|
||||
@ -51,18 +51,18 @@ func EntryFollowLink(commit *Commit, fullPath string, te *TreeEntry) (*EntryFoll
|
||||
}
|
||||
|
||||
targetFullPath := path.Join(path.Dir(fullPath), link)
|
||||
targetEntry, err := commit.GetTreeEntryByPath(targetFullPath)
|
||||
targetEntry, err := tree.GetTreeEntryByPath(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(tree *Tree, 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(tree, fullPath, treeEntry)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
@ -20,15 +20,17 @@ func TestFollowLink(t *testing.T) {
|
||||
commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
|
||||
require.NoError(t, err)
|
||||
|
||||
tree := NewTree(r, commit.TreeID)
|
||||
|
||||
// get the symlink
|
||||
{
|
||||
lnkFullPath := "foo/bar/link_to_hello"
|
||||
lnk, err := commit.Tree.GetTreeEntryByPath("foo/bar/link_to_hello")
|
||||
lnk, err := tree.GetTreeEntryByPath("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(tree, lnkFullPath, lnk)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "hello", res.TargetEntry.Name())
|
||||
assert.Equal(t, "foo/nar/hello", res.TargetFullPath)
|
||||
@ -38,38 +40,38 @@ func TestFollowLink(t *testing.T) {
|
||||
|
||||
{
|
||||
// should error when called on a normal file
|
||||
entry, err := commit.Tree.GetTreeEntryByPath("file1.txt")
|
||||
entry, err := tree.GetTreeEntryByPath("file1.txt")
|
||||
require.NoError(t, err)
|
||||
res, err := EntryFollowLink(commit, "file1.txt", entry)
|
||||
res, err := EntryFollowLink(tree, "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 := tree.GetTreeEntryByPath("foo/broken_link")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, entry.IsLink())
|
||||
res, err := EntryFollowLink(commit, "foo/broken_link", entry)
|
||||
res, err := EntryFollowLink(tree, "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 := tree.GetTreeEntryByPath("foo/outside_repo")
|
||||
require.NoError(t, err)
|
||||
assert.True(t, entry.IsLink())
|
||||
res, err := EntryFollowLink(commit, "foo/outside_repo", entry)
|
||||
res, err := EntryFollowLink(tree, "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 := tree.GetTreeEntryByPath("foo/link_short")
|
||||
require.NoError(t, err)
|
||||
res, err := EntryFollowLink(commit, "foo/link_short", entry)
|
||||
res, err := EntryFollowLink(tree, "foo/link_short", entry)
|
||||
assert.ErrorIs(t, err, util.ErrNotExist)
|
||||
assert.Equal(t, "a", res.SymlinkContent)
|
||||
}
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
package git
|
||||
|
||||
import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
|
||||
"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"
|
||||
@ -41,6 +43,11 @@ func (te *TreeEntry) Size() int64 {
|
||||
return te.size
|
||||
}
|
||||
|
||||
if err := te.ptree.loadTreeObject(); err != nil {
|
||||
log.Error("Unable to load tree object: %v", err)
|
||||
return 0
|
||||
}
|
||||
|
||||
file, err := te.ptree.gogitTree.TreeEntryFile(te.gogitTreeEntry)
|
||||
if err != nil {
|
||||
return 0
|
||||
|
||||
@ -23,9 +23,14 @@ type Tree struct {
|
||||
|
||||
// parent tree
|
||||
ptree *Tree
|
||||
|
||||
submoduleCache *ObjectCache[*SubModule]
|
||||
}
|
||||
|
||||
func (t *Tree) loadTreeObject() error {
|
||||
if t.gogitTree != nil {
|
||||
return nil
|
||||
}
|
||||
gogitTree, err := t.repo.gogitRepo.TreeObject(plumbing.Hash(t.ID.RawValue()))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -37,11 +42,8 @@ func (t *Tree) loadTreeObject() error {
|
||||
|
||||
// ListEntries returns all entries of current tree.
|
||||
func (t *Tree) ListEntries() (Entries, error) {
|
||||
if t.gogitTree == nil {
|
||||
err := t.loadTreeObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := t.loadTreeObject(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
entries := make([]*TreeEntry, len(t.gogitTree.Entries))
|
||||
@ -58,11 +60,9 @@ func (t *Tree) ListEntries() (Entries, error) {
|
||||
|
||||
// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees
|
||||
func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
|
||||
if t.gogitTree == nil {
|
||||
err := t.loadTreeObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err := t.loadTreeObject()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var entries []*TreeEntry
|
||||
|
||||
@ -26,6 +26,8 @@ type Tree struct {
|
||||
|
||||
entriesRecursive Entries
|
||||
entriesRecursiveParsed bool
|
||||
|
||||
submoduleCache *ObjectCache[*SubModule]
|
||||
}
|
||||
|
||||
// ListEntries returns all entries of current tree.
|
||||
|
||||
@ -18,9 +18,11 @@ func TestSubTree_Issue29101(t *testing.T) {
|
||||
commit, err := repo.GetCommit("ce064814f4a0d337b333e646ece456cd39fab612")
|
||||
assert.NoError(t, err)
|
||||
|
||||
tree := NewTree(repo, commit.TreeID)
|
||||
|
||||
// old code could produce a different error if called multiple times
|
||||
for range 10 {
|
||||
_, err = commit.SubTree("file1.txt")
|
||||
_, err = tree.SubTree("file1.txt")
|
||||
assert.Error(t, err)
|
||||
assert.True(t, IsErrNotExist(err))
|
||||
}
|
||||
|
||||
@ -47,8 +47,8 @@ func UnmarshalFromEntry(entry *git.TreeEntry, dir string) (*api.IssueTemplate, e
|
||||
}
|
||||
|
||||
// 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(tree *git.Tree, filename string) (*api.IssueTemplate, error) {
|
||||
entry, err := tree.GetTreeEntryByPath(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get entry for %q: %w", filename, err)
|
||||
}
|
||||
@ -62,7 +62,7 @@ func UnmarshalFromRepo(repo *git.Repository, branch, filename string) (*api.Issu
|
||||
return nil, fmt.Errorf("get commit on branch %q: %w", branch, err)
|
||||
}
|
||||
|
||||
return UnmarshalFromCommit(commit, filename)
|
||||
return UnmarshalFromCommit(git.NewTree(repo, commit.TreeID), filename)
|
||||
}
|
||||
|
||||
func unmarshalFromEntry(entry *git.TreeEntry, filename string) (*api.IssueTemplate, error) {
|
||||
|
||||
@ -80,7 +80,7 @@ func GetBranch(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branchName, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
br, err := convert.ToBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@ -271,7 +271,7 @@ func CreateBranch(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
br, err := convert.ToBranch(ctx, ctx.Repo.Repository, opt.BranchName, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
br, err := convert.ToBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, opt.BranchName, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@ -366,7 +366,7 @@ func ListBranches(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
branchProtection := rules.GetFirstMatched(branches[i].Name)
|
||||
apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, branches[i].Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, branches[i].Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@ -235,7 +235,7 @@ func GetAllCommits(ctx *context.APIContext) {
|
||||
}
|
||||
|
||||
// Query commits
|
||||
commits, err = baseCommit.CommitsByRange(listOptions.Page, listOptions.PageSize, not, since, until)
|
||||
commits, err = ctx.Repo.GitRepo.CommitsByRangeWithTime(baseCommit.ID, listOptions.Page, listOptions.PageSize, not, since, until)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
|
||||
@ -225,7 +225,8 @@ 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)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
entry, err := tree.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.APIErrorNotFound()
|
||||
|
||||
@ -174,7 +174,7 @@ func TestHook(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
commit := convert.ToPayloadCommit(ctx, ctx.Repo.Repository, ctx.Repo.Commit)
|
||||
commit := convert.ToPayloadCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Repo.Commit)
|
||||
|
||||
commitID := ctx.Repo.Commit.ID.String()
|
||||
if err := webhook_service.PrepareWebhook(ctx, hook, webhook_module.HookEventPush, &api.PushPayload{
|
||||
|
||||
@ -57,7 +57,7 @@ func ApplyDiffPatch(ctx *context.APIContext) {
|
||||
Signoff: changeRepoFileOpts.Signoff,
|
||||
}
|
||||
|
||||
fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts)
|
||||
fileResponse, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Doer, opts)
|
||||
if err != nil {
|
||||
handleChangeRepoFilesError(ctx, err)
|
||||
} else {
|
||||
|
||||
@ -114,7 +114,7 @@ func GetAnnotatedTag(ctx *context.APIContext) {
|
||||
if err != nil {
|
||||
ctx.APIError(http.StatusBadRequest, err)
|
||||
}
|
||||
ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, tag, commit))
|
||||
ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, tag, commit))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
@ -196,7 +196,7 @@ func getWikiPage(ctx *context.APIContext, wikiName wiki_service.WebPath) *api.Wi
|
||||
commitsCount, _ := wikiRepo.FileCommitsCount(ctx.Repo.Repository.DefaultWikiBranch, pageFilename)
|
||||
|
||||
// Get last change information.
|
||||
lastCommit, err := wikiRepo.GetCommitByPath(pageFilename)
|
||||
lastCommit, err := wikiRepo.GetCommitByPathDefaultBranch(pageFilename)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return nil
|
||||
@ -307,7 +307,7 @@ func ListWikiPages(ctx *context.APIContext) {
|
||||
skip := (page - 1) * limit
|
||||
maxNum := page * limit
|
||||
|
||||
entries, err := commit.ListEntries()
|
||||
entries, err := git.NewTree(wikiRepo, commit.TreeID).ListEntries()
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@ -317,7 +317,7 @@ func ListWikiPages(ctx *context.APIContext) {
|
||||
if i < skip || i >= maxNum || !entry.IsRegular() {
|
||||
continue
|
||||
}
|
||||
c, err := wikiRepo.GetCommitByPath(entry.Name())
|
||||
c, err := wikiRepo.GetCommitByPathDefaultBranch(entry.Name())
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return
|
||||
@ -423,7 +423,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
|
||||
}
|
||||
@ -450,8 +450,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(tree *git.Tree, target string) (*git.TreeEntry, error) {
|
||||
entry, err := tree.GetTreeEntryByPath(target)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -464,7 +464,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 tree.GetTreeEntryByPath(unescapedTarget)
|
||||
}
|
||||
|
||||
// findWikiRepoCommit opens the wiki repo and returns the latest commit, writing to context on error.
|
||||
@ -509,9 +509,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(git.NewTree(wikiRepo, commit.TreeID), gitFilename)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
if !isSidebarOrFooter {
|
||||
|
||||
@ -90,11 +90,11 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
|
||||
WithStdout(stdoutWriter).
|
||||
WithPipelineFunc(func(ctx context.Context, cancel context.CancelFunc) error {
|
||||
_ = stdoutWriter.Close()
|
||||
commit, err := git.CommitFromReader(repo, commitID, stdoutReader)
|
||||
commit, err := git.CommitFromReader(commitID, stdoutReader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, repo, commit)
|
||||
if !verification.Verified {
|
||||
cancel()
|
||||
return &errUnverifiedCommit{
|
||||
|
||||
@ -19,7 +19,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.GitRepo.CommitsByRangeWithTime(ctx.Repo.Commit.ID, 0, 10, "", "", "")
|
||||
if err != nil {
|
||||
ctx.ServerError("ShowBranchFeed", err)
|
||||
return
|
||||
|
||||
@ -131,7 +131,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(git.NewTree(ctx.Repo.GitRepo, commit.TreeID))
|
||||
if err != nil {
|
||||
ctx.ServerError("ListWorkflows", err)
|
||||
return nil, ""
|
||||
|
||||
@ -80,7 +80,7 @@ func ViewWorkflowFile(ctx *context_module.Context) {
|
||||
}, err)
|
||||
return
|
||||
}
|
||||
rpath, entries, err := actions.ListWorkflows(commit)
|
||||
rpath, entries, err := actions.ListWorkflows(git.NewTree(ctx.Repo.GitRepo, commit.TreeID))
|
||||
if err != nil {
|
||||
ctx.ServerError("ListWorkflows", err)
|
||||
return
|
||||
|
||||
@ -50,7 +50,8 @@ func RefBlame(ctx *context.Context) {
|
||||
ctx.NotFound(nil)
|
||||
return
|
||||
}
|
||||
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
entry, err := tree.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
|
||||
return
|
||||
@ -91,7 +92,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, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Repo.Commit, ctx.Repo.TreePath, bypassBlameIgnore)
|
||||
if err != nil {
|
||||
ctx.NotFound(err)
|
||||
return
|
||||
@ -116,10 +117,10 @@ 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, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (*blameResult, error) {
|
||||
objectFormat := ctx.Repo.GetObjectFormat()
|
||||
|
||||
blameReader, err := git.CreateBlameReader(ctx, objectFormat, repo.RepoPath(), commit, file, bypassBlameIgnore)
|
||||
blameReader, err := git.CreateBlameReader(ctx, gitRepo, objectFormat, repo.RepoPath(), commit, file, bypassBlameIgnore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -135,7 +136,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 = git.CreateBlameReader(ctx, objectFormat, repo.RepoPath(), commit, file, true)
|
||||
blameReader, err = git.CreateBlameReader(ctx, gitRepo, objectFormat, repo.RepoPath(), 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.GitRepo.CommitsByRangeWithTime(ctx.Repo.Commit.ID, page, pageSize, "", "", "")
|
||||
if err != nil {
|
||||
ctx.ServerError("CommitsByRange", err)
|
||||
return
|
||||
@ -194,7 +194,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.GitRepo.SearchCommits(ctx.Repo.Commit.ID, opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("SearchCommits", err)
|
||||
return
|
||||
@ -391,7 +391,7 @@ func Diff(ctx *context.Context) {
|
||||
ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses)
|
||||
ctx.Data["CommitStatuses"] = statuses
|
||||
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, ctx.Repo.GitRepo, commit)
|
||||
ctx.Data["Verification"] = verification
|
||||
ctx.Data["Author"] = user_model.ValidateCommitWithEmail(ctx, commit)
|
||||
ctx.Data["Parents"] = parents
|
||||
@ -459,7 +459,7 @@ func RawDiff(ctx *context.Context) {
|
||||
}
|
||||
|
||||
func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) ([]*git_model.SignCommitWithStatuses, error) {
|
||||
commits, err := git_service.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository)
|
||||
commits, err := git_service.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository, ctx.Repo.GitRepo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner
|
||||
return nil
|
||||
}
|
||||
|
||||
blob, err := commit.GetBlobByPath(path)
|
||||
blob, err := git.NewTree(ctx.Repo.GitRepo, commit.TreeID).GetBlobByPath(path)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
@ -937,9 +937,9 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
idxRight -= chunkSize
|
||||
leftHunkSize += chunkSize
|
||||
rightHunkSize += chunkSize
|
||||
section.Lines, err = getExcerptLines(commit, filePath, idxLeft-1, idxRight-1, chunkSize)
|
||||
section.Lines, err = getExcerptLines(gitRepo, commit, filePath, idxLeft-1, idxRight-1, chunkSize)
|
||||
} else if direction == "down" && (idxLeft-lastLeft) > chunkSize {
|
||||
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, chunkSize)
|
||||
section.Lines, err = getExcerptLines(gitRepo, commit, filePath, lastLeft, lastRight, chunkSize)
|
||||
lastLeft += chunkSize
|
||||
lastRight += chunkSize
|
||||
} else {
|
||||
@ -947,7 +947,7 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
if direction == "down" {
|
||||
offset = 0
|
||||
}
|
||||
section.Lines, err = getExcerptLines(commit, filePath, lastLeft, lastRight, idxRight-lastRight+offset)
|
||||
section.Lines, err = getExcerptLines(gitRepo, commit, filePath, lastLeft, lastRight, idxRight-lastRight+offset)
|
||||
leftHunkSize = 0
|
||||
rightHunkSize = 0
|
||||
idxLeft = lastLeft
|
||||
@ -1023,8 +1023,8 @@ func ExcerptBlob(ctx *context.Context) {
|
||||
ctx.HTML(http.StatusOK, tplBlobExcerpt)
|
||||
}
|
||||
|
||||
func getExcerptLines(commit *git.Commit, filePath string, idxLeft, idxRight, chunkSize int) ([]*gitdiff.DiffLine, error) {
|
||||
blob, err := commit.Tree.GetBlobByPath(filePath)
|
||||
func getExcerptLines(gitRepo *git.Repository, commit *git.Commit, filePath string, idxLeft, idxRight, chunkSize int) ([]*gitdiff.DiffLine, error) {
|
||||
blob, err := git.NewTree(gitRepo, commit.TreeID).GetBlobByPath(filePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -82,7 +82,8 @@ 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)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
entry, err := tree.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
if git.IsErrNotExist(err) {
|
||||
ctx.NotFound(err)
|
||||
|
||||
@ -221,7 +221,8 @@ 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)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
entry, err := tree.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "GetTreeEntryByPath", err)
|
||||
return nil, nil, nil
|
||||
|
||||
@ -31,7 +31,7 @@ func NewDiffPatchPost(ctx *context.Context) {
|
||||
}
|
||||
|
||||
defaultCommitMessage := ctx.Locale.TrString("repo.editor.patch")
|
||||
_, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, &files.ApplyDiffPatchOptions{
|
||||
_, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Doer, &files.ApplyDiffPatchOptions{
|
||||
LastCommitID: parsed.form.LastCommit,
|
||||
OldBranch: parsed.OldBranchName,
|
||||
NewBranch: parsed.NewBranchName,
|
||||
|
||||
@ -72,7 +72,7 @@ func CherryPickPost(ctx *context.Context) {
|
||||
}
|
||||
if err == nil {
|
||||
opts.Content = buf.String()
|
||||
_, err = files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts)
|
||||
_, err = files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Doer, opts)
|
||||
if err != nil {
|
||||
err = util.ErrorWrapTranslatable(err, "repo.editor.fail_to_apply_patch")
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ package repo
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
)
|
||||
@ -18,7 +19,9 @@ func DiffPreviewPost(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(treePath)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
|
||||
entry, err := tree.GetTreeEntryByPath(treePath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTreeEntryByPath", err)
|
||||
return
|
||||
|
||||
@ -46,7 +46,8 @@ func getClosestParentWithFiles(gitRepo *git.Repository, branchName, originTreePa
|
||||
return ""
|
||||
}
|
||||
// see if the tree has entries
|
||||
if tree, err := commit.SubTree(treePath); err != nil {
|
||||
tree := git.NewTree(gitRepo, commit.TreeID)
|
||||
if tree, err := tree.SubTree(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 {
|
||||
return f(path.Dir(treePath), commit) // no files in this dir, going up a dir
|
||||
|
||||
@ -50,11 +50,12 @@ func setTemplateIfExists(ctx *context.Context, ctxDataKey string, possibleFiles
|
||||
templateCandidates = append(templateCandidates, possibleFiles...) // Append files to the end because they should be fallback
|
||||
|
||||
templateErrs := map[string]error{}
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, commit.TreeID)
|
||||
for _, filename := range templateCandidates {
|
||||
if ok, _ := commit.HasFile(filename); !ok {
|
||||
if entry, _ := tree.GetTreeEntryByPath(filename); entry == nil {
|
||||
continue
|
||||
}
|
||||
template, err := issue_template.UnmarshalFromCommit(commit, filename)
|
||||
template, err := issue_template.UnmarshalFromCommit(tree, filename)
|
||||
if err != nil {
|
||||
templateErrs[filename] = err
|
||||
continue
|
||||
|
||||
@ -740,7 +740,7 @@ func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
beforeCommit, err = afterCommit.Parent(0)
|
||||
beforeCommit, err = gitRepo.ParentCommit(afterCommit, 0)
|
||||
if err != nil {
|
||||
ctx.ServerError("Parent", err)
|
||||
return
|
||||
|
||||
@ -59,7 +59,7 @@ func calReleaseNumCommitsBehind(repoCtx *context.Repository, release *repo_model
|
||||
return fmt.Errorf("GetBranchCommit(DefaultBranch): %w", err)
|
||||
}
|
||||
}
|
||||
countCache[target], err = commit.CommitsCount()
|
||||
countCache[target], err = repoCtx.GitRepo.CommitsCount(commit.ID.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %w", err)
|
||||
}
|
||||
|
||||
@ -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 = git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID).GetBlobByPath(ctx.Repo.TreePath)
|
||||
} else {
|
||||
blob, err = ctx.Repo.GitRepo.GetBlob(ctx.PathParam("sha"))
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ import (
|
||||
|
||||
// TreeList get all files' entries of a repository
|
||||
func TreeList(ctx *context.Context) {
|
||||
tree, err := ctx.Repo.Commit.SubTree("/")
|
||||
tree, err := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID).SubTree("/")
|
||||
if err != nil {
|
||||
ctx.ServerError("Repo.Commit.SubTree", err)
|
||||
return
|
||||
@ -144,7 +144,8 @@ 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"))
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.RepoLink, renderedIconPool, tree, ctx.Repo.TreePath, ctx.FormString("sub_path"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetTreeViewNodes", err)
|
||||
return
|
||||
|
||||
@ -124,7 +124,7 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool {
|
||||
// or of directory if not in root directory.
|
||||
ctx.Data["LatestCommit"] = latestCommit
|
||||
if latestCommit != nil {
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, latestCommit)
|
||||
verification := asymkey_service.ParseCommitWithSignature(ctx, ctx.Repo.GitRepo, latestCommit)
|
||||
|
||||
if err := asymkey_model.CalculateTrustStatus(verification, ctx.Repo.Repository.GetTrustModel(), func(user *user_model.User) (bool, error) {
|
||||
return repo_model.IsOwnerMemberCollaborator(ctx, ctx.Repo.Repository, user.ID)
|
||||
@ -271,9 +271,10 @@ func LastCommit(ctx *context.Context) {
|
||||
func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) {
|
||||
renderedIconPool := fileicon.NewRenderedIconPool()
|
||||
fileIcons := map[string]template.HTML{}
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
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(tree, fullPath, f.Entry)
|
||||
fileIcons[f.Entry.Name()] = fileicon.RenderEntryIconHTML(renderedIconPool, entryInfo)
|
||||
}
|
||||
fileIcons[".."] = fileicon.RenderEntryIconHTML(renderedIconPool, fileicon.EntryInfoFolder())
|
||||
@ -282,7 +283,8 @@ 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)
|
||||
rootTree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
tree, err := rootTree.SubTree(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "Repo.Commit.SubTree", err)
|
||||
return nil
|
||||
@ -291,7 +293,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri
|
||||
ctx.Data["LastCommitLoaderURL"] = ctx.Repo.RepoLink + "/lastcommit/" + url.PathEscape(ctx.Repo.CommitID) + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
// Get current entry user currently looking at.
|
||||
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
entry, err := rootTree.GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
|
||||
return nil
|
||||
@ -316,7 +318,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.GitRepo, ctx.Repo.RepoLink, ctx.Repo.Commit, ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitsInfo", err)
|
||||
return nil
|
||||
|
||||
@ -32,7 +32,7 @@ import (
|
||||
)
|
||||
|
||||
func prepareLatestCommitInfo(ctx *context.Context) bool {
|
||||
commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath)
|
||||
commit, err := ctx.Repo.GitRepo.GetCommitByPath(ctx.Repo.Commit.ID, ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitByPath", err)
|
||||
return false
|
||||
@ -177,6 +177,7 @@ func prepareFileView(ctx *context.Context, entry *git.TreeEntry) {
|
||||
ctx.Data["FileTreePath"] = ctx.Repo.TreePath
|
||||
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
|
||||
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
if ctx.Repo.TreePath == ".editorconfig" {
|
||||
_, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit)
|
||||
if editorconfigWarning != nil {
|
||||
@ -186,7 +187,7 @@ 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.Repo.GitRepo, ctx.Repo.TreePath, tree)
|
||||
if issueConfigErr != nil {
|
||||
ctx.Data["FileError"] = strings.TrimSpace(issueConfigErr.Error())
|
||||
}
|
||||
|
||||
@ -103,7 +103,7 @@ func prepareHomeSidebarCitationFile(entry *git.TreeEntry) func(ctx *context.Cont
|
||||
if entry.Name() != "" {
|
||||
return
|
||||
}
|
||||
tree, err := ctx.Repo.Commit.SubTree(ctx.Repo.TreePath)
|
||||
tree, err := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID).SubTree(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "Repo.Commit.SubTree", err)
|
||||
return
|
||||
@ -269,8 +269,8 @@ func isViewHomeOnlyContent(ctx *context.Context) bool {
|
||||
return ctx.FormBool("only_content")
|
||||
}
|
||||
|
||||
func handleRepoViewSubmodule(ctx *context.Context, commitSubmoduleFile *git.CommitSubmoduleFile) {
|
||||
submoduleWebLink := commitSubmoduleFile.SubmoduleWebLinkTree(ctx)
|
||||
func handleRepoViewSubmodule(ctx *context.Context, submoduleFile *git.SubmoduleFile) {
|
||||
submoduleWebLink := submoduleFile.SubmoduleWebLinkTree(ctx)
|
||||
if submoduleWebLink == nil {
|
||||
ctx.Data["NotFoundPrompt"] = ctx.Repo.TreePath
|
||||
ctx.NotFound(nil)
|
||||
@ -293,12 +293,12 @@ 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)
|
||||
submoduleFile, err := git.GetCommitInfoSubmoduleFile(ctx.Repo.GitRepo, ctx.Repo.RepoLink, ctx.Repo.TreePath, ctx.Repo.Commit.TreeID, entry.ID)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "prepareToRenderDirOrFile: GetCommitInfoSubmoduleFile", err)
|
||||
return
|
||||
}
|
||||
handleRepoViewSubmodule(ctx, commitSubmoduleFile)
|
||||
handleRepoViewSubmodule(ctx, submoduleFile)
|
||||
} else if entry.IsDir() {
|
||||
prepareToRenderDirectory(ctx)
|
||||
} else {
|
||||
@ -354,7 +354,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(git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID), 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
|
||||
@ -396,7 +396,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 := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID).GetTreeEntryByPath(ctx.Repo.TreePath)
|
||||
if err != nil {
|
||||
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
|
||||
return
|
||||
|
||||
@ -18,19 +18,19 @@ func TestViewHomeSubmoduleRedirect(t *testing.T) {
|
||||
unittest.PrepareTestEnv(t)
|
||||
|
||||
ctx, _ := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
|
||||
submodule := git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
|
||||
submodule := git_module.NewSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
|
||||
handleRepoViewSubmodule(ctx, submodule)
|
||||
assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus())
|
||||
assert.Equal(t, "/user2/repo-other/tree/any-ref-id", ctx.Resp.Header().Get("Location"))
|
||||
|
||||
ctx, _ = contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule")
|
||||
submodule = git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "https://other/user2/repo-other.git", "any-ref-id")
|
||||
submodule = git_module.NewSubmoduleFile("/user2/repo1", "test-submodule", "https://other/user2/repo-other.git", "any-ref-id")
|
||||
handleRepoViewSubmodule(ctx, submodule)
|
||||
// do not auto-redirect for external URLs, to avoid open redirect or phishing
|
||||
assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus())
|
||||
|
||||
ctx, respWriter := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule?only_content=true")
|
||||
submodule = git_module.NewCommitSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
|
||||
submodule = git_module.NewSubmoduleFile("/user2/repo1", "test-submodule", "../repo-other", "any-ref-id")
|
||||
handleRepoViewSubmodule(ctx, submodule)
|
||||
assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus())
|
||||
assert.Equal(t, `<a href="/user2/repo-other/tree/any-ref-id">/user2/repo-other/tree/any-ref-id</a>`, respWriter.Body.String())
|
||||
|
||||
@ -64,12 +64,13 @@ func findReadmeFileInEntries(ctx *context.Context, parentDir string, entries []*
|
||||
exts := append(localizedExtensions(".md", ctx.Locale.Language()), ".txt", "") // sorted by priority
|
||||
extCount := len(exts)
|
||||
readmeFiles := make([]*git.TreeEntry, extCount+1)
|
||||
tree := git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID)
|
||||
for _, entry := range entries {
|
||||
if i, ok := util.IsReadmeFileExtension(entry.Name(), exts...); ok {
|
||||
fullPath := path.Join(parentDir, entry.Name())
|
||||
if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].Name(), entry.Blob().Name()) {
|
||||
if entry.IsLink() {
|
||||
res, err := git.EntryFollowLinks(ctx.Repo.Commit, fullPath, entry)
|
||||
res, err := git.EntryFollowLinks(tree, fullPath, entry)
|
||||
if err == nil && (res.TargetEntry.IsExecutable() || res.TargetEntry.IsRegular()) {
|
||||
readmeFiles[i] = entry
|
||||
}
|
||||
@ -146,7 +147,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(git.NewTree(ctx.Repo.GitRepo, ctx.Repo.Commit.TreeID), readmeFullPath, readmeFile); err == nil {
|
||||
readmeTargetEntry = res.TargetEntry
|
||||
} else {
|
||||
readmeTargetEntry = nil // if we cannot resolve the symlink, we cannot render the readme, ignore the error
|
||||
|
||||
@ -78,8 +78,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(tree *git.Tree, target string) (*git.TreeEntry, error) {
|
||||
entry, err := tree.GetTreeEntryByPath(target)
|
||||
if err != nil && !git.IsErrNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
@ -92,7 +92,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 tree.GetTreeEntryByPath(unescapedTarget)
|
||||
}
|
||||
|
||||
func findWikiRepoCommit(ctx *context.Context) (*git.Repository, *git.Commit, error) {
|
||||
@ -144,10 +144,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, tree *git.Tree, wikiName wiki_service.WebPath) (*git.TreeEntry, string, bool, bool) {
|
||||
isRaw := false
|
||||
gitFilename := wiki_service.WebPathToGitPath(wikiName)
|
||||
entry, err := findEntryForFile(commit, gitFilename)
|
||||
entry, err := findEntryForFile(tree, gitFilename)
|
||||
if err != nil && !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("findEntryForFile", err)
|
||||
return nil, "", false, false
|
||||
@ -155,7 +155,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(tree, gitFilename)
|
||||
if err != nil && !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("findEntryForFile", err)
|
||||
return nil, "", false, false
|
||||
@ -170,8 +170,8 @@ 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, tree *git.Tree, wikiName wiki_service.WebPath) ([]byte, *git.TreeEntry, string, bool) {
|
||||
entry, gitFilename, noEntry, _ := wikiEntryByName(ctx, tree, wikiName)
|
||||
if entry == nil {
|
||||
return nil, nil, "", true
|
||||
}
|
||||
@ -187,8 +187,9 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
tree := git.NewTree(wikiGitRepo, commit.TreeID)
|
||||
// get the wiki pages list.
|
||||
entries, err := commit.ListEntries()
|
||||
entries, err := tree.ListEntries()
|
||||
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, tree, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
@ -286,7 +287,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
}
|
||||
|
||||
if !isSideBar {
|
||||
sidebarContent, _, _, _ := wikiContentsByName(ctx, commit, "_Sidebar")
|
||||
sidebarContent, _, _, _ := wikiContentsByName(ctx, tree, "_Sidebar")
|
||||
if ctx.Written() {
|
||||
return nil, nil
|
||||
}
|
||||
@ -298,7 +299,7 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
|
||||
}
|
||||
|
||||
if !isFooter {
|
||||
footerContent, _, _, _ := wikiContentsByName(ctx, commit, "_Footer")
|
||||
footerContent, _, _, _ := wikiContentsByName(ctx, tree, "_Footer")
|
||||
if ctx.Written() {
|
||||
return nil, nil
|
||||
}
|
||||
@ -340,8 +341,10 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
||||
ctx.Data["Username"] = ctx.Repo.Owner.Name
|
||||
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
|
||||
|
||||
tree := git.NewTree(wikiGitRepo, commit.TreeID)
|
||||
|
||||
// lookup filename in wiki - get page content, gitTree entry , real filename
|
||||
_, entry, pageFilename, noEntry := wikiContentsByName(ctx, commit, pageName)
|
||||
_, entry, pageFilename, noEntry := wikiContentsByName(ctx, tree, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
@ -367,7 +370,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
|
||||
ctx.ServerError("CommitsByFileAndRange", err)
|
||||
return nil, nil
|
||||
}
|
||||
ctx.Data["Commits"], err = git_service.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository)
|
||||
ctx.Data["Commits"], err = git_service.ConvertFromGitCommit(ctx, commitsHistory, ctx.Repo.Repository, wikiGitRepo)
|
||||
if err != nil {
|
||||
ctx.ServerError("ConvertFromGitCommit", err)
|
||||
return nil, nil
|
||||
@ -381,7 +384,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)
|
||||
@ -401,8 +404,10 @@ func renderEditPage(ctx *context.Context) {
|
||||
ctx.Data["Title"] = displayName
|
||||
ctx.Data["title"] = displayName
|
||||
|
||||
tree := git.NewTree(wikiGitRepo, commit.TreeID)
|
||||
|
||||
// lookup filename in wiki - gitTree entry , real filename
|
||||
entry, _, noEntry, isRaw := wikiEntryByName(ctx, commit, pageName)
|
||||
entry, _, noEntry, isRaw := wikiEntryByName(ctx, tree, pageName)
|
||||
if noEntry {
|
||||
ctx.Redirect(ctx.Repo.RepoLink + "/wiki/?action=_pages")
|
||||
}
|
||||
@ -497,7 +502,7 @@ func Wiki(ctx *context.Context) {
|
||||
ctx.Data["FormatWarning"] = ext + " rendering is not supported at the moment. Rendered as Markdown."
|
||||
}
|
||||
// Get last change information.
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath)
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPathDefaultBranch(wikiPath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitByPath", err)
|
||||
return
|
||||
@ -529,7 +534,7 @@ func WikiRevision(ctx *context.Context) {
|
||||
|
||||
// Get last change information.
|
||||
wikiPath := entry.Name()
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPath(wikiPath)
|
||||
lastCommit, err := wikiGitRepo.GetCommitByPathDefaultBranch(wikiPath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitByPath", err)
|
||||
return
|
||||
@ -549,14 +554,15 @@ func WikiPages(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("repo.wiki.pages")
|
||||
ctx.Data["CanWriteWiki"] = ctx.Repo.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
|
||||
}
|
||||
|
||||
rootTree := git.NewTree(wikiGitRepo, commit.TreeID)
|
||||
treePath := "" // To support list sub folders' pages in the future
|
||||
tree, err := commit.SubTree(treePath)
|
||||
tree, err := rootTree.SubTree(treePath)
|
||||
if err != nil {
|
||||
ctx.ServerError("SubTree", err)
|
||||
return
|
||||
@ -569,7 +575,7 @@ func WikiPages(ctx *context.Context) {
|
||||
}
|
||||
allEntries.CustomSort(base.NaturalSortLess)
|
||||
|
||||
entries, _, err := allEntries.GetCommitsInfo(ctx, ctx.Repo.RepoLink, commit, treePath)
|
||||
entries, _, err := allEntries.GetCommitsInfo(ctx, wikiGitRepo, ctx.Repo.RepoLink, commit, treePath)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCommitsInfo", err)
|
||||
return
|
||||
@ -603,7 +609,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)
|
||||
@ -617,8 +623,9 @@ func WikiRaw(ctx *context.Context) {
|
||||
providedGitPath := wiki_service.WebPathToGitPath(providedWebPath)
|
||||
var entry *git.TreeEntry
|
||||
if commit != nil {
|
||||
tree := git.NewTree(wikiGitRepo, commit.TreeID)
|
||||
// Try to find a file with that name
|
||||
entry, err = findEntryForFile(commit, providedGitPath)
|
||||
entry, err = findEntryForFile(tree, providedGitPath)
|
||||
if err != nil && !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("findFile", err)
|
||||
return
|
||||
@ -627,7 +634,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(tree, providedGitPath)
|
||||
if err != nil && !git.IsErrNotExist(err) {
|
||||
ctx.ServerError("findFile", err)
|
||||
return
|
||||
|
||||
@ -34,7 +34,8 @@ func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.
|
||||
defer wikiRepo.Close()
|
||||
commit, err := wikiRepo.GetBranchCommit("master")
|
||||
assert.NoError(t, err)
|
||||
entries, err := commit.ListEntries()
|
||||
tree := git.NewTree(wikiRepo, commit.TreeID)
|
||||
entries, err := tree.ListEntries()
|
||||
assert.NoError(t, err)
|
||||
for _, entry := range entries {
|
||||
if entry.Name() == wiki_service.WebPathToGitPath(wikiName) {
|
||||
|
||||
@ -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, _ = git.NewTree(profileGitRepo, commit.TreeID).GetBlobByPath("README.md") // no need to handle this error
|
||||
return profileDbRepo, profileReadmeBlob
|
||||
}
|
||||
|
||||
|
||||
@ -234,7 +234,7 @@ func notify(ctx context.Context, input *notifyInput) error {
|
||||
}
|
||||
|
||||
if shouldDetectSchedules {
|
||||
if err := handleSchedules(ctx, schedules, commit, input, ref.String()); err != nil {
|
||||
if err := handleSchedules(ctx, gitRepo, schedules, commit, input, ref.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -439,12 +439,13 @@ func ifNeedApproval(ctx context.Context, run *actions_model.ActionRun, repo *rep
|
||||
|
||||
func handleSchedules(
|
||||
ctx context.Context,
|
||||
gitRepo *git.Repository,
|
||||
detectedWorkflows []*actions_module.DetectedWorkflow,
|
||||
commit *git.Commit,
|
||||
input *notifyInput,
|
||||
ref string,
|
||||
) error {
|
||||
branch, err := commit.GetBranchName()
|
||||
branch, err := gitRepo.GetClosestBranchName(commit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -538,5 +539,5 @@ func DetectAndHandleSchedules(ctx context.Context, repo *repo_model.Repository)
|
||||
// so we use action user as the Doer of the notifyInput
|
||||
notifyInput := newNotifyInputForSchedules(repo)
|
||||
|
||||
return handleSchedules(ctx, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
|
||||
return handleSchedules(ctx, gitRepo, scheduleWorkflows, commit, notifyInput, repo.DefaultBranch)
|
||||
}
|
||||
|
||||
@ -89,7 +89,8 @@ func DispatchActionWorkflow(ctx reqctx.RequestContext, doer *user_model.User, re
|
||||
}
|
||||
|
||||
// get workflow entry from runTargetCommit
|
||||
_, entries, err := actions.ListWorkflows(runTargetCommit)
|
||||
tree := git.NewTree(gitRepo, runTargetCommit.TreeID)
|
||||
_, entries, err := actions.ListWorkflows(tree)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -23,7 +23,7 @@ import (
|
||||
)
|
||||
|
||||
// ParseCommitWithSignature check if signature is good against keystore.
|
||||
func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *asymkey_model.CommitVerification {
|
||||
func ParseCommitWithSignature(ctx context.Context, gitRepo *git.Repository, c *git.Commit) *asymkey_model.CommitVerification {
|
||||
committer, err := user_model.GetUserByEmail(ctx, c.Committer.Email)
|
||||
if err != nil && !user_model.IsErrUserNotExist(err) {
|
||||
log.Error("GetUserByEmail: %v", err)
|
||||
@ -32,14 +32,14 @@ func ParseCommitWithSignature(ctx context.Context, c *git.Commit) *asymkey_model
|
||||
Reason: "gpg.error.no_committer_account", // this error is not right, but such error should seldom happen
|
||||
}
|
||||
}
|
||||
return ParseCommitWithSignatureCommitter(ctx, c, committer)
|
||||
return ParseCommitWithSignatureCommitter(ctx, gitRepo, c, committer)
|
||||
}
|
||||
|
||||
// ParseCommitWithSignatureCommitter parses a commit's GPG or SSH signature.
|
||||
// The caller guarantees that the committer user is related to the commit by checking its activated email addresses or no-reply address.
|
||||
// If the commit is singed by an instance key, then committer can be nil.
|
||||
// If the signature exists, even if committer is nil, the returned CommittingUser will be a non-nil fake user (e.g.: instance key)
|
||||
func ParseCommitWithSignatureCommitter(ctx context.Context, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification {
|
||||
func ParseCommitWithSignatureCommitter(ctx context.Context, gitRepo *git.Repository, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification {
|
||||
// If no signature, just report the committer
|
||||
if c.Signature == nil {
|
||||
return &asymkey_model.CommitVerification{
|
||||
@ -58,10 +58,10 @@ func ParseCommitWithSignatureCommitter(ctx context.Context, c *git.Commit, commi
|
||||
if strings.HasPrefix(c.Signature.Signature, "-----BEGIN SSH SIGNATURE-----") {
|
||||
return parseCommitWithSSHSignature(ctx, c, committer)
|
||||
}
|
||||
return parseCommitWithGPGSignature(ctx, c, committer)
|
||||
return parseCommitWithGPGSignature(ctx, gitRepo, c, committer)
|
||||
}
|
||||
|
||||
func parseCommitWithGPGSignature(ctx context.Context, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification {
|
||||
func parseCommitWithGPGSignature(ctx context.Context, gitRepo *git.Repository, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification {
|
||||
// Parsing signature
|
||||
sig, err := asymkey_model.ExtractSignature(c.Signature.Signature)
|
||||
if err != nil { // Skipping failed to extract sign
|
||||
@ -162,7 +162,7 @@ func parseCommitWithGPGSignature(ctx context.Context, c *git.Commit, committer *
|
||||
}
|
||||
}
|
||||
|
||||
defaultGPGSettings, err := c.GetRepositoryDefaultPublicGPGKey(false)
|
||||
defaultGPGSettings, err := gitRepo.GetDefaultPublicGPGKey(false)
|
||||
if err != nil {
|
||||
log.Error("Error getting default public gpg key: %v", err)
|
||||
} else if defaultGPGSettings == nil {
|
||||
|
||||
@ -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-----
|
||||
|
||||
@ -212,7 +212,7 @@ Loop:
|
||||
if commit.Signature == nil {
|
||||
return false, nil, nil, &ErrWontSign{parentSigned}
|
||||
}
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{parentSigned}
|
||||
}
|
||||
@ -270,7 +270,7 @@ Loop:
|
||||
if commit.Signature == nil {
|
||||
return false, nil, nil, &ErrWontSign{parentSigned}
|
||||
}
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{parentSigned}
|
||||
}
|
||||
@ -343,7 +343,7 @@ Loop:
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{baseSigned}
|
||||
}
|
||||
@ -359,7 +359,7 @@ Loop:
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{headSigned}
|
||||
}
|
||||
@ -375,21 +375,25 @@ Loop:
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{commitsSigned}
|
||||
}
|
||||
// need to work out merge-base
|
||||
mergeBaseCommit, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit)
|
||||
mergeBaseCommitID, _, err := gitRepo.GetMergeBase("", baseCommit, headCommit)
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
commitList, err := commit.CommitsBeforeUntil(mergeBaseCommit)
|
||||
mergeBaseCommit, err := gitRepo.GetCommit(mergeBaseCommitID)
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
commitList, err := gitRepo.CommitsBetween(commit, mergeBaseCommit)
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
for _, commit := range commitList {
|
||||
verification := ParseCommitWithSignature(ctx, commit)
|
||||
verification := ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if !verification.Verified {
|
||||
return false, nil, nil, &ErrWontSign{commitsSigned}
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ func (r *Repository) GetCommitsCount() (int64, error) {
|
||||
contextName := r.RefFullName.ShortName()
|
||||
isRef := r.RefFullName.IsBranch() || r.RefFullName.IsTag()
|
||||
return cache.GetInt64(r.Repository.GetCommitsCountCacheKey(contextName, isRef), func() (int64, error) {
|
||||
return r.Commit.CommitsCount()
|
||||
return r.GitRepo.CommitsCount(r.Commit.ID.String())
|
||||
})
|
||||
}
|
||||
|
||||
@ -256,7 +256,7 @@ func (r *Repository) GetEditorconfig(optCommit ...*git.Commit) (cfg *editorconfi
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
treeEntry, err := commit.GetTreeEntryByPath(".editorconfig")
|
||||
treeEntry, err := git.NewTree(r.GitRepo, commit.TreeID).GetTreeEntryByPath(".editorconfig")
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ func ToEmailSearch(email *user_model.SearchEmailResult) *api.Email {
|
||||
}
|
||||
|
||||
// ToBranch convert a git.Commit and git.Branch to an api.Branch
|
||||
func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName string, c *git.Commit, bp *git_model.ProtectedBranch, user *user_model.User, isRepoAdmin bool) (*api.Branch, error) {
|
||||
func ToBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, branchName string, c *git.Commit, bp *git_model.ProtectedBranch, user *user_model.User, isRepoAdmin bool) (*api.Branch, error) {
|
||||
if bp == nil {
|
||||
var hasPerm bool
|
||||
var canPush bool
|
||||
@ -81,7 +81,7 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin
|
||||
|
||||
return &api.Branch{
|
||||
Name: branchName,
|
||||
Commit: ToPayloadCommit(ctx, repo, c),
|
||||
Commit: ToPayloadCommit(ctx, repo, gitRepo, c),
|
||||
Protected: false,
|
||||
RequiredApprovals: 0,
|
||||
EnableStatusCheck: false,
|
||||
@ -93,7 +93,7 @@ func ToBranch(ctx context.Context, repo *repo_model.Repository, branchName strin
|
||||
|
||||
branch := &api.Branch{
|
||||
Name: branchName,
|
||||
Commit: ToPayloadCommit(ctx, repo, c),
|
||||
Commit: ToPayloadCommit(ctx, repo, gitRepo, c),
|
||||
Protected: true,
|
||||
RequiredApprovals: bp.RequiredApprovals,
|
||||
EnableStatusCheck: bp.EnableStatusCheck,
|
||||
@ -390,11 +390,11 @@ func ToActionWorkflowJob(ctx context.Context, repo *repo_model.Repository, task
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getActionWorkflowEntry(ctx context.Context, repo *repo_model.Repository, commit *git.Commit, folder string, entry *git.TreeEntry) *api.ActionWorkflow {
|
||||
func getActionWorkflowEntry(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit, folder string, entry *git.TreeEntry) *api.ActionWorkflow {
|
||||
cfgUnit := repo.MustGetUnit(ctx, unit.TypeActions)
|
||||
cfg := cfgUnit.ActionsConfig()
|
||||
|
||||
defaultBranch, _ := commit.GetBranchName()
|
||||
defaultBranch, _ := gitRepo.GetClosestBranchName(commit)
|
||||
|
||||
workflowURL := fmt.Sprintf("%s/actions/workflows/%s", repo.APIURL(), util.PathEscapeSegments(entry.Name()))
|
||||
workflowRepoURL := fmt.Sprintf("%s/src/branch/%s/%s/%s", repo.HTMLURL(ctx), util.PathEscapeSegments(defaultBranch), util.PathEscapeSegments(folder), util.PathEscapeSegments(entry.Name()))
|
||||
@ -455,14 +455,14 @@ func ListActionWorkflows(ctx context.Context, gitrepo *git.Repository, repo *rep
|
||||
return nil, err
|
||||
}
|
||||
|
||||
folder, entries, err := actions.ListWorkflows(defaultBranchCommit)
|
||||
folder, entries, err := actions.ListWorkflows(git.NewTree(gitrepo, defaultBranchCommit.TreeID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
workflows := make([]*api.ActionWorkflow, len(entries))
|
||||
for i, entry := range entries {
|
||||
workflows[i] = getActionWorkflowEntry(ctx, repo, defaultBranchCommit, folder, entry)
|
||||
workflows[i] = getActionWorkflowEntry(ctx, repo, gitrepo, defaultBranchCommit, folder, entry)
|
||||
}
|
||||
|
||||
return workflows, nil
|
||||
@ -530,8 +530,8 @@ func ToActionRunner(ctx context.Context, runner *actions_model.ActionRunner) *ap
|
||||
}
|
||||
|
||||
// ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification
|
||||
func ToVerification(ctx context.Context, c *git.Commit) *api.PayloadCommitVerification {
|
||||
verif := asymkey_service.ParseCommitWithSignature(ctx, c)
|
||||
func ToVerification(ctx context.Context, gitRepo *git.Repository, c *git.Commit) *api.PayloadCommitVerification {
|
||||
verif := asymkey_service.ParseCommitWithSignature(ctx, gitRepo, c)
|
||||
commitVerification := &api.PayloadCommitVerification{
|
||||
Verified: verif.Verified,
|
||||
Reason: verif.Reason,
|
||||
@ -697,7 +697,7 @@ func ToTeams(ctx context.Context, teams []*organization.Team, loadOrgs bool) ([]
|
||||
}
|
||||
|
||||
// ToAnnotatedTag convert git.Tag to api.AnnotatedTag
|
||||
func ToAnnotatedTag(ctx context.Context, repo *repo_model.Repository, t *git.Tag, c *git.Commit) *api.AnnotatedTag {
|
||||
func ToAnnotatedTag(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, t *git.Tag, c *git.Commit) *api.AnnotatedTag {
|
||||
return &api.AnnotatedTag{
|
||||
Tag: t.Name,
|
||||
SHA: t.ID.String(),
|
||||
@ -705,7 +705,7 @@ func ToAnnotatedTag(ctx context.Context, repo *repo_model.Repository, t *git.Tag
|
||||
Message: t.Message,
|
||||
URL: util.URLJoin(repo.APIURL(), "git/tags", t.ID.String()),
|
||||
Tagger: ToCommitUser(t.Tagger),
|
||||
Verification: ToVerification(ctx, c),
|
||||
Verification: ToVerification(ctx, gitRepo, c),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -39,7 +39,7 @@ func ToCommitMeta(repo *repo_model.Repository, tag *git.Tag) *api.CommitMeta {
|
||||
}
|
||||
|
||||
// ToPayloadCommit convert a git.Commit to api.PayloadCommit
|
||||
func ToPayloadCommit(ctx context.Context, repo *repo_model.Repository, c *git.Commit) *api.PayloadCommit {
|
||||
func ToPayloadCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, c *git.Commit) *api.PayloadCommit {
|
||||
authorUsername := ""
|
||||
if author, err := user_model.GetUserByEmail(ctx, c.Author.Email); err == nil {
|
||||
authorUsername = author.Name
|
||||
@ -69,7 +69,7 @@ func ToPayloadCommit(ctx context.Context, repo *repo_model.Repository, c *git.Co
|
||||
UserName: committerUsername,
|
||||
},
|
||||
Timestamp: c.Author.When,
|
||||
Verification: ToVerification(ctx, c),
|
||||
Verification: ToVerification(ctx, gitRepo, c),
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
|
||||
|
||||
// Retrieve verification for commit
|
||||
if opts.Verification {
|
||||
res.RepoCommit.Verification = ToVerification(ctx, commit)
|
||||
res.RepoCommit.Verification = ToVerification(ctx, gitRepo, commit)
|
||||
}
|
||||
|
||||
// Retrieve files affected by the commit
|
||||
|
||||
@ -17,7 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
|
||||
func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository, oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType) ([]*asymkey_model.SignCommit, error) {
|
||||
func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, oldCommits []*user_model.UserCommit, repoTrustModel repo_model.TrustModelType) ([]*asymkey_model.SignCommit, error) {
|
||||
newCommits := make([]*asymkey_model.SignCommit, 0, len(oldCommits))
|
||||
keyMap := map[string]bool{}
|
||||
|
||||
@ -37,7 +37,7 @@ func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository,
|
||||
committerUser := emailUsers.GetByEmail(c.Committer.Email) // FIXME: why ValidateCommitsWithEmails uses "Author", but ParseCommitsWithSignature uses "Committer"?
|
||||
signCommit := &asymkey_model.SignCommit{
|
||||
UserCommit: c,
|
||||
Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, c.Commit, committerUser),
|
||||
Verification: asymkey_service.ParseCommitWithSignatureCommitter(ctx, gitRepo, c.Commit, committerUser),
|
||||
}
|
||||
|
||||
isOwnerMemberCollaborator := func(user *user_model.User) (bool, error) {
|
||||
@ -52,7 +52,7 @@ func ParseCommitsWithSignature(ctx context.Context, repo *repo_model.Repository,
|
||||
}
|
||||
|
||||
// ConvertFromGitCommit converts git commits into SignCommitWithStatuses
|
||||
func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo_model.Repository) ([]*git_model.SignCommitWithStatuses, error) {
|
||||
func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo_model.Repository, gitRepo *git.Repository) ([]*git_model.SignCommitWithStatuses, error) {
|
||||
validatedCommits, err := user_model.ValidateCommitsWithEmails(ctx, commits)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -60,6 +60,7 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo
|
||||
signedCommits, err := ParseCommitsWithSignature(
|
||||
ctx,
|
||||
repo,
|
||||
gitRepo,
|
||||
validatedCommits,
|
||||
repo.GetTrustModel(),
|
||||
)
|
||||
|
||||
@ -97,7 +97,7 @@ func validateGitDiffTreeArguments(gitRepo *git.Repository, useMergeBase bool, ba
|
||||
return false, objectFormat.EmptyTree().String(), headCommitID, nil
|
||||
}
|
||||
|
||||
baseCommit, err := headCommit.Parent(0)
|
||||
baseCommit, err := gitRepo.ParentCommit(headCommit, 0)
|
||||
if err != nil {
|
||||
return false, "", "", fmt.Errorf("baseSha is '', attempted to use parent of commit %s, got error: %v", headCommit.ID.String(), err)
|
||||
}
|
||||
|
||||
@ -421,17 +421,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(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(gitRepo, leftCommit, diffFile.OldName)
|
||||
}
|
||||
if (diffFile.Type == DiffFileAdd || diffFile.Type == DiffFileChange) && rightCommit != nil {
|
||||
rightLineCount, diffLimitedContent.RightContent = getCommitFileLineCountAndLimitedContent(rightCommit, diffFile.OldName)
|
||||
rightLineCount, diffLimitedContent.RightContent = getCommitFileLineCountAndLimitedContent(gitRepo, rightCommit, diffFile.OldName)
|
||||
}
|
||||
if len(diffFile.Sections) == 0 || diffFile.Type != DiffFileChange {
|
||||
return nil, diffLimitedContent
|
||||
@ -505,8 +505,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(gitRepo *git.Repository, commit *git.Commit, filePath string) (lineCount int, limitWriter *limitByteWriter) {
|
||||
blob, err := git.NewTree(gitRepo, commit.TreeID).GetBlobByPath(filePath)
|
||||
if err != nil {
|
||||
return 0, nil
|
||||
}
|
||||
@ -1176,7 +1176,7 @@ func guessBeforeCommitForDiff(gitRepo *git.Repository, beforeCommitID string, af
|
||||
actualBeforeCommitID = commitObjectFormat.EmptyTree()
|
||||
} else {
|
||||
if isBeforeCommitIDEmpty {
|
||||
actualBeforeCommit, err = afterCommit.Parent(0)
|
||||
actualBeforeCommit, err = gitRepo.ParentCommit(afterCommit, 0)
|
||||
} else {
|
||||
actualBeforeCommit, err = gitRepo.GetCommit(beforeCommitID)
|
||||
}
|
||||
@ -1286,7 +1286,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(gitRepo, repoLink, diffFile, beforeCommit, afterCommit)
|
||||
}
|
||||
|
||||
if !isVendored.Has() {
|
||||
@ -1298,7 +1298,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(gitRepo, beforeCommit, afterCommit)
|
||||
if tailSection != nil {
|
||||
diffFile.Sections = append(diffFile.Sections, tailSection)
|
||||
}
|
||||
|
||||
@ -15,12 +15,12 @@ import (
|
||||
|
||||
type SubmoduleDiffInfo struct {
|
||||
SubmoduleName string
|
||||
SubmoduleFile *git.CommitSubmoduleFile // it might be nil if the submodule is not found or unable to parse
|
||||
SubmoduleFile *git.SubmoduleFile // it might be nil if the submodule is not found or unable to parse
|
||||
NewRefID string
|
||||
PreviousRefID string
|
||||
}
|
||||
|
||||
func (si *SubmoduleDiffInfo) PopulateURL(repoLink string, diffFile *DiffFile, leftCommit, rightCommit *git.Commit) {
|
||||
func (si *SubmoduleDiffInfo) PopulateURL(gitRepo *git.Repository, repoLink string, 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,13 +31,13 @@ func (si *SubmoduleDiffInfo) PopulateURL(repoLink string, diffFile *DiffFile, le
|
||||
}
|
||||
|
||||
submoduleFullPath := diffFile.GetDiffFileName()
|
||||
submodule, err := submoduleCommit.GetSubModule(submoduleFullPath)
|
||||
submodule, err := git.NewTree(gitRepo, submoduleCommit.TreeID).GetSubModule(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
|
||||
}
|
||||
if submodule != nil {
|
||||
si.SubmoduleFile = git.NewCommitSubmoduleFile(repoLink, submoduleFullPath, submodule.URL, submoduleCommit.ID.String())
|
||||
si.SubmoduleFile = git.NewSubmoduleFile(repoLink, submoduleFullPath, submodule.URL, submoduleCommit.ID.String())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ func TestSubmoduleInfo(t *testing.T) {
|
||||
assert.EqualValues(t, "aaaa...bbbb", sdi.CompareRefIDLinkHTML(ctx))
|
||||
assert.EqualValues(t, "name", sdi.SubmoduleRepoLinkHTML(ctx))
|
||||
|
||||
sdi.SubmoduleFile = git.NewCommitSubmoduleFile("/any/repo-link", "fullpath", "https://github.com/owner/repo", "1234")
|
||||
sdi.SubmoduleFile = git.NewSubmoduleFile("/any/repo-link", "fullpath", "https://github.com/owner/repo", "1234")
|
||||
assert.EqualValues(t, `<a href="https://github.com/owner/repo/tree/1111">1111</a>`, sdi.CommitRefIDLinkHTML(ctx, "1111"))
|
||||
assert.EqualValues(t, `<a href="https://github.com/owner/repo/compare/aaaa...bbbb">aaaa...bbbb</a>`, sdi.CompareRefIDLinkHTML(ctx))
|
||||
assert.EqualValues(t, `<a href="https://github.com/owner/repo">name</a>`, sdi.SubmoduleRepoLinkHTML(ctx))
|
||||
|
||||
@ -184,7 +184,7 @@ func LoadCommentPushCommits(ctx context.Context, c *issues_model.Comment) error
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
c.Commits, err = git_service.ConvertFromGitCommit(ctx, gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
|
||||
c.Commits, err = git_service.ConvertFromGitCommit(ctx, gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo, gitRepo)
|
||||
if err != nil {
|
||||
log.Debug("ConvertFromGitCommit: %v", err) // no need to show 500 error to end user when the commit does not exist
|
||||
} else {
|
||||
|
||||
@ -80,9 +80,10 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tree := git.NewTree(repo, commit.TreeID)
|
||||
var data string
|
||||
for _, file := range codeOwnerFiles {
|
||||
if blob, err := commit.GetBlobByPath(file); err == nil {
|
||||
if blob, err := tree.GetBlobByPath(file); err == nil {
|
||||
data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
|
||||
if err == nil {
|
||||
break
|
||||
|
||||
@ -47,12 +47,12 @@ 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(gitRepo *git.Repository, path string, tree *git.Tree) (api.IssueConfig, error) {
|
||||
if gitRepo == nil {
|
||||
return GetDefaultTemplateConfig(), nil
|
||||
}
|
||||
|
||||
treeEntry, err := commit.GetTreeEntryByPath(path)
|
||||
treeEntry, err := tree.GetTreeEntryByPath(path)
|
||||
if err != nil {
|
||||
return GetDefaultTemplateConfig(), err
|
||||
}
|
||||
@ -124,8 +124,10 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
|
||||
return ret
|
||||
}
|
||||
|
||||
tree := git.NewTree(gitRepo, commit.TreeID)
|
||||
|
||||
for _, dirName := range templateDirCandidates {
|
||||
tree, err := commit.SubTree(dirName)
|
||||
tree, err := tree.SubTree(dirName)
|
||||
if err != nil {
|
||||
log.Debug("get sub tree of %s: %v", dirName, err)
|
||||
continue
|
||||
@ -165,13 +167,15 @@ func GetTemplateConfigFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repo
|
||||
return GetDefaultTemplateConfig(), err
|
||||
}
|
||||
|
||||
tree := git.NewTree(gitRepo, commit.TreeID)
|
||||
|
||||
for _, configName := range templateConfigCandidates {
|
||||
if _, err := commit.GetTreeEntryByPath(configName + ".yaml"); err == nil {
|
||||
return GetTemplateConfig(gitRepo, configName+".yaml", commit)
|
||||
if _, err := tree.GetTreeEntryByPath(configName + ".yaml"); err == nil {
|
||||
return GetTemplateConfig(gitRepo, configName+".yaml", tree)
|
||||
}
|
||||
|
||||
if _, err := commit.GetTreeEntryByPath(configName + ".yml"); err == nil {
|
||||
return GetTemplateConfig(gitRepo, configName+".yml", commit)
|
||||
if _, err := tree.GetTreeEntryByPath(configName + ".yml"); err == nil {
|
||||
return GetTemplateConfig(gitRepo, configName+".yml", tree)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ import (
|
||||
"code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unit"
|
||||
"code.gitea.io/gitea/modules/charset"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/git/languagestats"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
"code.gitea.io/gitea/modules/indexer/code"
|
||||
@ -62,7 +63,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 := git.NewTree(gitRepo, commit.TreeID).GetBlobByPath(opts.FilePath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ func (g *GiteaLocalUploader) CreateReleases(ctx context.Context, releases ...*ba
|
||||
return fmt.Errorf("GetTagCommit[%v]: %w", rel.TagName, err)
|
||||
}
|
||||
rel.Sha1 = commit.ID.String()
|
||||
rel.NumCommits, err = commit.CommitsCount()
|
||||
rel.NumCommits, err = g.gitRepo.CommitsCount(commit.ID.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("CommitsCount: %w", 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 := git.NewTree(baseGitRepo, commit.TreeID).GetFileContent(templateFilepath, setting.Repository.PullRequest.DefaultMergeMessageSize)
|
||||
if err != nil {
|
||||
if !git.IsErrNotExist(err) {
|
||||
return "", "", err
|
||||
|
||||
@ -1040,7 +1040,7 @@ func IsHeadEqualWithBranch(ctx context.Context, pr *issues_model.PullRequest, br
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
return baseCommit.HasPreviousCommit(headCommit.ID)
|
||||
return baseGitRepo.HasPreviousCommit(baseCommit, headCommit.ID)
|
||||
}
|
||||
|
||||
type CommitInfo struct {
|
||||
|
||||
@ -148,7 +148,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel
|
||||
}
|
||||
|
||||
rel.Sha1 = commit.ID.String()
|
||||
rel.NumCommits, err = commit.CommitsCount()
|
||||
rel.NumCommits, err = gitRepo.CommitsCount(commit.ID.String())
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("CommitsCount: %w", err)
|
||||
}
|
||||
|
||||
@ -733,7 +733,7 @@ func GetBranchDivergingInfo(ctx reqctx.RequestContext, baseRepo *repo_model.Repo
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hasPreviousCommit, _ := headCommit.HasPreviousCommit(baseCommitID)
|
||||
hasPreviousCommit, _ := headGitRepo.HasPreviousCommit(headCommit, baseCommitID)
|
||||
info.BaseHasNewCommits = !hasPreviousCommit
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@ -19,12 +19,17 @@ func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
|
||||
}
|
||||
|
||||
if gitRepo.LastCommitCache == nil {
|
||||
commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(fullRefName.ShortName(), true), commit.CommitsCount)
|
||||
commitsCount, err := cache.GetInt64(repo.GetCommitsCountCacheKey(fullRefName.ShortName(), true), func() (int64, error) {
|
||||
return git.CommitsCount(gitRepo.Ctx, git.CommitsCountOptions{
|
||||
RepoPath: gitRepo.Path,
|
||||
Revision: []string{commit.ID.String()},
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
gitRepo.LastCommitCache = git.NewLastCommitCache(commitsCount, repo.FullName(), gitRepo, cache.GetCache())
|
||||
}
|
||||
|
||||
return commit.CacheCommit(ctx)
|
||||
return gitRepo.CacheCommit(ctx, commit)
|
||||
}
|
||||
|
||||
@ -140,8 +140,8 @@ 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
|
||||
verification := GetPayloadCommitVerification(ctx, commit)
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, t.gitRepo, commit) // ok if fails, then will be nil
|
||||
verification := GetPayloadCommitVerification(ctx, t.gitRepo, commit)
|
||||
fileResponse := &structs.FileResponse{
|
||||
Commit: fileCommitResponse,
|
||||
Verification: verification,
|
||||
|
||||
@ -12,9 +12,9 @@ import (
|
||||
)
|
||||
|
||||
// GetPayloadCommitVerification returns the verification information of a commit
|
||||
func GetPayloadCommitVerification(ctx context.Context, commit *git.Commit) *structs.PayloadCommitVerification {
|
||||
func GetPayloadCommitVerification(ctx context.Context, gitRepo *git.Repository, commit *git.Commit) *structs.PayloadCommitVerification {
|
||||
verification := &structs.PayloadCommitVerification{}
|
||||
commitVerification := asymkey_service.ParseCommitWithSignature(ctx, commit)
|
||||
commitVerification := asymkey_service.ParseCommitWithSignature(ctx, gitRepo, commit)
|
||||
if commit.Signature != nil {
|
||||
verification.Signature = commit.Signature.Signature
|
||||
verification.Payload = commit.Signature.Payload
|
||||
|
||||
@ -46,7 +46,7 @@ type GetContentsOrListOptions struct {
|
||||
// GetContentsOrList gets the metadata of a file's contents (*ContentsResponse) if treePath not a tree
|
||||
// directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag
|
||||
func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, refCommit *utils.RefCommit, opts GetContentsOrListOptions) (ret api.ContentsExtResponse, _ error) {
|
||||
entry, err := prepareGetContentsEntry(refCommit, &opts.TreePath)
|
||||
entry, err := prepareGetContentsEntry(gitRepo, refCommit, &opts.TreePath)
|
||||
if repo.IsEmpty && opts.TreePath == "" {
|
||||
return api.ContentsExtResponse{DirContents: make([]*api.ContentsResponse, 0)}, nil
|
||||
}
|
||||
@ -61,7 +61,8 @@ func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, gitRepo
|
||||
}
|
||||
|
||||
// list directory contents
|
||||
gitTree, err := refCommit.Commit.SubTree(opts.TreePath)
|
||||
tree := git.NewTree(gitRepo, refCommit.Commit.TreeID)
|
||||
gitTree, err := tree.SubTree(opts.TreePath)
|
||||
if err != nil {
|
||||
return ret, err
|
||||
}
|
||||
@ -99,7 +100,7 @@ func GetObjectTypeFromTreeEntry(entry *git.TreeEntry) ContentType {
|
||||
}
|
||||
}
|
||||
|
||||
func prepareGetContentsEntry(refCommit *utils.RefCommit, treePath *string) (*git.TreeEntry, error) {
|
||||
func prepareGetContentsEntry(gitRepo *git.Repository, refCommit *utils.RefCommit, treePath *string) (*git.TreeEntry, error) {
|
||||
// Check that the path given in opts.treePath is valid (not a git path)
|
||||
cleanTreePath := CleanGitTreePath(*treePath)
|
||||
if cleanTreePath == "" && *treePath != "" {
|
||||
@ -113,12 +114,13 @@ func prepareGetContentsEntry(refCommit *utils.RefCommit, treePath *string) (*git
|
||||
return nil, util.NewNotExistErrorf("no commit found for the ref [ref: %s]", refCommit.RefName)
|
||||
}
|
||||
|
||||
return refCommit.Commit.GetTreeEntryByPath(*treePath)
|
||||
tree := git.NewTree(gitRepo, refCommit.Commit.TreeID)
|
||||
return tree.GetTreeEntryByPath(*treePath)
|
||||
}
|
||||
|
||||
// GetFileContents gets the metadata on a file's contents. Ref can be a branch, commit or tag
|
||||
func GetFileContents(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, refCommit *utils.RefCommit, opts GetContentsOrListOptions) (*api.ContentsResponse, error) {
|
||||
entry, err := prepareGetContentsEntry(refCommit, &opts.TreePath)
|
||||
entry, err := prepareGetContentsEntry(gitRepo, refCommit, &opts.TreePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -146,13 +148,15 @@ func getFileContentsByEntryInternal(_ context.Context, repo *repo_model.Reposito
|
||||
},
|
||||
}
|
||||
|
||||
tree := git.NewTree(gitRepo, commit.TreeID)
|
||||
|
||||
if opts.IncludeCommitMetadata || opts.IncludeCommitMessage {
|
||||
err = gitRepo.AddLastCommitCache(repo.GetCommitsCountCacheKey(refCommit.InputRef, refType != git.RefTypeCommit), repo.FullName(), refCommit.CommitID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lastCommit, err := refCommit.Commit.GetCommitByPath(opts.TreePath)
|
||||
lastCommit, err := gitRepo.GetCommitByPath(refCommit.Commit.ID, opts.TreePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -202,7 +206,7 @@ func getFileContentsByEntryInternal(_ context.Context, repo *repo_model.Reposito
|
||||
contentsResponse.Target = &targetFromContent
|
||||
} else if entry.IsSubModule() {
|
||||
contentsResponse.Type = string(ContentTypeSubmodule)
|
||||
submodule, err := commit.GetSubModule(opts.TreePath)
|
||||
submodule, err := tree.GetSubModule(opts.TreePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -45,8 +45,8 @@ func GetContentsListFromTreePaths(ctx context.Context, repo *repo_model.Reposito
|
||||
|
||||
func GetFilesResponseFromCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, refCommit *utils.RefCommit, treeNames []string) (*api.FilesResponse, error) {
|
||||
files := GetContentsListFromTreePaths(ctx, repo, gitRepo, refCommit, treeNames)
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, refCommit.Commit) // ok if fails, then will be nil
|
||||
verification := GetPayloadCommitVerification(ctx, refCommit.Commit)
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, gitRepo, refCommit.Commit) // ok if fails, then will be nil
|
||||
verification := GetPayloadCommitVerification(ctx, gitRepo, refCommit.Commit)
|
||||
filesResponse := &api.FilesResponse{
|
||||
Files: files,
|
||||
Commit: fileCommitResponse,
|
||||
@ -70,18 +70,19 @@ func GetFileResponseFromFilesResponse(filesResponse *api.FilesResponse, index in
|
||||
}
|
||||
|
||||
// GetFileCommitResponse Constructs a FileCommitResponse from a Commit object
|
||||
func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*api.FileCommitResponse, error) {
|
||||
func GetFileCommitResponse(repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit) (*api.FileCommitResponse, error) {
|
||||
if repo == nil {
|
||||
return nil, errors.New("repo cannot be nil")
|
||||
}
|
||||
if commit == nil {
|
||||
return nil, errors.New("commit cannot be nil")
|
||||
}
|
||||
|
||||
commitURL, _ := url.Parse(repo.APIURL() + "/git/commits/" + url.PathEscape(commit.ID.String()))
|
||||
commitTreeURL, _ := url.Parse(repo.APIURL() + "/git/trees/" + url.PathEscape(commit.Tree.ID.String()))
|
||||
commitTreeURL, _ := url.Parse(repo.APIURL() + "/git/trees/" + url.PathEscape(commit.TreeID.String()))
|
||||
parents := make([]*api.CommitMeta, commit.ParentCount())
|
||||
for i := 0; i <= commit.ParentCount(); i++ {
|
||||
if parent, err := commit.Parent(i); err == nil && parent != nil {
|
||||
if parent, err := gitRepo.ParentCommit(commit, i); err == nil && parent != nil {
|
||||
parentCommitURL, _ := url.Parse(repo.APIURL() + "/git/commits/" + url.PathEscape(parent.ID.String()))
|
||||
parents[i] = &api.CommitMeta{
|
||||
SHA: parent.ID.String(),
|
||||
@ -113,7 +114,7 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap
|
||||
Message: commit.Message(),
|
||||
Tree: &api.CommitMeta{
|
||||
URL: commitTreeURL.String(),
|
||||
SHA: commit.Tree.ID.String(),
|
||||
SHA: commit.TreeID.String(),
|
||||
},
|
||||
Parents: parents,
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user