Skip to content

Move git references checking to gitrepo packages to reduce expose of repository path #33891

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions modules/git/repo_tag.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
package git

import (
"context"
"fmt"
"io"
"strings"
Expand All @@ -17,11 +16,6 @@ import (
// TagPrefix tags prefix path on the repository
const TagPrefix = "refs/tags/"

// IsTagExist returns true if given tag exists in the repository.
func IsTagExist(ctx context.Context, repoPath, name string) bool {
return IsReferenceExist(ctx, repoPath, TagPrefix+name)
}

// CreateTag create one tag in the repository
func (repo *Repository) CreateTag(name, revision string) error {
_, _, err := NewCommand("tag").AddDashesAndList(name, revision).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
Expand Down
18 changes: 18 additions & 0 deletions modules/gitrepo/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,21 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) {
func GetWikiDefaultBranch(ctx context.Context, repo Repository) (string, error) {
return git.GetDefaultBranch(ctx, wikiPath(repo))
}

// IsReferenceExist returns true if given reference exists in the repository.
func IsReferenceExist(ctx context.Context, repo Repository, name string) bool {
return git.IsReferenceExist(ctx, repoPath(repo), name)
}

func IsWikiReferenceExist(ctx context.Context, repo Repository, name string) bool {
return git.IsReferenceExist(ctx, wikiPath(repo), name)
}

// IsBranchExist returns true if given branch exists in the repository.
func IsBranchExist(ctx context.Context, repo Repository, name string) bool {
return IsReferenceExist(ctx, repo, git.BranchPrefix+name)
}

func IsWikiBranchExist(ctx context.Context, repo Repository, name string) bool {
return IsWikiReferenceExist(ctx, repo, git.BranchPrefix+name)
}
15 changes: 15 additions & 0 deletions modules/gitrepo/tag.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package gitrepo

import (
"context"

"code.gitea.io/gitea/modules/git"
)

// IsTagExist returns true if given tag exists in the repository.
func IsTagExist(ctx context.Context, repo Repository, name string) bool {
return IsReferenceExist(ctx, repo, git.TagPrefix+name)
}
4 changes: 2 additions & 2 deletions routers/api/v1/repo/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func CreateBranch(ctx *context.APIContext) {
return
}
} else if len(opt.OldBranchName) > 0 { //nolint
if ctx.Repo.GitRepo.IsBranchExist(opt.OldBranchName) { //nolint
if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, opt.OldBranchName) { //nolint
oldCommit, err = ctx.Repo.GitRepo.GetBranchCommit(opt.OldBranchName) //nolint
if err != nil {
ctx.APIErrorInternal(err)
Expand Down Expand Up @@ -1019,7 +1019,7 @@ func EditBranchProtection(ctx *context.APIContext) {
isPlainRule := !git_model.IsRuleNameSpecial(bpName)
var isBranchExist bool
if isPlainRule {
isBranchExist = git.IsBranchExist(ctx.Req.Context(), ctx.Repo.Repository.RepoPath(), bpName)
isBranchExist = gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, bpName)
}

if isBranchExist {
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -742,7 +742,7 @@ func EditPullRequest(ctx *context.APIContext) {

// change pull target branch
if !pr.HasMerged && len(form.Base) != 0 && form.Base != pr.BaseBranch {
if !ctx.Repo.GitRepo.IsBranchExist(form.Base) {
if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, form.Base) {
ctx.APIError(http.StatusNotFound, fmt.Errorf("new base '%s' not exist", form.Base))
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/api/v1/repo/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err

// Default branch only updated if changed and exist or the repository is empty
updateRepoLicense := false
if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) {
if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, *opts.DefaultBranch)) {
if !repo.IsEmpty {
if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil {
ctx.APIErrorInternal(err)
Expand Down
5 changes: 3 additions & 2 deletions routers/private/hook_pre_receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/web"
Expand Down Expand Up @@ -447,13 +448,13 @@ func preReceiveFor(ctx *preReceiveContext, refFullName git.RefName) {
baseBranchName := refFullName.ForBranchName()

baseBranchExist := false
if ctx.Repo.GitRepo.IsBranchExist(baseBranchName) {
if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, baseBranchName) {
baseBranchExist = true
}

if !baseBranchExist {
for p, v := range baseBranchName {
if v == '/' && ctx.Repo.GitRepo.IsBranchExist(baseBranchName[:p]) && p != len(baseBranchName)-1 {
if v == '/' && gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, baseBranchName[:p]) && p != len(baseBranchName)-1 {
baseBranchExist = true
break
}
Expand Down
8 changes: 4 additions & 4 deletions routers/web/repo/compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,8 +301,8 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {

// Check if base branch is valid.
baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(ci.BaseBranch)
baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(ci.BaseBranch)
baseIsTag := ctx.Repo.GitRepo.IsTagExist(ci.BaseBranch)
baseIsBranch := gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, ci.BaseBranch)
baseIsTag := gitrepo.IsTagExist(ctx, ctx.Repo.Repository, ci.BaseBranch)

if !baseIsCommit && !baseIsBranch && !baseIsTag {
// Check if baseBranch is short sha commit hash
Expand Down Expand Up @@ -504,8 +504,8 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {

// Check if head branch is valid.
headIsCommit := ci.HeadGitRepo.IsCommitExist(ci.HeadBranch)
headIsBranch := ci.HeadGitRepo.IsBranchExist(ci.HeadBranch)
headIsTag := ci.HeadGitRepo.IsTagExist(ci.HeadBranch)
headIsBranch := gitrepo.IsBranchExist(ctx, ci.HeadRepo, ci.HeadBranch)
headIsTag := gitrepo.IsTagExist(ctx, ci.HeadRepo, ci.HeadBranch)
if !headIsCommit && !headIsBranch && !headIsTag {
// Check if headBranch is short sha commit hash
if headCommit, _ := ci.HeadGitRepo.GetCommit(ci.HeadBranch); headCommit != nil {
Expand Down
3 changes: 2 additions & 1 deletion routers/web/repo/issue_comment.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"code.gitea.io/gitea/models/renderhelper"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup/markdown"
repo_module "code.gitea.io/gitea/modules/repository"
Expand Down Expand Up @@ -117,7 +118,7 @@ func NewComment(ctx *context.Context) {
ctx.ServerError("Unable to load head repo", err)
return
}
if ok := git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.BaseBranch); !ok {
if ok := gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.BaseBranch); !ok {
// todo localize
ctx.JSONError("The origin branch is delete, cannot reopen.")
return
Expand Down
3 changes: 2 additions & 1 deletion routers/web/repo/issue_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/emoji"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
Expand Down Expand Up @@ -526,7 +527,7 @@ func preparePullViewDeleteBranch(ctx *context.Context, issue *issues_model.Issue
pull := issue.PullRequest
isPullBranchDeletable := canDelete &&
pull.HeadRepo != nil &&
git.IsBranchExist(ctx, pull.HeadRepo.RepoPath(), pull.HeadBranch) &&
gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.HeadBranch) &&
(!pull.HasMerged || ctx.Data["HeadBranchCommitID"] == ctx.Data["PullHeadCommitID"])

if isPullBranchDeletable && pull.HasMerged {
Expand Down
6 changes: 3 additions & 3 deletions routers/web/repo/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
defer baseGitRepo.Close()
}

if !baseGitRepo.IsBranchExist(pull.BaseBranch) {
if !gitrepo.IsBranchExist(ctx, pull.BaseRepo, pull.BaseBranch) {
ctx.Data["BaseBranchNotExist"] = true
ctx.Data["IsPullRequestBroken"] = true
ctx.Data["BaseTarget"] = pull.BaseBranch
Expand Down Expand Up @@ -404,9 +404,9 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
defer closer.Close()

if pull.Flow == issues_model.PullRequestFlowGithub {
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
headBranchExist = gitrepo.IsBranchExist(ctx, pull.HeadRepo, pull.HeadBranch)
} else {
headBranchExist = git.IsReferenceExist(ctx, baseGitRepo.Path, pull.GetGitRefName())
headBranchExist = gitrepo.IsReferenceExist(ctx, pull.BaseRepo, pull.GetGitRefName())
}

if headBranchExist {
Expand Down
3 changes: 2 additions & 1 deletion routers/web/repo/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -420,7 +421,7 @@ func NewReleasePost(ctx *context.Context) {
return
}

if !ctx.Repo.GitRepo.IsBranchExist(form.Target) {
if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, form.Target) {
ctx.RenderWithErr(ctx.Tr("form.target_branch_not_exist"), tplReleaseNew, &form)
return
}
Expand Down
2 changes: 1 addition & 1 deletion routers/web/repo/setting/default_branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func SetDefaultBranchPost(ctx *context.Context) {
}

branch := ctx.FormString("branch")
if err := repo_service.SetRepoDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, branch); err != nil {
if err := repo_service.SetRepoDefaultBranch(ctx, ctx.Repo.Repository, branch); err != nil {
switch {
case git_model.IsErrBranchNotExist(err):
ctx.Status(http.StatusNotFound)
Expand Down
5 changes: 3 additions & 2 deletions services/agit/agit.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
"code.gitea.io/gitea/modules/setting"
Expand Down Expand Up @@ -56,10 +57,10 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.

baseBranchName := opts.RefFullNames[i].ForBranchName()
currentTopicBranch := ""
if !gitRepo.IsBranchExist(baseBranchName) {
if !gitrepo.IsBranchExist(ctx, repo, baseBranchName) {
// try match refs/for/<target-branch>/<topic-branch>
for p, v := range baseBranchName {
if v == '/' && gitRepo.IsBranchExist(baseBranchName[:p]) && p != len(baseBranchName)-1 {
if v == '/' && gitrepo.IsBranchExist(ctx, repo, baseBranchName[:p]) && p != len(baseBranchName)-1 {
currentTopicBranch = baseBranchName[p+1:]
baseBranchName = baseBranchName[:p]
break
Expand Down
6 changes: 3 additions & 3 deletions services/automerge/automerge.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,13 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {

switch pr.Flow {
case issues_model.PullRequestFlowGithub:
headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch)
if pr.HeadRepo == nil || !headBranchExist {
headBranchExist := pr.HeadRepo != nil && gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch)
if !headBranchExist {
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch)
return
}
case issues_model.PullRequestFlowAGit:
headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName())
headBranchExist := gitrepo.IsReferenceExist(ctx, pr.BaseRepo, pr.GetGitRefName())
if !headBranchExist {
log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch)
return
Expand Down
4 changes: 2 additions & 2 deletions services/context/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,14 +304,14 @@ func RepoRefForAPI(next http.Handler) http.Handler {
refName, _, _ := getRefNameLegacy(ctx.Base, ctx.Repo, ctx.PathParam("*"), ctx.FormTrim("ref"))
var err error

if ctx.Repo.GitRepo.IsBranchExist(refName) {
if gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refName) {
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetBranchCommit(refName)
if err != nil {
ctx.APIErrorInternal(err)
return
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if ctx.Repo.GitRepo.IsTagExist(refName) {
} else if gitrepo.IsTagExist(ctx, ctx.Repo.Repository, refName) {
ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refName)
if err != nil {
ctx.APIErrorInternal(err)
Expand Down
6 changes: 3 additions & 3 deletions services/context/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
reqPath := ctx.PathParam("*")
if reqPath == "" {
refShortName = ctx.Repo.Repository.DefaultBranch
if !ctx.Repo.GitRepo.IsBranchExist(refShortName) {
if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refShortName) {
brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1)
if err == nil && len(brs) != 0 {
refShortName = brs[0].Name
Expand Down Expand Up @@ -854,7 +854,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
return
}

if refType == git.RefTypeBranch && ctx.Repo.GitRepo.IsBranchExist(refShortName) {
if refType == git.RefTypeBranch && gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refShortName) {
ctx.Repo.BranchName = refShortName
ctx.Repo.RefFullName = git.RefNameFromBranch(refShortName)

Expand All @@ -864,7 +864,7 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) {
return
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
} else if refType == git.RefTypeTag && ctx.Repo.GitRepo.IsTagExist(refShortName) {
} else if refType == git.RefTypeTag && gitrepo.IsTagExist(ctx, ctx.Repo.Repository, refShortName) {
ctx.Repo.RefFullName = git.RefNameFromTag(refShortName)

ctx.Repo.Commit, err = ctx.Repo.GitRepo.GetTagCommit(refShortName)
Expand Down
5 changes: 2 additions & 3 deletions services/pull/commit_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/structs"
Expand Down Expand Up @@ -131,10 +130,10 @@ func GetPullRequestCommitStatusState(ctx context.Context, pr *issues_model.PullR
}
defer closer.Close()

if pr.Flow == issues_model.PullRequestFlowGithub && !headGitRepo.IsBranchExist(pr.HeadBranch) {
if pr.Flow == issues_model.PullRequestFlowGithub && !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
return "", errors.New("Head branch does not exist, can not merge")
}
if pr.Flow == issues_model.PullRequestFlowAGit && !git.IsReferenceExist(ctx, headGitRepo.Path, pr.GetGitRefName()) {
if pr.Flow == issues_model.PullRequestFlowAGit && !gitrepo.IsReferenceExist(ctx, pr.HeadRepo, pr.GetGitRefName()) {
return "", errors.New("Head branch does not exist, can not merge")
}

Expand Down
5 changes: 3 additions & 2 deletions services/pull/protected_branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
)

func CreateOrUpdateProtectedBranch(ctx context.Context, repo *repo_model.Repository,
Expand All @@ -22,7 +22,8 @@ func CreateOrUpdateProtectedBranch(ctx context.Context, repo *repo_model.Reposit
isPlainRule := !git_model.IsRuleNameSpecial(protectBranch.RuleName)
var isBranchExist bool
if isPlainRule {
isBranchExist = git.IsBranchExist(ctx, repo.RepoPath(), protectBranch.RuleName)
// TODO: read the database directly to check if the branch exists
isBranchExist = gitrepo.IsBranchExist(ctx, repo, protectBranch.RuleName)
}

if isBranchExist {
Expand Down
2 changes: 1 addition & 1 deletion services/pull/pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ func AddTestPullRequestTask(opts TestPullRequestOptions) {
for _, pr := range prs {
divergence, err := GetDiverging(ctx, pr)
if err != nil {
if git_model.IsErrBranchNotExist(err) && !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) {
if git_model.IsErrBranchNotExist(err) && !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
log.Warn("Cannot test PR %s/%d: head_branch %s no longer exists", pr.BaseRepo.Name, pr.IssueID, pr.HeadBranch)
} else {
log.Error("GetDiverging: %v", err)
Expand Down
3 changes: 2 additions & 1 deletion services/pull/temp_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
)
Expand Down Expand Up @@ -181,7 +182,7 @@ func createTemporaryRepoForPR(ctx context.Context, pr *issues_model.PullRequest)
if err := git.NewCommand("fetch").AddArguments(fetchArgs...).AddDynamicArguments(remoteRepoName, headBranch+":"+trackingBranch).
Run(ctx, prCtx.RunOpts()); err != nil {
cancel()
if !git.IsBranchExist(ctx, pr.HeadRepo.RepoPath(), pr.HeadBranch) {
if !gitrepo.IsBranchExist(ctx, pr.HeadRepo, pr.HeadBranch) {
return nil, nil, git_model.ErrBranchNotExist{
BranchName: pr.HeadBranch,
}
Expand Down
2 changes: 1 addition & 1 deletion services/release/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func createTag(ctx context.Context, gitRepo *git.Repository, rel *repo_model.Rel
var created bool
// Only actual create when publish.
if !rel.IsDraft {
if !gitRepo.IsTagExist(rel.TagName) {
if !gitrepo.IsTagExist(ctx, rel.Repo, rel.TagName) {
if err := rel.LoadAttributes(ctx); err != nil {
log.Error("LoadAttributes: %v", err)
return false, err
Expand Down
Loading