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

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

ref:
* #33893
This commit is contained in:
wxiaoguang
2026-07-16 01:30:01 +08:00
committed by GitHub
parent ed678b9d45
commit 82edc3da01
115 changed files with 732 additions and 864 deletions
+2 -2
View File
@@ -526,7 +526,7 @@ func UpdateBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git
return nil
}
isForcePush, err := newCommit.IsForcePush(branch.CommitID)
isForcePush, err := newCommit.IsForcePush(ctx, gitRepo, branch.CommitID)
if err != nil {
return err
}
@@ -811,7 +811,7 @@ func GetBranchDivergingInfo(ctx reqctx.RequestContext, baseRepo *repo_model.Repo
if err != nil {
return nil, err
}
hasPreviousCommit, _ := headCommit.HasPreviousCommit(baseCommitID)
hasPreviousCommit, _ := headCommit.HasPreviousCommit(ctx, headGitRepo, baseCommitID)
info.BaseHasNewCommits = !hasPreviousCommit
return info, nil
}
+1 -1
View File
@@ -29,5 +29,5 @@ func CacheRef(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep
gitRepo.LastCommitCache = git.NewLastCommitCache(commitsCount, repo.FullName(), gitRepo, cache.GetCache())
}
return commit.CacheCommit(ctx)
return commit.CacheCommit(ctx, gitRepo)
}
+1 -1
View File
@@ -147,7 +147,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod
return nil, err
}
fileCommitResponse, _ := GetFileCommitResponse(repo, commit) // ok if fails, then will be nil
fileCommitResponse, _ := GetFileCommitResponse(repo, gitRepo, commit) // ok if fails, then will be nil
verification := GetPayloadCommitVerification(ctx, commit)
fileResponse := &structs.FileResponse{
Commit: fileCommitResponse,
+10 -10
View File
@@ -43,7 +43,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(ctx, gitRepo, refCommit, &opts.TreePath)
if repo.IsEmpty && opts.TreePath == "" {
return api.ContentsExtResponse{DirContents: make([]*api.ContentsResponse, 0)}, nil
}
@@ -58,11 +58,11 @@ func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, gitRepo
}
// list directory contents
gitTree, err := refCommit.Commit.SubTree(opts.TreePath)
gitTree, err := refCommit.Commit.SubTree(ctx, gitRepo, opts.TreePath)
if err != nil {
return ret, err
}
entries, err := gitTree.ListEntries()
entries, err := gitTree.ListEntries(ctx, gitRepo)
if err != nil {
return ret, err
}
@@ -96,7 +96,7 @@ func GetObjectTypeFromTreeEntry(entry *git.TreeEntry) ContentType {
}
}
func prepareGetContentsEntry(refCommit *utils.RefCommit, treePath *string) (*git.TreeEntry, error) {
func prepareGetContentsEntry(ctx context.Context, 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 != "" {
@@ -110,12 +110,12 @@ 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)
return refCommit.Commit.GetTreeEntryByPath(ctx, gitRepo, *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(ctx, gitRepo, refCommit, &opts.TreePath)
if err != nil {
return nil, err
}
@@ -149,7 +149,7 @@ func getFileContentsByEntryInternal(ctx context.Context, repo *repo_model.Reposi
Name: entry.Name(),
Path: opts.TreePath,
SHA: entry.ID.String(),
Size: entry.Size(),
Size: entry.GetSize(ctx, gitRepo),
URL: &selfURLString,
Links: &api.FileLinksResponse{
Self: &selfURLString,
@@ -162,7 +162,7 @@ func getFileContentsByEntryInternal(ctx context.Context, repo *repo_model.Reposi
return nil, err
}
lastCommit, err := refCommit.Commit.GetCommitByPath(opts.TreePath)
lastCommit, err := refCommit.Commit.GetCommitByPath(gitRepo, opts.TreePath)
if err != nil {
return nil, err
}
@@ -205,14 +205,14 @@ func getFileContentsByEntryInternal(ctx context.Context, repo *repo_model.Reposi
} else if entry.IsLink() {
contentsResponse.Type = string(ContentTypeLink)
// The target of a symlink file is the content of the file
targetFromContent, err := entry.Blob().GetBlobContent(1024)
targetFromContent, err := entry.Blob(gitRepo).GetBlobContent(1024)
if err != nil {
return nil, err
}
contentsResponse.Target = &targetFromContent
} else if entry.IsSubModule() {
contentsResponse.Type = string(ContentTypeSubmodule)
submodule, err := commit.GetSubModule(opts.TreePath)
submodule, err := commit.GetSubModule(ctx, gitRepo, opts.TreePath)
if err != nil {
return nil, err
}
+6 -6
View File
@@ -45,7 +45,7 @@ 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
fileCommitResponse, _ := GetFileCommitResponse(repo, gitRepo, refCommit.Commit) // ok if fails, then will be nil
verification := GetPayloadCommitVerification(ctx, refCommit.Commit)
filesResponse := &api.FilesResponse{
Files: files,
@@ -70,7 +70,7 @@ 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")
}
@@ -78,10 +78,10 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap
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 {
for i := 0; i < commit.ParentCount(); i++ {
if parent, err := commit.Parent(gitRepo, 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 +113,7 @@ func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*ap
Message: commit.MessageUTF8(),
Tree: &api.CommitMeta{
URL: commitTreeURL.String(),
SHA: commit.Tree.ID.String(),
SHA: commit.TreeID.String(),
},
Parents: parents,
}
+1 -1
View File
@@ -211,7 +211,7 @@ func ApplyDiffPatch(ctx context.Context, repo *repo_model.Repository, doer *user
return nil, err
}
fileCommitResponse, _ := GetFileCommitResponse(repo, commit) // ok if fails, then will be nil
fileCommitResponse, _ := GetFileCommitResponse(repo, gitRepo, commit) // ok if fails, then will be nil
verification := GetPayloadCommitVerification(ctx, commit)
fileResponse := &structs.FileResponse{
Commit: fileCommitResponse,
+18 -33
View File
@@ -22,35 +22,20 @@ import (
"gitea.dev/modules/util"
)
// ErrSHANotFound represents a "SHADoesNotMatch" kind of error.
type ErrSHANotFound struct {
SHA string
}
func (err ErrSHANotFound) Error() string {
return fmt.Sprintf("sha not found [%s]", err.SHA)
}
func (err ErrSHANotFound) Unwrap() error {
return util.ErrNotExist
}
// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash.
// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash (id of a commit or a tree)
func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, sha string, page, perPage int, recursive bool) (*api.GitTreeResponse, error) {
gitTree, err := gitRepo.GetTree(sha)
if err != nil || gitTree == nil {
return nil, ErrSHANotFound{ // TODO: this error has never been catch outside of this function
SHA: sha,
}
if err != nil {
return nil, util.NewInvalidArgumentErrorf("sha not found [%s]", sha)
}
tree := new(api.GitTreeResponse)
tree.SHA = gitTree.ResolvedID.String()
tree.URL = repo.APIURL() + "/git/trees/" + url.PathEscape(tree.SHA)
tree.SHA = gitTree.ID.String() // always return the real tree id to end users, but not the commit's id if sha is a commit
tree.URL = repo.APIURL(ctx) + "/git/trees/" + url.PathEscape(tree.SHA)
var entries git.Entries
if recursive {
entries, err = gitTree.ListEntriesRecursiveWithSize()
entries, err = gitTree.ListEntriesRecursiveWithSize(ctx, gitRepo)
} else {
entries, err = gitTree.ListEntries()
entries, err = gitTree.ListEntries(ctx, gitRepo)
}
if err != nil {
return nil, err
@@ -79,7 +64,7 @@ func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git
tree.Entries[i].Path = entries[e].Name()
tree.Entries[i].Mode = fmt.Sprintf("%06o", entries[e].Mode())
tree.Entries[i].Type = entries[e].Type()
tree.Entries[i].Size = entries[e].Size()
tree.Entries[i].Size = entries[e].GetSize(ctx, gitRepo)
tree.Entries[i].SHA = entries[e].ID.String()
if entries[e].IsDir() {
@@ -129,14 +114,14 @@ func (node *TreeViewNode) sortLevel() int {
return util.Iif(node.EntryMode == "tree" || node.EntryMode == "commit", 0, 1)
}
func newTreeViewNodeFromEntry(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, parentDir string, entry *git.TreeEntry) *TreeViewNode {
func newTreeViewNodeFromEntry(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, gitRepo *git.Repository, commit *git.Commit, parentDir string, entry *git.TreeEntry) *TreeViewNode {
node := &TreeViewNode{
EntryName: entry.Name(),
EntryMode: entryModeString(entry.Mode()),
FullPath: path.Join(parentDir, entry.Name()),
}
entryInfo := fileicon.EntryInfoFromGitTreeEntry(commit, node.FullPath, entry)
entryInfo := fileicon.EntryInfoFromGitTreeEntry(ctx, gitRepo, commit, node.FullPath, entry)
node.EntryIcon = fileicon.RenderEntryIconHTML(renderedIconPool, entryInfo)
if entryInfo.EntryMode.IsDir() {
entryInfo.IsOpen = true
@@ -144,7 +129,7 @@ func newTreeViewNodeFromEntry(ctx context.Context, repoLink string, renderedIcon
}
if node.EntryMode == "commit" {
if subModule, err := commit.GetSubModule(node.FullPath); err != nil {
if subModule, err := commit.GetSubModule(ctx, gitRepo, node.FullPath); err != nil {
log.Error("GetSubModule: %v", err)
} else if subModule != nil {
submoduleFile := git.NewCommitSubmoduleFile(repoLink, node.FullPath, subModule.URL, entry.ID.String())
@@ -169,8 +154,8 @@ func sortTreeViewNodes(nodes []*TreeViewNode) {
})
}
func listTreeNodes(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, tree *git.Tree, treePath, subPath string) ([]*TreeViewNode, error) {
entries, err := tree.ListEntries()
func listTreeNodes(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, gitRepo *git.Repository, commit *git.Commit, tree *git.Tree, treePath, subPath string) ([]*TreeViewNode, error) {
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
return nil, err
}
@@ -178,14 +163,14 @@ func listTreeNodes(ctx context.Context, repoLink string, renderedIconPool *filei
subPathDirName, subPathRemaining, _ := strings.Cut(subPath, "/")
nodes := make([]*TreeViewNode, 0, len(entries))
for _, entry := range entries {
node := newTreeViewNodeFromEntry(ctx, repoLink, renderedIconPool, commit, treePath, entry)
node := newTreeViewNodeFromEntry(ctx, repoLink, renderedIconPool, gitRepo, commit, treePath, entry)
nodes = append(nodes, node)
if entry.IsDir() && subPathDirName == entry.Name() {
subTreePath := treePath + "/" + node.EntryName
if subTreePath[0] == '/' {
subTreePath = subTreePath[1:]
}
subNodes, err := listTreeNodes(ctx, repoLink, renderedIconPool, commit, entry.Tree(), subTreePath, subPathRemaining)
subNodes, err := listTreeNodes(ctx, repoLink, renderedIconPool, gitRepo, commit, entry.Tree(gitRepo), subTreePath, subPathRemaining)
if err != nil {
log.Error("listTreeNodes: %v", err)
} else {
@@ -197,10 +182,10 @@ func listTreeNodes(ctx context.Context, repoLink string, renderedIconPool *filei
return nodes, nil
}
func GetTreeViewNodes(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, treePath, subPath string) ([]*TreeViewNode, error) {
entry, err := commit.GetTreeEntryByPath(treePath)
func GetTreeViewNodes(ctx context.Context, repoLink string, renderedIconPool *fileicon.RenderedIconPool, gitRepo *git.Repository, commit *git.Commit, treePath, subPath string) ([]*TreeViewNode, error) {
entry, err := commit.GetTreeEntryByPath(ctx, gitRepo, treePath)
if err != nil {
return nil, err
}
return listTreeNodes(ctx, repoLink, renderedIconPool, commit, entry.Tree(), treePath, subPath)
return listTreeNodes(ctx, repoLink, renderedIconPool, gitRepo, commit, entry.Tree(gitRepo), treePath, subPath)
}
+6 -8
View File
@@ -25,17 +25,15 @@ func TestGetTreeBySHA(t *testing.T) {
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
sha := ctx.Repo.Repository.DefaultBranch
page := 1
perPage := 10
ctx.SetPathParam("id", "1")
ctx.SetPathParam("sha", sha)
ctx.SetPathParam("sha", ctx.Repo.Repository.DefaultBranch)
tree, err := GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.PathParam("sha"), page, perPage, true)
assert.NoError(t, err)
expectedTree := &api.GitTreeResponse{
SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/trees/65f1bf27bc3bf70f64657658635e66094edbcb4d",
SHA: "2a2f1d4670728a2e10049e345bd7a276468beab6",
URL: "https://try.gitea.io/api/v1/repos/user2/repo1/git/trees/2a2f1d4670728a2e10049e345bd7a276468beab6",
Entries: []api.GitEntry{
{
Path: "README.md",
@@ -78,7 +76,7 @@ func TestGetTreeViewNodes(t *testing.T) {
// With basic theme (default for folders), we get octicon icons without IDs
return template.HTML(`<span>octicon-file-directory-open-fill(16/)</span>`)
}
treeNodes, err := GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.Commit, "", "")
treeNodes, err := GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "", "")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
{
@@ -90,7 +88,7 @@ func TestGetTreeViewNodes(t *testing.T) {
},
}, treeNodes)
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.Commit, "", "docs/README.md")
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "", "docs/README.md")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
{
@@ -110,7 +108,7 @@ func TestGetTreeViewNodes(t *testing.T) {
},
}, treeNodes)
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.Commit, "docs", "README.md")
treeNodes, err = GetTreeViewNodes(ctx, curRepoLink, renderedIconPool, ctx.Repo.GitRepo, ctx.Repo.Commit, "docs", "README.md")
assert.NoError(t, err)
assert.Equal(t, []*TreeViewNode{
{
+8 -8
View File
@@ -219,7 +219,7 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use
}
for _, file := range opts.Files {
if err = handleCheckErrors(file, commit, opts); err != nil {
if err = handleCheckErrors(ctx, file, t.gitRepo, commit, opts); err != nil {
return nil, err
}
}
@@ -361,12 +361,12 @@ func (err ErrSHAOrCommitIDNotProvided) Error() string {
}
// handles the check for various issues for ChangeRepoFiles
func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRepoFilesOptions) error {
func handleCheckErrors(ctx context.Context, file *ChangeRepoFile, gitRepo *git.Repository, commit *git.Commit, opts *ChangeRepoFilesOptions) error {
// check old entry (fromTreePath/fromEntry)
if file.Operation == "update" || file.Operation == "upload" || file.Operation == "delete" || file.Operation == "rename" {
var fromEntryIDString string
{
fromEntry, err := commit.GetTreeEntryByPath(file.Options.fromTreePath)
fromEntry, err := commit.GetTreeEntryByPath(ctx, gitRepo, file.Options.fromTreePath)
if file.Operation == "upload" && git.IsErrNotExist(err) {
fromEntry = nil
} else if err != nil {
@@ -391,7 +391,7 @@ func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRep
// If a lastCommitID given doesn't match the branch head's commitID throw
// an error, but only if we aren't creating a new branch.
if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
if changed, err := commit.FileChangedSinceCommit(file.Options.treePath, opts.LastCommitID); err != nil {
if changed, err := commit.FileChangedSinceCommit(gitRepo, file.Options.treePath, opts.LastCommitID); err != nil {
return err
} else if changed {
return ErrCommitIDDoesNotMatch{
@@ -417,7 +417,7 @@ func handleCheckErrors(file *ChangeRepoFile, commit *git.Commit, opts *ChangeRep
subTreePath := ""
for index, part := range treePathParts {
subTreePath = path.Join(subTreePath, part)
entry, err := commit.GetTreeEntryByPath(subTreePath)
entry, err := commit.GetTreeEntryByPath(ctx, gitRepo, subTreePath)
if err != nil {
if git.IsErrNotExist(err) {
// Means there is no item with that name, so we're good
@@ -596,7 +596,7 @@ func writeRepoObjectForRename(ctx context.Context, t *TemporaryUploadRepository,
if err != nil {
return nil, err
}
oldEntry, err := commit.GetTreeEntryByPath(file.Options.fromTreePath)
oldEntry, err := commit.GetTreeEntryByPath(ctx, t.gitRepo, file.Options.fromTreePath)
if err != nil {
return nil, err
}
@@ -619,7 +619,7 @@ func writeRepoObjectForRename(ctx context.Context, t *TemporaryUploadRepository,
}
oldEntryBlobPointerBy := func(f func(r io.Reader) (lfs.Pointer, error)) (lfsPointer lfs.Pointer, err error) {
r, err := oldEntry.Blob().DataAsync()
r, err := oldEntry.Blob(t.gitRepo).DataAsync()
if err != nil {
return lfsPointer, err
}
@@ -645,7 +645,7 @@ func writeRepoObjectForRename(ctx context.Context, t *TemporaryUploadRepository,
if err != nil {
return nil, err
}
ret.LfsContent, err = oldEntry.Blob().DataAsync()
ret.LfsContent, err = oldEntry.Blob(t.gitRepo).DataAsync()
if err != nil {
return nil, err
}
+3 -3
View File
@@ -84,7 +84,7 @@ func repoLicenseUpdater(items ...*LicenseUpdaterOptions) []*LicenseUpdaterOption
log.Error("repoLicenseUpdater [%d] failed: GetBranchCommit: %v", opts.RepoID, err)
continue
}
if err = UpdateRepoLicenses(ctx, repo, commit); err != nil {
if err = UpdateRepoLicenses(ctx, repo, gitRepo, commit); err != nil {
log.Error("repoLicenseUpdater [%d] failed: updateRepoLicenses: %v", opts.RepoID, err)
}
}
@@ -115,12 +115,12 @@ func SyncRepoLicenses(ctx context.Context) error {
}
// UpdateRepoLicenses will update repository licenses col if license file exists
func UpdateRepoLicenses(ctx context.Context, repo *repo_model.Repository, commit *git.Commit) error {
func UpdateRepoLicenses(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, commit *git.Commit) error {
if commit == nil {
return nil
}
b, err := commit.GetBlobByPath(LicenseFileName)
b, err := commit.GetBlobByPath(ctx, gitRepo, LicenseFileName)
if err != nil && !git.IsErrNotExist(err) {
return fmt.Errorf("GetBlobByPath: %w", err)
}
+7 -7
View File
@@ -168,9 +168,9 @@ func pushQueueHandleUpdates(optsList []*repo_module.PushUpdateOptions) error {
// Push new branch.
var l []*git.Commit
if opts.IsNewRef() {
l, err = pushNewBranch(ctx, repo, pusher, opts, newCommit)
l, err = pushNewBranch(ctx, repo, gitRepo, pusher, opts, newCommit)
} else {
l, err = pushUpdateBranch(ctx, repo, pusher, opts, newCommit)
l, err = pushUpdateBranch(ctx, repo, gitRepo, pusher, opts, newCommit)
}
if err != nil {
return err
@@ -264,7 +264,7 @@ func getCompareURL(repo *repo_model.Repository, gitRepo *git.Repository, objectF
return ""
}
func pushNewBranch(ctx context.Context, repo *repo_model.Repository, pusher *user_model.User, opts *repo_module.PushUpdateOptions, newCommit *git.Commit) ([]*git.Commit, error) {
func pushNewBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, pusher *user_model.User, opts *repo_module.PushUpdateOptions, newCommit *git.Commit) ([]*git.Commit, error) {
if repo.IsEmpty { // Change default branch and empty status only if pushed ref is non-empty branch.
repo.DefaultBranch = opts.RefName()
repo.IsEmpty = false
@@ -279,7 +279,7 @@ func pushNewBranch(ctx context.Context, repo *repo_model.Repository, pusher *use
}
}
l, err := newCommit.CommitsBeforeLimit(10)
l, err := newCommit.CommitsBeforeLimit(gitRepo, 10)
if err != nil {
return nil, fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err)
}
@@ -287,15 +287,15 @@ func pushNewBranch(ctx context.Context, repo *repo_model.Repository, pusher *use
return l, nil
}
func pushUpdateBranch(_ context.Context, repo *repo_model.Repository, pusher *user_model.User, opts *repo_module.PushUpdateOptions, newCommit *git.Commit) ([]*git.Commit, error) {
l, err := newCommit.CommitsBeforeUntil(git.RefNameFromCommit(opts.OldCommitID))
func pushUpdateBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, pusher *user_model.User, opts *repo_module.PushUpdateOptions, newCommit *git.Commit) ([]*git.Commit, error) {
l, err := newCommit.CommitsBeforeUntil(gitRepo, git.RefNameFromCommit(opts.OldCommitID))
if err != nil {
return nil, fmt.Errorf("newCommit.CommitsBeforeUntil: %w", err)
}
branch := opts.RefFullName.BranchName()
isForcePush, err := newCommit.IsForcePush(opts.OldCommitID)
isForcePush, err := newCommit.IsForcePush(ctx, gitRepo, opts.OldCommitID)
if err != nil {
log.Error("IsForcePush %s:%s failed: %v", repo.FullName(), branch, err)
}