1
1
mirror of https://github.com/go-gitea/gitea synced 2025-01-10 17:54:27 +00:00

Add rootRepo and ownForkRepo

This commit is contained in:
Lunny Xiao 2024-12-12 00:37:51 -08:00
parent 52639ffaa9
commit a3eb356f7a
No known key found for this signature in database
GPG Key ID: C3B7C91B632F738A
5 changed files with 116 additions and 48 deletions

View File

@ -61,7 +61,7 @@ func CompareDiff(ctx *context.APIContext) {
pathParam := ctx.PathParam("*") pathParam := ctx.PathParam("*")
baseRepo := ctx.Repo.Repository baseRepo := ctx.Repo.Repository
ci, err := common.ParseComparePathParams(ctx, pathParam, baseRepo, ctx.Repo.GitRepo) ci, err := common.ParseComparePathParams(ctx, pathParam, baseRepo, ctx.Repo.GitRepo, ctx.Doer)
if err != nil { if err != nil {
switch { switch {
case user_model.IsErrUserNotExist(err): case user_model.IsErrUserNotExist(err):

View File

@ -403,7 +403,7 @@ func CreatePullRequest(ctx *context.APIContext) {
) )
// Get repo/branch information // Get repo/branch information
ci, err := common.ParseComparePathParams(ctx, form.Base+"..."+form.Head, repo, ctx.Repo.GitRepo) ci, err := common.ParseComparePathParams(ctx, form.Base+"..."+form.Head, repo, ctx.Repo.GitRepo, ctx.Doer)
if err != nil { if err != nil {
switch { switch {
case user_model.IsErrUserNotExist(err): case user_model.IsErrUserNotExist(err):

View File

@ -101,6 +101,8 @@ type CompareInfo struct {
HeadUser *user_model.User HeadUser *user_model.User
HeadRepo *repo_model.Repository HeadRepo *repo_model.Repository
HeadGitRepo *git.Repository HeadGitRepo *git.Repository
RootRepo *repo_model.Repository
OwnForkRepo *repo_model.Repository
CompareInfo *git.CompareInfo CompareInfo *git.CompareInfo
close func() close func()
IsBaseCommit bool IsBaseCommit bool
@ -190,6 +192,20 @@ func findHeadRepoFromRootBase(ctx context.Context, baseRepo *repo_model.Reposito
return nil, nil return nil, nil
} }
func getRootRepo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) {
curRepo := repo
for curRepo.IsFork {
if err := curRepo.GetBaseRepo(ctx); err != nil {
return nil, err
}
if curRepo.BaseRepo == nil {
break
}
curRepo = curRepo.BaseRepo
}
return curRepo, nil
}
// ParseComparePathParams Get compare information // ParseComparePathParams Get compare information
// A full compare url is of the form: // A full compare url is of the form:
// //
@ -215,7 +231,7 @@ func findHeadRepoFromRootBase(ctx context.Context, baseRepo *repo_model.Reposito
// format: <base branch>...[<head repo>:]<head branch> // format: <base branch>...[<head repo>:]<head branch>
// base<-head: master...head:feature // base<-head: master...head:feature
// same repo: master...feature // same repo: master...feature
func ParseComparePathParams(ctx context.Context, pathParam string, baseRepo *repo_model.Repository, baseGitRepo *git.Repository) (*CompareInfo, error) { func ParseComparePathParams(ctx context.Context, pathParam string, baseRepo *repo_model.Repository, baseGitRepo *git.Repository, doer *user_model.User) (*CompareInfo, error) {
ci := &CompareInfo{} ci := &CompareInfo{}
var err error var err error
@ -273,13 +289,37 @@ func ParseComparePathParams(ctx context.Context, pathParam string, baseRepo *rep
} }
} }
// find root repo
if !baseRepo.IsFork {
ci.RootRepo = baseRepo
} else {
if !ci.HeadRepo.IsFork {
ci.RootRepo = ci.HeadRepo
} else {
ci.RootRepo, err = getRootRepo(ctx, baseRepo)
if err != nil {
return nil, err
}
}
}
// find ownfork repo
if doer != nil && ci.HeadRepo.OwnerID != doer.ID && baseRepo.OwnerID != doer.ID {
ci.OwnForkRepo, err = findHeadRepo(ctx, baseRepo, doer.ID)
if err != nil {
return nil, err
}
}
ci.BaseFullRef, ci.IsBaseCommit, err = detectFullRef(ctx, baseRepo.ID, baseGitRepo, ci.BaseOriRef) ci.BaseFullRef, ci.IsBaseCommit, err = detectFullRef(ctx, baseRepo.ID, baseGitRepo, ci.BaseOriRef)
if err != nil { if err != nil {
ci.Close()
return nil, err return nil, err
} }
ci.HeadFullRef, ci.IsHeadCommit, err = detectFullRef(ctx, ci.HeadRepo.ID, ci.HeadGitRepo, ci.HeadOriRef) ci.HeadFullRef, ci.IsHeadCommit, err = detectFullRef(ctx, ci.HeadRepo.ID, ci.HeadGitRepo, ci.HeadOriRef)
if err != nil { if err != nil {
ci.Close()
return nil, err return nil, err
} }
return ci, nil return ci, nil

View File

@ -14,6 +14,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"path/filepath" "path/filepath"
"slices"
"strings" "strings"
"code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/db"
@ -193,7 +194,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
pathParam := ctx.PathParam("*") pathParam := ctx.PathParam("*")
baseRepo := ctx.Repo.Repository baseRepo := ctx.Repo.Repository
ci, err := common.ParseComparePathParams(ctx, pathParam, baseRepo, ctx.Repo.GitRepo) ci, err := common.ParseComparePathParams(ctx, pathParam, baseRepo, ctx.Repo.GitRepo, ctx.Doer)
if err != nil { if err != nil {
switch { switch {
case user_model.IsErrUserNotExist(err): case user_model.IsErrUserNotExist(err):
@ -207,7 +208,6 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
} }
return nil return nil
} }
defer ci.Close()
// remove the check when we support compare with carets // remove the check when we support compare with carets
if ci.CaretTimes > 0 { if ci.CaretTimes > 0 {
@ -245,8 +245,6 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
ctx.Data["CanWriteToHeadRepo"] = permHead.CanWrite(unit.TypeCode) ctx.Data["CanWriteToHeadRepo"] = permHead.CanWrite(unit.TypeCode)
} }
// TODO: prepareRepos, branches and tags for dropdowns
ctx.Data["PageIsComparePull"] = ci.IsPull() && ctx.Repo.CanReadIssuesOrPulls(true) ctx.Data["PageIsComparePull"] = ci.IsPull() && ctx.Repo.CanReadIssuesOrPulls(true)
ctx.Data["BaseName"] = baseRepo.OwnerName ctx.Data["BaseName"] = baseRepo.OwnerName
ctx.Data["BaseBranch"] = ci.BaseOriRef ctx.Data["BaseBranch"] = ci.BaseOriRef
@ -258,7 +256,6 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
ctx.Data["BaseIsBranch"] = ci.BaseFullRef.IsBranch() ctx.Data["BaseIsBranch"] = ci.BaseFullRef.IsBranch()
ctx.Data["BaseIsTag"] = ci.BaseFullRef.IsTag() ctx.Data["BaseIsTag"] = ci.BaseFullRef.IsTag()
ctx.Data["IsPull"] = true ctx.Data["IsPull"] = true
// ctx.Data["OwnForkRepo"] = ownForkRepo FIXME: This is not used
ctx.Data["HeadRepo"] = ci.HeadRepo ctx.Data["HeadRepo"] = ci.HeadRepo
ctx.Data["BaseCompareRepo"] = ctx.Repo.Repository ctx.Data["BaseCompareRepo"] = ctx.Repo.Repository
@ -399,14 +396,8 @@ func PrepareCompareDiff(
return false return false
} }
func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) (branches, tags []string, err error) { func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repository) ([]string, []string, error) {
gitRepo, err := gitrepo.OpenRepository(ctx, repo) branches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
if err != nil {
return nil, nil, err
}
defer gitRepo.Close()
branches, err = git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
RepoID: repo.ID, RepoID: repo.ID,
ListOptions: db.ListOptionsAll, ListOptions: db.ListOptionsAll,
IsDeletedBranch: optional.Some(false), IsDeletedBranch: optional.Some(false),
@ -414,19 +405,82 @@ func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repositor
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
tags, err = gitRepo.GetTags(0, 0) // always put default branch on the top if it exists
if slices.Contains(branches, repo.DefaultBranch) {
branches = util.SliceRemoveAll(branches, repo.DefaultBranch)
branches = append([]string{repo.DefaultBranch}, branches...)
}
tags, err := repo_model.GetTagNamesByRepoID(ctx, repo.ID)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
return branches, tags, nil return branches, tags, nil
} }
func prepareCompareRepoBranchesTagsDropdowns(ctx *context.Context, ci *common.CompareInfo) {
baseRepo := ctx.Repo.Repository
// For compare repo branches
baseBranches, baseTags, err := getBranchesAndTagsForRepo(ctx, baseRepo)
if err != nil {
ctx.ServerError("getBranchesAndTagsForRepo", err)
return
}
ctx.Data["Branches"] = baseBranches
ctx.Data["Tags"] = baseTags
if ci.IsSameRepo() {
ctx.Data["HeadBranches"] = baseBranches
ctx.Data["HeadTags"] = baseTags
} else {
headBranches, headTags, err := getBranchesAndTagsForRepo(ctx, ci.HeadRepo)
if err != nil {
ctx.ServerError("getBranchesAndTagsForRepo", err)
return
}
ctx.Data["HeadBranches"] = headBranches
ctx.Data["HeadTags"] = headTags
}
if ci.RootRepo != nil &&
ci.RootRepo.ID != ci.HeadRepo.ID &&
ci.RootRepo.ID != baseRepo.ID {
canRead := access_model.CheckRepoUnitUser(ctx, ci.RootRepo, ctx.Doer, unit.TypeCode)
if canRead {
ctx.Data["RootRepo"] = ci.RootRepo
branches, tags, err := getBranchesAndTagsForRepo(ctx, ci.RootRepo)
if err != nil {
ctx.ServerError("GetBranchesForRepo", err)
return
}
ctx.Data["RootRepoBranches"] = branches
ctx.Data["RootRepoTags"] = tags
}
}
if ci.OwnForkRepo != nil &&
ci.OwnForkRepo.ID != ci.HeadRepo.ID &&
ci.OwnForkRepo.ID != baseRepo.ID &&
(ci.RootRepo == nil || ci.OwnForkRepo.ID != ci.RootRepo.ID) {
ctx.Data["OwnForkRepo"] = ci.OwnForkRepo
branches, tags, err := getBranchesAndTagsForRepo(ctx, ci.OwnForkRepo)
if err != nil {
ctx.ServerError("GetBranchesForRepo", err)
return
}
ctx.Data["OwnForkRepoBranches"] = branches
ctx.Data["OwnForkRepoTags"] = tags
}
}
// CompareDiff show different from one commit to another commit // CompareDiff show different from one commit to another commit
func CompareDiff(ctx *context.Context) { func CompareDiff(ctx *context.Context) {
ci := ParseCompareInfo(ctx) ci := ParseCompareInfo(ctx)
defer func() { defer func() {
if ci != nil && ci.HeadGitRepo != nil { if ci != nil {
ci.HeadGitRepo.Close() ci.Close()
} }
}() }()
if ctx.Written() { if ctx.Written() {
@ -448,43 +502,17 @@ func CompareDiff(ctx *context.Context) {
return return
} }
baseTags, err := repo_model.GetTagNamesByRepoID(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.ServerError("GetTagNamesByRepoID", err)
return
}
ctx.Data["Tags"] = baseTags
fileOnly := ctx.FormBool("file-only") fileOnly := ctx.FormBool("file-only")
if fileOnly { if fileOnly {
ctx.HTML(http.StatusOK, tplDiffBox) ctx.HTML(http.StatusOK, tplDiffBox)
return return
} }
headBranches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{ prepareCompareRepoBranchesTagsDropdowns(ctx, ci)
RepoID: ci.HeadRepo.ID,
ListOptions: db.ListOptionsAll,
IsDeletedBranch: optional.Some(false),
})
if err != nil {
ctx.ServerError("GetBranches", err)
return
}
ctx.Data["HeadBranches"] = headBranches
// For compare repo branches
PrepareBranchList(ctx)
if ctx.Written() { if ctx.Written() {
return return
} }
headTags, err := repo_model.GetTagNamesByRepoID(ctx, ci.HeadRepo.ID)
if err != nil {
ctx.ServerError("GetTagNamesByRepoID", err)
return
}
ctx.Data["HeadTags"] = headTags
if ctx.Data["PageIsComparePull"] == true { if ctx.Data["PageIsComparePull"] == true {
pr, err := issues_model.GetUnmergedPullRequest(ctx, ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadOriRef, ci.BaseOriRef, issues_model.PullRequestFlowGithub) pr, err := issues_model.GetUnmergedPullRequest(ctx, ci.HeadRepo.ID, ctx.Repo.Repository.ID, ci.HeadOriRef, ci.BaseOriRef, issues_model.PullRequestFlowGithub)
if err != nil { if err != nil {

View File

@ -1266,8 +1266,8 @@ func CompareAndPullRequestPost(ctx *context.Context) {
ci := ParseCompareInfo(ctx) ci := ParseCompareInfo(ctx)
defer func() { defer func() {
if ci != nil && ci.HeadGitRepo != nil { if ci != nil {
ci.HeadGitRepo.Close() ci.Close()
} }
}() }()
if ctx.Written() { if ctx.Written() {