diff --git a/modules/git/remote.go b/modules/git/remote.go index e94ca374e4d..856b1714683 100644 --- a/modules/git/remote.go +++ b/modules/git/remote.go @@ -14,9 +14,9 @@ import ( ) // GetRemoteAddress returns remote url of git repository in the repoPath with special remote name -func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string, error) { +func GetRemoteAddress(ctx context.Context, repo RepositoryFacade, remoteName string) (string, error) { cmd := gitcmd.NewCommand("remote", "get-url").AddDynamicArguments(remoteName) - result, _, err := cmd.WithDir(repoPath).RunStdString(ctx) + result, _, err := cmd.WithRepo(repo).RunStdString(ctx) if err != nil { return "", err } diff --git a/modules/gitrepo/archive.go b/modules/gitrepo/archive.go index b28edfd2aea..10b22236545 100644 --- a/modules/gitrepo/archive.go +++ b/modules/gitrepo/archive.go @@ -12,12 +12,13 @@ import ( "path/filepath" "strings" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" "gitea.dev/modules/setting" ) // CreateArchive create archive content to the target path -func CreateArchive(ctx context.Context, repo Repository, repoName, format string, target io.Writer, commitID string, paths []string) error { +func CreateArchive(ctx context.Context, repo git.RepositoryFacade, repoName, format string, target io.Writer, commitID string, paths []string) error { if format == "unknown" { return fmt.Errorf("unknown format: %v", format) } @@ -33,11 +34,15 @@ func CreateArchive(ctx context.Context, repo Repository, repoName, format string // although "git archive" already ensures the paths won't go outside the repo, we still clean them here for safety cmd.AddDynamicArguments(path.Clean(paths[i])) } - return RunCmdWithStderr(ctx, repo, cmd.WithStdoutCopy(target)) + return cmd.WithStdoutCopy(target).WithRepo(repo).RunWithStderr(ctx) } // CreateBundle create bundle content to the target path -func CreateBundle(ctx context.Context, repo Repository, commit string, out io.Writer) error { +func CreateBundle(ctx context.Context, repo git.RepositoryFacade, commit string, out io.Writer) error { + // TODO: use the following steps instead of creating a temp file, also need to iterate and clean up outdated refs + // git update-ref refs/bundle/temp-{timestamp} {commit} + // git bundle create - refs/bundle/temp-{timestamp} + // git update-ref -d refs/bundle/temp-{timestamp} tmp, cleanup, err := setting.AppDataTempDir("git-repo-content").MkdirTempRandom("gitea-bundle") if err != nil { return err diff --git a/modules/gitrepo/blame.go b/modules/gitrepo/blame.go index 042bbef715f..98b0150ccc3 100644 --- a/modules/gitrepo/blame.go +++ b/modules/gitrepo/blame.go @@ -14,12 +14,12 @@ import ( "gitea.dev/modules/setting" ) -func LineBlame(ctx context.Context, repo Repository, revision, file string, line uint) (string, error) { - stdout, _, err := RunCmdString(ctx, repo, - gitcmd.NewCommand("blame"). - AddOptionFormat("-L %d,%d", line, line). - AddOptionValues("-p", revision). - AddDashesAndList(file)) +func LineBlame(ctx context.Context, repo git.RepositoryFacade, revision, file string, line uint) (string, error) { + stdout, _, err := gitcmd.NewCommand("blame").WithRepo(repo). + AddOptionFormat("-L %d,%d", line, line). + AddOptionValues("-p", revision). + AddDashesAndList(file). + RunStdString(ctx) return stdout, err } @@ -138,8 +138,8 @@ func (r *BlameReader) cleanup() { } } -// CreateBlameReader creates reader for given repository, commit and file -func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo Repository, gitRepo *git.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, retErr error) { +// CreateBlameReader creates reader for given git.RepositoryFacade, commit and file +func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo git.RepositoryFacade, gitRepo *git.Repository, commit *git.Commit, file string, bypassBlameIgnore bool) (rd *BlameReader, retErr error) { defer func() { if retErr != nil { rd.cleanup() @@ -174,7 +174,7 @@ func CreateBlameReader(ctx context.Context, objectFormat git.ObjectFormat, repo go func() { // TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close" - rd.done <- RunCmdWithStderr(ctx, repo, cmd) + rd.done <- cmd.WithRepo(repo).RunWithStderr(ctx) }() return rd, nil diff --git a/modules/gitrepo/branch.go b/modules/gitrepo/branch.go index 9a9d4c8bb5f..87cf4faea35 100644 --- a/modules/gitrepo/branch.go +++ b/modules/gitrepo/branch.go @@ -14,7 +14,7 @@ import ( // GetBranchesByPath returns a branch by its path // if limit = 0 it will not limit -func GetBranchesByPath(ctx context.Context, repo Repository, skip, limit int) ([]string, int, error) { +func GetBranchesByPath(ctx context.Context, repo git.RepositoryFacade, skip, limit int) ([]string, int, error) { gitRepo, err := OpenRepository(repo) if err != nil { return nil, 0, err @@ -24,7 +24,7 @@ func GetBranchesByPath(ctx context.Context, repo Repository, skip, limit int) ([ return gitRepo.GetBranchNames(ctx, skip, limit) } -func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (string, error) { +func GetBranchCommitID(ctx context.Context, repo git.RepositoryFacade, branch string) (string, error) { gitRepo, err := OpenRepository(repo) if err != nil { return "", err @@ -35,15 +35,15 @@ func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (str } // SetDefaultBranch sets default branch of repository. -func SetDefaultBranch(ctx context.Context, repo Repository, name string) error { - _, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD"). - AddDynamicArguments(git.BranchPrefix+name)) +func SetDefaultBranch(ctx context.Context, repo git.RepositoryFacade, name string) error { + _, _, err := gitcmd.NewCommand("symbolic-ref", "HEAD"). + AddDynamicArguments(git.BranchPrefix + name).WithRepo(repo).RunStdString(ctx) return err } // GetDefaultBranch gets default branch of repository. -func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) { - stdout, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("symbolic-ref", "HEAD")) +func GetDefaultBranch(ctx context.Context, repo git.RepositoryFacade) (string, error) { + stdout, _, err := gitcmd.NewCommand("symbolic-ref", "HEAD").WithRepo(repo).RunStdString(ctx) if err != nil { return "", err } @@ -55,18 +55,18 @@ func GetDefaultBranch(ctx context.Context, repo Repository) (string, error) { } // IsReferenceExist returns true if given reference exists in the repository. -func IsReferenceExist(ctx context.Context, repo Repository, name string) bool { - _, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("show-ref", "--verify").AddDashesAndList(name)) +func IsReferenceExist(ctx context.Context, repo git.RepositoryFacade, name string) bool { + _, _, err := gitcmd.NewCommand("show-ref", "--verify").AddDashesAndList(name).WithRepo(repo).RunStdString(ctx) return err == nil } // IsBranchExist returns true if given branch exists in the repository. -func IsBranchExist(ctx context.Context, repo Repository, name string) bool { +func IsBranchExist(ctx context.Context, repo git.RepositoryFacade, name string) bool { return IsReferenceExist(ctx, repo, git.BranchPrefix+name) } // DeleteBranch delete a branch by name on repository. -func DeleteBranch(ctx context.Context, repo Repository, name string, force bool) error { +func DeleteBranch(ctx context.Context, repo git.RepositoryFacade, name string, force bool) error { cmd := gitcmd.NewCommand("branch") if force { @@ -76,21 +76,21 @@ func DeleteBranch(ctx context.Context, repo Repository, name string, force bool) } cmd.AddDashesAndList(name) - _, _, err := RunCmdString(ctx, repo, cmd) + _, _, err := cmd.WithRepo(repo).RunStdString(ctx) return err } // CreateBranch create a new branch -func CreateBranch(ctx context.Context, repo Repository, branch, oldbranchOrCommit string) error { +func CreateBranch(ctx context.Context, repo git.RepositoryFacade, branch, oldbranchOrCommit string) error { cmd := gitcmd.NewCommand("branch") cmd.AddDashesAndList(branch, oldbranchOrCommit) - _, _, err := RunCmdString(ctx, repo, cmd) + _, _, err := cmd.WithRepo(repo).RunStdString(ctx) return err } // RenameBranch rename a branch -func RenameBranch(ctx context.Context, repo Repository, from, to string) error { - _, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("branch", "-m").AddDynamicArguments(from, to)) +func RenameBranch(ctx context.Context, repo git.RepositoryFacade, from, to string) error { + _, _, err := gitcmd.NewCommand("branch", "-m").AddDynamicArguments(from, to).WithRepo(repo).RunStdString(ctx) return err } diff --git a/modules/gitrepo/clone.go b/modules/gitrepo/clone.go index e1718fd8791..521112f9605 100644 --- a/modules/gitrepo/clone.go +++ b/modules/gitrepo/clone.go @@ -10,15 +10,15 @@ import ( ) // CloneExternalRepo clones an external repository to the managed repository. -func CloneExternalRepo(ctx context.Context, fromRemoteURL string, toRepo Repository, opts git.CloneRepoOptions) error { +func CloneExternalRepo(ctx context.Context, fromRemoteURL string, toRepo git.RepositoryFacade, opts git.CloneRepoOptions) error { return git.Clone(ctx, fromRemoteURL, repoPath(toRepo), opts) } // CloneRepoToLocal clones a managed repository to a local path. -func CloneRepoToLocal(ctx context.Context, fromRepo Repository, toLocalPath string, opts git.CloneRepoOptions) error { +func CloneRepoToLocal(ctx context.Context, fromRepo git.RepositoryFacade, toLocalPath string, opts git.CloneRepoOptions) error { return git.Clone(ctx, repoPath(fromRepo), toLocalPath, opts) } -func Clone(ctx context.Context, fromRepo, toRepo Repository, opts git.CloneRepoOptions) error { +func CloneManaged(ctx context.Context, fromRepo, toRepo git.RepositoryFacade, opts git.CloneRepoOptions) error { return git.Clone(ctx, repoPath(fromRepo), repoPath(toRepo), opts) } diff --git a/modules/gitrepo/command.go b/modules/gitrepo/command.go deleted file mode 100644 index 6572f44f51d..00000000000 --- a/modules/gitrepo/command.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2025 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package gitrepo - -import ( - "context" - - "gitea.dev/modules/git/gitcmd" -) - -// TODO: all wrappers can be removed in next PR, because cmd now can accept Repository directly. - -func RunCmd(ctx context.Context, repo Repository, cmd *gitcmd.Command) error { - return cmd.WithRepo(repo).WithParentCallerInfo().Run(ctx) -} - -func RunCmdString(ctx context.Context, repo Repository, cmd *gitcmd.Command) (string, string, gitcmd.RunStdError) { - return cmd.WithRepo(repo).WithParentCallerInfo().RunStdString(ctx) -} - -func RunCmdBytes(ctx context.Context, repo Repository, cmd *gitcmd.Command) ([]byte, []byte, gitcmd.RunStdError) { - return cmd.WithRepo(repo).WithParentCallerInfo().RunStdBytes(ctx) -} - -func RunCmdWithStderr(ctx context.Context, repo Repository, cmd *gitcmd.Command) gitcmd.RunStdError { - return cmd.WithRepo(repo).WithParentCallerInfo().RunWithStderr(ctx) -} diff --git a/modules/gitrepo/commit.go b/modules/gitrepo/commit.go index 24df90c015c..d71bb270562 100644 --- a/modules/gitrepo/commit.go +++ b/modules/gitrepo/commit.go @@ -23,7 +23,7 @@ type CommitsCountOptions struct { } // CommitsCount returns number of total commits of until given revision. -func CommitsCount(ctx context.Context, repo Repository, opts CommitsCountOptions) (int64, error) { +func CommitsCount(ctx context.Context, repo git.RepositoryFacade, opts CommitsCountOptions) (int64, error) { cmd := gitcmd.NewCommand("rev-list", "--count") cmd.AddDynamicArguments(opts.Revision...) @@ -44,7 +44,7 @@ func CommitsCount(ctx context.Context, repo Repository, opts CommitsCountOptions cmd.AddDashesAndList(opts.RelPath...) } - stdout, _, err := cmd.WithDir(repoPath(repo)).RunStdString(ctx) + stdout, _, err := cmd.WithRepo(repo).RunStdString(ctx) if err != nil { return 0, err } @@ -53,7 +53,7 @@ func CommitsCount(ctx context.Context, repo Repository, opts CommitsCountOptions } // FileCommitsCount return the number of files at a revision -func FileCommitsCount(ctx context.Context, repo Repository, revision, file string) (int64, error) { +func FileCommitsCount(ctx context.Context, repo git.RepositoryFacade, revision, file string) (int64, error) { return CommitsCount(ctx, repo, CommitsCountOptions{ Revision: []string{revision}, @@ -62,14 +62,14 @@ func FileCommitsCount(ctx context.Context, repo Repository, revision, file strin } // CommitsCountOfCommit returns number of total commits of until current revision. -func CommitsCountOfCommit(ctx context.Context, repo Repository, commitID string) (int64, error) { +func CommitsCountOfCommit(ctx context.Context, repo git.RepositoryFacade, commitID string) (int64, error) { return CommitsCount(ctx, repo, CommitsCountOptions{ Revision: []string{commitID}, }) } // AllCommitsCount returns count of all commits in repository -func AllCommitsCount(ctx context.Context, repo Repository, hidePRRefs bool, files ...string) (int64, error) { +func AllCommitsCount(ctx context.Context, repo git.RepositoryFacade, hidePRRefs bool, files ...string) (int64, error) { cmd := gitcmd.NewCommand("rev-list") if hidePRRefs { cmd.AddArguments("--exclude=" + git.PullPrefix + "*") @@ -79,7 +79,7 @@ func AllCommitsCount(ctx context.Context, repo Repository, hidePRRefs bool, file cmd.AddDashesAndList(files...) } - stdout, _, err := RunCmdString(ctx, repo, cmd) + stdout, _, err := cmd.WithRepo(repo).RunStdString(ctx) if err != nil { return 0, err } @@ -87,14 +87,13 @@ func AllCommitsCount(ctx context.Context, repo Repository, hidePRRefs bool, file return strconv.ParseInt(strings.TrimSpace(stdout), 10, 64) } -func GetFullCommitID(ctx context.Context, repo Repository, shortID string) (string, error) { +func GetFullCommitID(ctx context.Context, repo git.RepositoryFacade, shortID string) (string, error) { return git.GetFullCommitID(ctx, repoPath(repo), shortID) } // GetLatestCommitTime returns time for latest commit in repository (across all branches) -func GetLatestCommitTime(ctx context.Context, repo Repository) (time.Time, error) { - stdout, _, err := RunCmdString(ctx, repo, - gitcmd.NewCommand("for-each-ref", "--sort=-committerdate", git.BranchPrefix, "--count", "1", "--format=%(committerdate)")) +func GetLatestCommitTime(ctx context.Context, repo git.RepositoryFacade) (time.Time, error) { + stdout, _, err := gitcmd.NewCommand("for-each-ref", "--sort=-committerdate", git.BranchPrefix, "--count", "1", "--format=%(committerdate)").WithRepo(repo).RunStdString(ctx) if err != nil { return time.Time{}, err } diff --git a/modules/gitrepo/commit_file.go b/modules/gitrepo/commit_file.go index ce4f51ffdab..33983fef94c 100644 --- a/modules/gitrepo/commit_file.go +++ b/modules/gitrepo/commit_file.go @@ -8,6 +8,7 @@ import ( "context" "io" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" "gitea.dev/modules/log" ) @@ -66,7 +67,7 @@ func parseCommitFileStatus(fileStatus *CommitFileStatus, stdout io.Reader) { } // GetCommitFileStatus returns file status of commit in given repository. -func GetCommitFileStatus(ctx context.Context, repo Repository, commitID string) (*CommitFileStatus, error) { +func GetCommitFileStatus(ctx context.Context, repo git.RepositoryFacade, commitID string) (*CommitFileStatus, error) { cmd := gitcmd.NewCommand("log", "--name-status", "-m", "--pretty=format:", "--first-parent", "--no-renames", "-z", "-1") stdout, stdoutClose := cmd.MakeStdoutPipe() defer stdoutClose() @@ -77,7 +78,7 @@ func GetCommitFileStatus(ctx context.Context, repo Repository, commitID string) close(done) }() err := cmd.AddDynamicArguments(commitID). - WithDir(repoPath(repo)). + WithRepo(repo). RunWithStderr(ctx) if err != nil { return nil, err diff --git a/modules/gitrepo/compare.go b/modules/gitrepo/compare.go index 2a552986b34..8cce2d0a05c 100644 --- a/modules/gitrepo/compare.go +++ b/modules/gitrepo/compare.go @@ -9,6 +9,7 @@ import ( "strconv" "strings" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" ) @@ -19,10 +20,10 @@ type DivergeObject struct { } // GetDivergingCommits returns the number of commits a targetBranch is ahead or behind a baseBranch -func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targetBranch string) (*DivergeObject, error) { +func GetDivergingCommits(ctx context.Context, repo git.RepositoryFacade, baseBranch, targetBranch string) (*DivergeObject, error) { cmd := gitcmd.NewCommand("rev-list", "--count", "--left-right"). AddDynamicArguments(baseBranch + "..." + targetBranch).AddArguments("--") - stdout, _, err1 := RunCmdString(ctx, repo, cmd) + stdout, _, err1 := cmd.WithRepo(repo).RunStdString(ctx) if err1 != nil { return nil, err1 } @@ -45,7 +46,7 @@ func GetDivergingCommits(ctx context.Context, repo Repository, baseBranch, targe // GetCommitIDsBetweenReverse returns the last commit IDs between two commits in reverse order (from old to new) with limit. // If the result exceeds the limit, the old commits IDs will be ignored -func GetCommitIDsBetweenReverse(ctx context.Context, repo Repository, startRef, endRef, notRef string, limit int) ([]string, error) { +func GetCommitIDsBetweenReverse(ctx context.Context, repo git.RepositoryFacade, startRef, endRef, notRef string, limit int) ([]string, error) { genCmd := func(reversions ...string) *gitcmd.Command { cmd := gitcmd.NewCommand("rev-list", "--reverse"). AddArguments("-n").AddDynamicArguments(strconv.Itoa(limit)). @@ -55,11 +56,11 @@ func GetCommitIDsBetweenReverse(ctx context.Context, repo Repository, startRef, } return cmd } - stdout, _, err := RunCmdString(ctx, repo, genCmd(startRef+".."+endRef)) + stdout, _, err := genCmd(startRef + ".." + endRef).WithRepo(repo).RunStdString(ctx) if gitcmd.IsStderr(err, gitcmd.StderrNoMergeBase) { // if the start and end are not related (no merge base), just get all commits pushed by "end ref" // previously it would return the results of git rev-list before last so let's try that... - stdout, _, err = RunCmdString(ctx, repo, genCmd(endRef)) + stdout, _, err = genCmd(endRef).WithRepo(repo).RunStdString(ctx) } if err != nil { return nil, err diff --git a/modules/gitrepo/config.go b/modules/gitrepo/config.go index 56e3d0e82d3..2c79d1ee9fa 100644 --- a/modules/gitrepo/config.go +++ b/modules/gitrepo/config.go @@ -10,22 +10,22 @@ import ( "gitea.dev/modules/git/gitcmd" ) -// GitConfigAdd add a git configuration key to a specific value for the given repository. -func GitConfigAdd(ctx context.Context, repo Repository, key, value string) error { +// ManagedConfigAdd add a git configuration key to a specific value for the given repository. +func ManagedConfigAdd(ctx context.Context, repo git.RepositoryFacade, key, value string) error { return git.LockConfigAndDo(ctx, repo, func(ctx context.Context) error { - _, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("config", "--add"). - AddDynamicArguments(key, value)) + _, _, err := gitcmd.NewCommand("config", "--add"). + AddDynamicArguments(key, value).WithRepo(repo).RunStdString(ctx) return err }) } -// GitConfigSet updates a git configuration key to a specific value for the given repository. +// ManagedConfigSet updates a git configuration key to a specific value for the given repository. // If the key does not exist, it will be created. // If the key exists, it will be updated to the new value. -func GitConfigSet(ctx context.Context, repo Repository, key, value string) error { +func ManagedConfigSet(ctx context.Context, repo git.RepositoryFacade, key, value string) error { return git.LockConfigAndDo(ctx, repo, func(ctx context.Context) error { - _, _, err := RunCmdString(ctx, repo, gitcmd.NewCommand("config"). - AddDynamicArguments(key, value)) + _, _, err := gitcmd.NewCommand("config"). + AddDynamicArguments(key, value).WithRepo(repo).RunStdString(ctx) return err }) } diff --git a/modules/gitrepo/diff.go b/modules/gitrepo/diff.go index 5aaddf0560a..14880cb1593 100644 --- a/modules/gitrepo/diff.go +++ b/modules/gitrepo/diff.go @@ -10,18 +10,19 @@ import ( "regexp" "strconv" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" ) // GetDiffShortStatByCmdArgs counts number of changed files, number of additions and deletions // TODO: it can be merged with another "GetDiffShortStat" in the future -func GetDiffShortStatByCmdArgs(ctx context.Context, repo Repository, trustedArgs gitcmd.TrustedCmdArgs, dynamicArgs ...string) (numFiles, totalAdditions, totalDeletions int, err error) { +func GetDiffShortStatByCmdArgs(ctx context.Context, repo git.RepositoryFacade, trustedArgs gitcmd.TrustedCmdArgs, dynamicArgs ...string) (numFiles, totalAdditions, totalDeletions int, err error) { // Now if we call: // $ git diff --shortstat 1ebb35b98889ff77299f24d82da426b434b0cca0...788b8b1440462d477f45b0088875 // we get: // " 9902 files changed, 2034198 insertions(+), 298800 deletions(-)\n" cmd := gitcmd.NewCommand("diff", "--shortstat").AddArguments(trustedArgs...).AddDynamicArguments(dynamicArgs...) - stdout, _, err := RunCmdString(ctx, repo, cmd) + stdout, _, err := cmd.WithRepo(repo).RunStdString(ctx) if err != nil { return 0, 0, 0, err } @@ -63,9 +64,9 @@ func parseDiffStat(stdout string) (numFiles, totalAdditions, totalDeletions int, } // GetReverseRawDiff dumps the reverse diff results of repository in given commit ID to io.Writer. -func GetReverseRawDiff(ctx context.Context, repo Repository, commitID string, writer io.Writer) error { - return RunCmdWithStderr(ctx, repo, gitcmd.NewCommand("show", "--pretty=format:revert %H%n", "-R"). +func GetReverseRawDiff(ctx context.Context, repo git.RepositoryFacade, commitID string, writer io.Writer) error { + return gitcmd.NewCommand("show", "--pretty=format:revert %H%n", "-R"). AddDynamicArguments(commitID). - WithStdoutCopy(writer), - ) + WithStdoutCopy(writer). + WithRepo(repo).RunWithStderr(ctx) } diff --git a/modules/gitrepo/fetch.go b/modules/gitrepo/fetch.go index aae43497144..c7efb3e16d5 100644 --- a/modules/gitrepo/fetch.go +++ b/modules/gitrepo/fetch.go @@ -19,10 +19,11 @@ import ( // // This behavior is sufficient for temporary operations, such as determining the // merge base between commits. -func FetchRemoteCommit(ctx context.Context, repo, remoteRepo Repository, commitID string) error { +func FetchRemoteCommit(ctx context.Context, repo, remoteRepo git.RepositoryFacade, commitID string) error { return git.LockWriteAndDo(ctx, repo, func(ctx context.Context) error { - return RunCmd(ctx, repo, gitcmd.NewCommand("fetch", "--no-tags"). + return gitcmd.NewCommand("fetch", "--no-tags"). AddDynamicArguments(repoPath(remoteRepo)). - AddDynamicArguments(commitID)) + AddDynamicArguments(commitID). + WithRepo(repo).Run(ctx) }) } diff --git a/modules/gitrepo/fsck.go b/modules/gitrepo/fsck.go index 42cf9cb4f98..9cc8bd439bb 100644 --- a/modules/gitrepo/fsck.go +++ b/modules/gitrepo/fsck.go @@ -7,10 +7,11 @@ import ( "context" "time" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" ) // Fsck verifies the connectivity and validity of the objects in the database -func Fsck(ctx context.Context, repo Repository, timeout time.Duration, args gitcmd.TrustedCmdArgs) error { - return RunCmd(ctx, repo, gitcmd.NewCommand("fsck").AddArguments(args...).WithTimeout(timeout)) +func Fsck(ctx context.Context, repo git.RepositoryFacade, timeout time.Duration, args gitcmd.TrustedCmdArgs) error { + return gitcmd.NewCommand("fsck").AddArguments(args...).WithTimeout(timeout).WithRepo(repo).Run(ctx) } diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go index 6574ca32345..8d400cafbba 100644 --- a/modules/gitrepo/gitrepo.go +++ b/modules/gitrepo/gitrepo.go @@ -5,11 +5,7 @@ package gitrepo import ( "context" - "fmt" "io" - "io/fs" - "os" - "path/filepath" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" @@ -17,12 +13,7 @@ import ( "gitea.dev/modules/util" ) -type Repository = gitcmd.RepositoryFacade - -var ( - repoPath = gitcmd.RepoLocalPath - OpenRepository = git.OpenRepository -) +var OpenRepository = git.OpenRepository // TODO: can be removed in the future // contextKey is a value for use with context.WithValue. type contextKey struct { @@ -31,7 +22,7 @@ type contextKey struct { // RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it // The caller must call Closer.Close() -func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Repository, io.Closer, error) { +func RepositoryFromContextOrOpen(ctx context.Context, repo git.RepositoryFacade) (*git.Repository, io.Closer, error) { reqCtx := reqctx.FromContext(ctx) if reqCtx != nil { gitRepo, err := RepositoryFromRequestContextOrOpen(reqCtx, repo) @@ -43,7 +34,7 @@ func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Rep // RepositoryFromRequestContextOrOpen opens the repository at the given relative path in the provided request context. // Caller shouldn't close the git repo manually, the git repo will be automatically closed when the request context is done. -func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Repository) (*git.Repository, error) { +func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo git.RepositoryFacade) (*git.Repository, error) { ck := contextKey{key: repo.GitRepoLocation()} if gitRepo, ok := ctx.Value(ck).(*git.Repository); ok { return gitRepo, nil @@ -57,62 +48,7 @@ func RepositoryFromRequestContextOrOpen(ctx reqctx.RequestContext, repo Reposito return gitRepo, nil } -// IsRepositoryExist returns true if the repository directory exists in the disk -func IsRepositoryExist(ctx context.Context, repo Repository) (bool, error) { - return util.IsExist(repoPath(repo)) -} - -// DeleteRepository deletes the repository directory from the disk, it will return -// nil if the repository does not exist. -func DeleteRepository(ctx context.Context, repo Repository) error { - return util.RemoveAll(repoPath(repo)) -} - -// RenameRepository renames a repository's name on disk -func RenameRepository(ctx context.Context, repo, newRepo Repository) error { - dstDir := repoPath(newRepo) - if err := os.MkdirAll(filepath.Dir(dstDir), os.ModePerm); err != nil { - return fmt.Errorf("Failed to create dir %s: %w", filepath.Dir(dstDir), err) - } - - if err := util.Rename(repoPath(repo), dstDir); err != nil { - return fmt.Errorf("rename repository directory: %w", err) - } - return nil -} - -func InitRepository(ctx context.Context, repo Repository, objectFormatName string) error { - return git.InitRepository(ctx, repoPath(repo), true, objectFormatName) -} - -func UpdateServerInfo(ctx context.Context, repo Repository) error { - _, _, err := RunCmdBytes(ctx, repo, gitcmd.NewCommand("update-server-info")) +func UpdateServerInfo(ctx context.Context, repo git.RepositoryFacade) error { + _, _, err := gitcmd.NewCommand("update-server-info").WithRepo(repo).RunStdBytes(ctx) return err } - -func GetRepoFS(repo Repository) fs.FS { - return os.DirFS(repoPath(repo)) -} - -func IsRepoFileExist(ctx context.Context, repo Repository, relativeFilePath string) (bool, error) { - absoluteFilePath := filepath.Join(repoPath(repo), relativeFilePath) - return util.IsExist(absoluteFilePath) -} - -func IsRepoDirExist(ctx context.Context, repo Repository, relativeDirPath string) (bool, error) { - absoluteDirPath := filepath.Join(repoPath(repo), relativeDirPath) - return util.IsDir(absoluteDirPath) -} - -func RemoveRepoFileOrDir(ctx context.Context, repo Repository, relativeFileOrDirPath string) error { - absoluteFilePath := filepath.Join(repoPath(repo), relativeFileOrDirPath) - return util.Remove(absoluteFilePath) -} - -func CreateRepoFile(ctx context.Context, repo Repository, relativeFilePath string) (io.WriteCloser, error) { - absoluteFilePath := filepath.Join(repoPath(repo), relativeFilePath) - if err := os.MkdirAll(filepath.Dir(absoluteFilePath), os.ModePerm); err != nil { - return nil, err - } - return os.Create(absoluteFilePath) -} diff --git a/modules/gitrepo/hooks.go b/modules/gitrepo/hooks.go index 19b24e6abb4..f137ded930f 100644 --- a/modules/gitrepo/hooks.go +++ b/modules/gitrepo/hooks.go @@ -10,6 +10,7 @@ import ( "path/filepath" "runtime" + "gitea.dev/modules/git" "gitea.dev/modules/setting" "gitea.dev/modules/util" ) @@ -107,7 +108,7 @@ done } // CreateDelegateHooks creates all the hooks scripts for the repo -func CreateDelegateHooks(_ context.Context, repo Repository) (err error) { +func CreateDelegateHooks(_ context.Context, repo git.RepositoryFacade) (err error) { return createDelegateHooks(filepath.Join(repoPath(repo), "hooks")) } @@ -174,7 +175,7 @@ func ensureExecutable(filename string) error { } // CheckDelegateHooks checks the hooks scripts for the repo -func CheckDelegateHooks(_ context.Context, repo Repository) ([]string, error) { +func CheckDelegateHooks(_ context.Context, repo git.RepositoryFacade) ([]string, error) { return checkDelegateHooks(filepath.Join(repoPath(repo), "hooks")) } diff --git a/modules/gitrepo/localfs.go b/modules/gitrepo/localfs.go new file mode 100644 index 00000000000..fefdc5d2505 --- /dev/null +++ b/modules/gitrepo/localfs.go @@ -0,0 +1,74 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package gitrepo + +import ( + "context" + "fmt" + "io" + "io/fs" + "os" + "path/filepath" + + "gitea.dev/modules/git" + "gitea.dev/modules/git/gitcmd" + "gitea.dev/modules/util" +) + +var repoPath = gitcmd.RepoLocalPath // some functions need to operate local filesystem directly + +// IsRepositoryExist returns true if the repository directory exists in the disk +func IsRepositoryExist(ctx context.Context, repo git.RepositoryFacade) (bool, error) { + return util.IsExist(repoPath(repo)) +} + +// DeleteRepository deletes the repository directory from the disk, it will return +// nil if the repository does not exist. +func DeleteRepository(ctx context.Context, repo git.RepositoryFacade) error { + return util.RemoveAll(repoPath(repo)) +} + +// RenameRepository renames a repository's name on disk +func RenameRepository(ctx context.Context, repo, newRepo git.RepositoryFacade) error { + dstDir := repoPath(newRepo) + if err := os.MkdirAll(filepath.Dir(dstDir), os.ModePerm); err != nil { + return fmt.Errorf("Failed to create dir %s: %w", filepath.Dir(dstDir), err) + } + + if err := util.Rename(repoPath(repo), dstDir); err != nil { + return fmt.Errorf("rename repository directory: %w", err) + } + return nil +} + +func InitRepository(ctx context.Context, repo git.RepositoryFacade, objectFormatName string) error { + return git.InitRepository(ctx, repoPath(repo), true, objectFormatName) +} + +func GetRepoFS(repo git.RepositoryFacade) fs.FS { + return os.DirFS(repoPath(repo)) +} + +func IsRepoFileExist(ctx context.Context, repo git.RepositoryFacade, relativeFilePath string) (bool, error) { + absoluteFilePath := filepath.Join(repoPath(repo), relativeFilePath) + return util.IsExist(absoluteFilePath) +} + +func IsRepoDirExist(ctx context.Context, repo git.RepositoryFacade, relativeDirPath string) (bool, error) { + absoluteDirPath := filepath.Join(repoPath(repo), relativeDirPath) + return util.IsDir(absoluteDirPath) +} + +func RemoveRepoFileOrDir(ctx context.Context, repo git.RepositoryFacade, relativeFileOrDirPath string) error { + absoluteFilePath := filepath.Join(repoPath(repo), relativeFileOrDirPath) + return util.Remove(absoluteFilePath) +} + +func CreateRepoFile(ctx context.Context, repo git.RepositoryFacade, relativeFilePath string) (io.WriteCloser, error) { + absoluteFilePath := filepath.Join(repoPath(repo), relativeFilePath) + if err := os.MkdirAll(filepath.Dir(absoluteFilePath), os.ModePerm); err != nil { + return nil, err + } + return os.Create(absoluteFilePath) +} diff --git a/modules/gitrepo/merge.go b/modules/gitrepo/merge.go index 831b96102b1..971b7bba001 100644 --- a/modules/gitrepo/merge.go +++ b/modules/gitrepo/merge.go @@ -8,14 +8,15 @@ import ( "fmt" "strings" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" "gitea.dev/modules/util" ) // MergeBase checks and returns merge base of two commits. -func MergeBase(ctx context.Context, repo Repository, baseCommitID, headCommitID string) (string, error) { - mergeBase, stderr, err := RunCmdString(ctx, repo, gitcmd.NewCommand("merge-base"). - AddDashesAndList(baseCommitID, headCommitID)) +func MergeBase(ctx context.Context, repo git.RepositoryFacade, baseCommitID, headCommitID string) (string, error) { + mergeBase, stderr, err := gitcmd.NewCommand("merge-base"). + AddDashesAndList(baseCommitID, headCommitID).WithRepo(repo).RunStdString(ctx) if err != nil { if gitcmd.IsErrorExitCode(err, 1) && strings.TrimSpace(stderr) == "" { return "", util.NewNotExistErrorf("merge-base for %s and %s doesn't exist", baseCommitID, headCommitID) diff --git a/modules/gitrepo/merge_tree.go b/modules/gitrepo/merge_tree.go index a026882f0e3..17c30cd36e5 100644 --- a/modules/gitrepo/merge_tree.go +++ b/modules/gitrepo/merge_tree.go @@ -8,6 +8,7 @@ import ( "context" "fmt" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" "gitea.dev/modules/util" ) @@ -17,7 +18,7 @@ const MaxConflictedDetectFiles = 10 // MergeTree performs a merge between two commits (baseRef and headRef) with an optional merge base. // It returns the resulting tree hash, a list of conflicted files (if any), and an error if the operation fails. // If there are no conflicts, the list of conflicted files will be nil. -func MergeTree(ctx context.Context, repo Repository, baseRef, headRef, mergeBase string) (treeID string, isErrHasConflicts bool, conflictFiles []string, _ error) { +func MergeTree(ctx context.Context, repo git.RepositoryFacade, baseRef, headRef, mergeBase string) (treeID string, isErrHasConflicts bool, conflictFiles []string, _ error) { cmd := gitcmd.NewCommand("merge-tree", "--write-tree", "-z", "--name-only", "--no-messages"). AddOptionFormat("--merge-base=%s", mergeBase). AddDynamicArguments(baseRef, headRef) @@ -47,7 +48,7 @@ func MergeTree(ctx context.Context, repo Repository, baseRef, headRef, mergeBase return scanner.Err() }) - err := RunCmdWithStderr(ctx, repo, cmd) + err := cmd.WithRepo(repo).RunWithStderr(ctx) // For a successful, non-conflicted merge, the exit status is 0. When the merge has conflicts, the exit status is 1. // A merge can have conflicts without having individual files conflict // https://git-scm.com/docs/git-merge-tree/2.38.0#_mistakes_to_avoid diff --git a/modules/gitrepo/push.go b/modules/gitrepo/push.go index c7debe431a8..7fdc11c8c16 100644 --- a/modules/gitrepo/push.go +++ b/modules/gitrepo/push.go @@ -10,18 +10,18 @@ import ( ) // PushToExternal pushes a managed repository to an external remote. -func PushToExternal(ctx context.Context, repo Repository, opts git.PushOptions) error { +func PushToExternal(ctx context.Context, repo git.RepositoryFacade, opts git.PushOptions) error { return git.Push(ctx, repoPath(repo), opts) } -// Push pushes from one managed repository to another managed repository. -func Push(ctx context.Context, fromRepo, toRepo Repository, opts git.PushOptions) error { +// PushManaged pushes from one managed repository to another managed repository. +func PushManaged(ctx context.Context, fromRepo, toRepo git.RepositoryFacade, opts git.PushOptions) error { opts.Remote = repoPath(toRepo) return git.Push(ctx, repoPath(fromRepo), opts) } // PushFromLocal pushes from a local path to a managed repository. -func PushFromLocal(ctx context.Context, fromLocalPath string, toRepo Repository, opts git.PushOptions) error { +func PushFromLocal(ctx context.Context, fromLocalPath string, toRepo git.RepositoryFacade, opts git.PushOptions) error { opts.Remote = repoPath(toRepo) return git.Push(ctx, fromLocalPath, opts) } diff --git a/modules/gitrepo/ref.go b/modules/gitrepo/ref.go index f8f78d4bcc5..17c908e6345 100644 --- a/modules/gitrepo/ref.go +++ b/modules/gitrepo/ref.go @@ -6,14 +6,14 @@ package gitrepo import ( "context" + "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" ) -func UpdateRef(ctx context.Context, repo Repository, refName, newCommitID string) error { - return RunCmd(ctx, repo, gitcmd.NewCommand("update-ref").AddDynamicArguments(refName, newCommitID)) +func UpdateRef(ctx context.Context, repo git.RepositoryFacade, refName, newCommitID string) error { + return gitcmd.NewCommand("update-ref").AddDynamicArguments(refName, newCommitID).WithRepo(repo).Run(ctx) } -func RemoveRef(ctx context.Context, repo Repository, refName string) error { - return RunCmd(ctx, repo, gitcmd.NewCommand("update-ref", "--no-deref", "-d"). - AddDynamicArguments(refName)) +func RemoveRef(ctx context.Context, repo git.RepositoryFacade, refName string) error { + return gitcmd.NewCommand("update-ref", "--no-deref", "-d").AddDynamicArguments(refName).WithRepo(repo).Run(ctx) } diff --git a/modules/gitrepo/remote.go b/modules/gitrepo/remote.go index 96a68d2fdd7..50af148133c 100644 --- a/modules/gitrepo/remote.go +++ b/modules/gitrepo/remote.go @@ -20,7 +20,7 @@ const ( RemoteOptionMirrorFetch RemoteOption = "--mirror=fetch" ) -func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...RemoteOption) error { +func ManagedRemoteAdd(ctx context.Context, repo git.RepositoryFacade, remoteName, remoteURL string, options ...RemoteOption) error { return git.LockConfigAndDo(ctx, repo, func(ctx context.Context) error { cmd := gitcmd.NewCommand("remote", "add") if len(options) > 0 { @@ -33,22 +33,22 @@ func GitRemoteAdd(ctx context.Context, repo Repository, remoteName, remoteURL st return errors.New("unknown remote option: " + string(options[0])) } } - _, _, err := RunCmdString(ctx, repo, cmd.AddDynamicArguments(remoteName, remoteURL)) + _, _, err := cmd.AddDynamicArguments(remoteName, remoteURL).WithRepo(repo).RunStdString(ctx) return err }) } -func GitRemoteRemove(ctx context.Context, repo Repository, remoteName string) error { +func ManagedRemoteRemove(ctx context.Context, repo git.RepositoryFacade, remoteName string) error { return git.LockConfigAndDo(ctx, repo, func(ctx context.Context) error { cmd := gitcmd.NewCommand("remote", "rm").AddDynamicArguments(remoteName) - _, _, err := RunCmdString(ctx, repo, cmd) + _, _, err := cmd.WithRepo(repo).RunStdString(ctx) return err }) } // GitRemoteGetURL returns the url of a specific remote of the repository. -func GitRemoteGetURL(ctx context.Context, repo Repository, remoteName string) (*giturl.GitURL, error) { - addr, err := git.GetRemoteAddress(ctx, repoPath(repo), remoteName) +func GitRemoteGetURL(ctx context.Context, repo git.RepositoryFacade, remoteName string) (*giturl.GitURL, error) { + addr, err := git.GetRemoteAddress(ctx, repo, remoteName) if err != nil { return nil, err } diff --git a/modules/gitrepo/size.go b/modules/gitrepo/size.go index 7524bb25422..d637e5d986c 100644 --- a/modules/gitrepo/size.go +++ b/modules/gitrepo/size.go @@ -6,12 +6,14 @@ package gitrepo import ( "os" "path/filepath" + + "gitea.dev/modules/git" ) const notRegularFileMode = os.ModeSymlink | os.ModeNamedPipe | os.ModeSocket | os.ModeDevice | os.ModeCharDevice | os.ModeIrregular // CalcRepositorySize returns the disk consumption for a given path -func CalcRepositorySize(repo Repository) (int64, error) { +func CalcRepositorySize(repo git.RepositoryFacade) (int64, error) { var size int64 err := filepath.WalkDir(repoPath(repo), func(_ string, entry os.DirEntry, err error) error { if os.IsNotExist(err) { // ignore the error because some files (like temp/lock file) may be deleted during traversing. diff --git a/modules/gitrepo/tag.go b/modules/gitrepo/tag.go index 47abcac8ceb..cddea4c8bbc 100644 --- a/modules/gitrepo/tag.go +++ b/modules/gitrepo/tag.go @@ -10,6 +10,6 @@ import ( ) // IsTagExist returns true if given tag exists in the repository. -func IsTagExist(ctx context.Context, repo Repository, name string) bool { +func IsTagExist(ctx context.Context, repo git.RepositoryFacade, name string) bool { return IsReferenceExist(ctx, repo, git.TagPrefix+name) } diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go index 46ef2533f56..a5f326cd06c 100644 --- a/modules/indexer/code/bleve/bleve.go +++ b/modules/indexer/code/bleve/bleve.go @@ -16,7 +16,6 @@ import ( "gitea.dev/modules/charset" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" - "gitea.dev/modules/gitrepo" "gitea.dev/modules/indexer" path_filter "gitea.dev/modules/indexer/code/bleve/token/path" "gitea.dev/modules/indexer/code/internal" @@ -163,7 +162,7 @@ func (b *Indexer) addUpdate(ctx context.Context, catFileBatch git.CatFileBatch, var err error if !update.Sized { var stdout string - stdout, _, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha)) + stdout, _, err = gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).WithRepo(repo).RunStdString(ctx) if err != nil { return err } diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go index bc1aed1a227..c0b20735b18 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch.go +++ b/modules/indexer/code/elasticsearch/elasticsearch.go @@ -15,7 +15,6 @@ import ( "gitea.dev/modules/charset" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" - "gitea.dev/modules/gitrepo" "gitea.dev/modules/indexer" "gitea.dev/modules/indexer/code/internal" es "gitea.dev/modules/indexer/internal/elasticsearch" @@ -134,7 +133,7 @@ func (b *Indexer) addUpdate(ctx context.Context, catFileBatch git.CatFileBatch, var err error if !update.Sized { var stdout string - stdout, _, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha)) + stdout, _, err = gitcmd.NewCommand("cat-file", "-s").AddDynamicArguments(update.BlobSha).WithRepo(repo).RunStdString(ctx) if err != nil { return nil, err } diff --git a/modules/indexer/code/git.go b/modules/indexer/code/git.go index e1ca1ff4b9a..4e7d50a4f07 100644 --- a/modules/indexer/code/git.go +++ b/modules/indexer/code/git.go @@ -11,14 +11,13 @@ import ( repo_model "gitea.dev/models/repo" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" - "gitea.dev/modules/gitrepo" "gitea.dev/modules/indexer/code/internal" "gitea.dev/modules/log" "gitea.dev/modules/setting" ) func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) { - stdout, _, err := gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("show-ref", "-s").AddDynamicArguments(git.BranchPrefix+repo.DefaultBranch)) + stdout, _, err := gitcmd.NewCommand("show-ref", "-s").AddDynamicArguments(git.BranchPrefix + repo.DefaultBranch).WithRepo(repo).RunStdString(ctx) if err != nil { return "", err } @@ -35,7 +34,7 @@ func getRepoChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *g needGenesis := len(status.CommitSha) == 0 if !needGenesis { hasAncestorCmd := gitcmd.NewCommand("merge-base").AddDynamicArguments(status.CommitSha, revision) - stdout, _, _ := gitrepo.RunCmdString(ctx, repo, hasAncestorCmd) // FIXME: error is not handled + stdout, _, _ := hasAncestorCmd.WithRepo(repo).RunStdString(ctx) // FIXME: error is not handled needGenesis = len(stdout) == 0 } @@ -88,7 +87,7 @@ func parseGitLsTreeOutput(ctx context.Context, gitRepo *git.Repository, stdout [ // genesisChanges get changes to add repo to the indexer for the first time func genesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, revision string) (*internal.RepoChanges, error) { var changes internal.RepoChanges - stdout, _, runErr := gitrepo.RunCmdBytes(ctx, repo, gitcmd.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision)) + stdout, _, runErr := gitcmd.NewCommand("ls-tree", "--full-tree", "-l", "-r").AddDynamicArguments(revision).WithRepo(repo).RunStdBytes(ctx) if runErr != nil { return nil, runErr } @@ -101,7 +100,7 @@ func genesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *g // nonGenesisChanges get changes since the previous indexer update func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, revision string) (*internal.RepoChanges, error) { diffCmd := gitcmd.NewCommand("diff", "--name-status").AddDynamicArguments(repo.CodeIndexerStatus.CommitSha, revision) - stdout, _, runErr := gitrepo.RunCmdString(ctx, repo, diffCmd) + stdout, _, runErr := diffCmd.WithRepo(repo).RunStdString(ctx) if runErr != nil { // previous commit sha may have been removed by a force push, so // try rebuilding from scratch @@ -119,7 +118,7 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, gitRepo updateChanges := func() error { cmd := gitcmd.NewCommand("ls-tree", "--full-tree", "-l").AddDynamicArguments(revision). AddDashesAndList(updatedFilenames...) - lsTreeStdout, _, err := gitrepo.RunCmdBytes(ctx, repo, cmd) + lsTreeStdout, _, err := cmd.WithRepo(repo).RunStdBytes(ctx) if err != nil { return err } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index 4a2ca016001..3bf39bfe868 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1597,7 +1597,7 @@ func GetPullRequestFiles(ctx *context.APIContext) { return } - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ctx.Repo.Repository, baseGitRepo, startCommitID, endCommitID) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, baseGitRepo, startCommitID, endCommitID) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 2036ff14217..3f350683470 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -18,7 +18,6 @@ import ( user_model "gitea.dev/models/user" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" - "gitea.dev/modules/gitrepo" "gitea.dev/modules/log" "gitea.dev/modules/private" "gitea.dev/modules/util" @@ -199,12 +198,9 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r // 2. Disallow force pushes to protected branches if oldCommitID != objectFormat.EmptyObjectID().String() { - output, _, err := gitrepo.RunCmdString(ctx, - repo, - gitcmd.NewCommand("rev-list", "--max-count=1"). - AddDynamicArguments(oldCommitID, "^"+newCommitID). - WithEnv(ctx.env), - ) + output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1"). + AddDynamicArguments(oldCommitID, "^"+newCommitID). + WithEnv(ctx.env).WithRepo(repo).RunStdString(ctx) if err != nil { log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err) ctx.JSON(http.StatusInternalServerError, private.Response{ diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go index ab91ab01f05..ccadbfe1d35 100644 --- a/routers/web/repo/branch.go +++ b/routers/web/repo/branch.go @@ -138,7 +138,7 @@ func RestoreBranchPost(ctx *context.Context) { return } - if err := gitrepo.Push(ctx, ctx.Repo.Repository, ctx.Repo.Repository, git.PushOptions{ + if err := gitrepo.PushManaged(ctx, ctx.Repo.Repository, ctx.Repo.Repository, git.PushOptions{ Branch: fmt.Sprintf("%s:%s%s", deletedBranch.CommitID, git.BranchPrefix, deletedBranch.Name), Env: repo_module.PushingEnvironment(ctx.Doer, ctx.Repo.Repository), }); err != nil { diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go index c5108c39c49..e06d495b8b1 100644 --- a/routers/web/repo/commit.go +++ b/routers/web/repo/commit.go @@ -288,13 +288,11 @@ func Diff(ctx *context.Context) { DiffStyle: GetDiffViewStyle(ctx), AfterCommitID: commitID, } - gitRepo := ctx.Repo.GitRepo - var gitRepoStore gitrepo.Repository = ctx.Repo.Repository + gitRepo := ctx.Repo.GitRepo // don't access ctx.Repo.GitRepo anymore, because it might not be right for wiki repo if ctx.Data["PageIsWiki"] != nil { var err error - gitRepoStore = ctx.Repo.Repository.WikiStorageRepo() - gitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, gitRepoStore) + gitRepo, err = gitrepo.RepositoryFromRequestContextOrOpen(ctx, ctx.Repo.Repository.WikiStorageRepo()) if err != nil { ctx.ServerError("Repo.GitRepo.GetCommit", err) return @@ -334,7 +332,7 @@ func Diff(ctx *context.Context) { ctx.NotFound(err) return } - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, gitRepoStore, gitRepo, "", commitID) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, gitRepo, "", commitID) if err != nil { ctx.ServerError("GetDiffShortStat", err) return @@ -410,7 +408,7 @@ func Diff(ctx *context.Context) { } note := &git.Note{} - err = git.GetNote(ctx, ctx.Repo.GitRepo, commitID, note) + err = git.GetNote(ctx, gitRepo, commitID, note) if err == nil { ctx.Data["NoteCommit"] = note.Commit ctx.Data["NoteAuthor"] = user_model.GetUserByGitAuthor(ctx, note.Commit) diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go index 5ee4aa7a744..d9cb02467b5 100644 --- a/routers/web/repo/compare.go +++ b/routers/web/repo/compare.go @@ -426,7 +426,7 @@ func (cpi *comparePageInfoType) prepareCompareDiff(ctx *context.Context, whitesp ctx.ServerError("GetDiff", err) return } - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ci.HeadRepo, ci.HeadGitRepo, beforeCommitID, headCommitID) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ci.HeadGitRepo, beforeCommitID, headCommitID) if err != nil { ctx.ServerError("GetDiffShortStat", err) return diff --git a/routers/web/repo/editor_util.go b/routers/web/repo/editor_util.go index 523d4547c32..5afb05cbf66 100644 --- a/routers/web/repo/editor_util.go +++ b/routers/web/repo/editor_util.go @@ -128,7 +128,7 @@ func getUniqueRepositoryName(ctx context.Context, ownerID int64, name string) st } func editorPushBranchToForkedRepository(ctx context.Context, doer *user_model.User, baseRepo *repo_model.Repository, baseBranchName string, targetRepo *repo_model.Repository, targetBranchName string) error { - return gitrepo.Push(ctx, baseRepo, targetRepo, git.PushOptions{ + return gitrepo.PushManaged(ctx, baseRepo, targetRepo, git.PushOptions{ Branch: baseBranchName + ":" + targetBranchName, Env: repo_module.PushingEnvironment(doer, targetRepo), }) diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index 15577e245c8..0e168dc341b 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -306,11 +306,11 @@ type serviceHandler struct { environ []string } -func (h *serviceHandler) getStorageRepo() gitrepo.Repository { +func (h *serviceHandler) getStorageRepo() git.RepositoryFacade { if h.isWiki { return h.repo.WikiStorageRepo() } - return h.repo + return h.repo.CodeStorageRepo() } func setHeaderNoCache(ctx *context.Context) { @@ -412,11 +412,12 @@ func serviceRPC(ctx *context.Context, service string) { h.environ = append(h.environ, "GIT_PROTOCOL="+protocol) } - if err := gitrepo.RunCmdWithStderr(ctx, h.getStorageRepo(), cmd.AddArguments("."). - WithEnv(append(os.Environ(), h.environ...)). + err := cmd.AddArguments("."). + WithRepo(h.getStorageRepo()).WithEnv(append(os.Environ(), h.environ...)). WithStdinCopy(reqBody). - WithStdoutCopy(ctx.Resp), - ); err != nil { + WithStdoutCopy(ctx.Resp). + RunWithStderr(ctx) + if err != nil { if !gitcmd.IsErrorCanceledOrKilled(err) { repoLogName := h.repo.FullName() + util.Iif(h.isWiki, ".wiki", "") log.Error("Fail to serve RPC(%s) for repo %s: %v", service, repoLogName, err) @@ -482,7 +483,7 @@ func GetInfoRefs(ctx *context.Context) { h.environ = append(os.Environ(), h.environ...) cmd = cmd.AddArguments("--stateless-rpc", "--advertise-refs", ".").WithEnv(h.environ) - refs, _, err := gitrepo.RunCmdBytes(ctx, h.getStorageRepo(), cmd) + refs, _, err := cmd.WithRepo(h.getStorageRepo()).RunStdBytes(ctx) if err != nil { ctx.ServerError("RunGitServiceAdvertiseRefs", err) return diff --git a/routers/web/repo/issue_comment.go b/routers/web/repo/issue_comment.go index 4681c2fecd9..d2eb1eab18e 100644 --- a/routers/web/repo/issue_comment.go +++ b/routers/web/repo/issue_comment.go @@ -146,7 +146,7 @@ func NewComment(ctx *context.Context) { if prHeadCommitID != headBranchCommitID { // force push to base repo - err := gitrepo.Push(ctx, pull.HeadRepo, pull.BaseRepo, git.PushOptions{ + err := gitrepo.PushManaged(ctx, pull.HeadRepo, pull.BaseRepo, git.PushOptions{ Branch: pull.HeadBranch + ":" + prHeadRef, Force: true, Env: repo_module.InternalPushingEnvironment(pull.Issue.Poster, pull.BaseRepo), diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go index 379a0111210..a770c14aaaf 100644 --- a/routers/web/repo/pull.go +++ b/routers/web/repo/pull.go @@ -210,7 +210,7 @@ func GetPullDiffStats(ctx *context.Context) { log.Error("Failed to GetRefCommitID: %v, repo: %v", err, ctx.Repo.Repository.FullName()) return } - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, mergeBaseCommitID, headCommitID) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ctx.Repo.GitRepo, mergeBaseCommitID, headCommitID) if err != nil { log.Error("Failed to GetDiffShortStat: %v, repo: %v", err, ctx.Repo.Repository.FullName()) return @@ -243,8 +243,8 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri } if commitSHA != "" { // Get immediate parent of the first commit in the patch, grab history back - parentCommit, _, err = gitrepo.RunCmdString(ctx, ctx.Repo.Repository, - gitcmd.NewCommand("rev-list", "-1", "--skip=1").AddDynamicArguments(commitSHA)) + parentCommit, _, err = gitcmd.NewCommand("rev-list", "-1", "--skip=1"). + AddDynamicArguments(commitSHA).WithRepo(ctx.Repo.Repository).RunStdString(ctx) if err == nil { parentCommit = strings.TrimSpace(parentCommit) } @@ -811,7 +811,7 @@ func viewPullFiles(ctx *context.Context, beforeCommitID, afterCommitID string) { } } - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, beforeCommitID, afterCommitID) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, ctx.Repo.GitRepo, beforeCommitID, afterCommitID) if err != nil { ctx.ServerError("GetDiffShortStat", err) return diff --git a/services/agit/agit.go b/services/agit/agit.go index 2624312b9ab..8b2bb575fd9 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -16,7 +16,6 @@ import ( user_model "gitea.dev/models/user" "gitea.dev/modules/git" "gitea.dev/modules/git/gitcmd" - "gitea.dev/modules/gitrepo" "gitea.dev/modules/log" "gitea.dev/modules/private" "gitea.dev/modules/setting" @@ -225,10 +224,8 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git. } if !forcePush.Value() { - output, _, err := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("rev-list", "--max-count=1"). - AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]), - ) + output, _, err := gitcmd.NewCommand("rev-list", "--max-count=1"). + AddDynamicArguments(oldCommitID, "^"+opts.NewCommitIDs[i]).WithRepo(repo).RunStdString(ctx) if err != nil { return nil, fmt.Errorf("failed to detect force push: %w", err) } else if len(output) > 0 { diff --git a/services/convert/git_commit.go b/services/convert/git_commit.go index f19ec439115..855f0f79d39 100644 --- a/services/convert/git_commit.go +++ b/services/convert/git_commit.go @@ -210,7 +210,7 @@ func ToCommit(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Rep // Get diff stats for commit if opts.Stat { - diffShortStat, err := gitdiff.GetDiffShortStat(ctx, repo, gitRepo, "", commit.ID.String()) + diffShortStat, err := gitdiff.GetDiffShortStat(ctx, gitRepo, "", commit.ID.String()) if err != nil { return nil, err } diff --git a/services/convert/pull.go b/services/convert/pull.go index 74560837e10..884fb06543a 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -236,7 +236,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u // Calculate diff startCommitID = pr.MergeBase - diffShortStats, err := gitdiff.GetDiffShortStat(ctx, pr.BaseRepo, gitRepo, startCommitID, endCommitID) + diffShortStats, err := gitdiff.GetDiffShortStat(ctx, gitRepo, startCommitID, endCommitID) if err != nil { log.Error("GetDiffShortStat: %v", err) } else { diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go index 1effa754037..0ccde7a1996 100644 --- a/services/gitdiff/gitdiff.go +++ b/services/gitdiff/gitdiff.go @@ -1491,7 +1491,7 @@ type DiffShortStat struct { NumFiles, TotalAddition, TotalDeletion int } -func GetDiffShortStat(ctx context.Context, repoStorage gitrepo.Repository, gitRepo *git.Repository, beforeCommitID, afterCommitID string) (*DiffShortStat, error) { +func GetDiffShortStat(ctx context.Context, gitRepo *git.Repository, beforeCommitID, afterCommitID string) (*DiffShortStat, error) { afterCommit, err := gitRepo.GetCommit(ctx, afterCommitID) if err != nil { return nil, err @@ -1503,7 +1503,7 @@ func GetDiffShortStat(ctx context.Context, repoStorage gitrepo.Repository, gitRe } diff := &DiffShortStat{} - diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = gitrepo.GetDiffShortStatByCmdArgs(ctx, repoStorage, nil, actualBeforeCommitID.String(), afterCommitID) + diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = gitrepo.GetDiffShortStatByCmdArgs(ctx, gitRepo, nil, actualBeforeCommitID.String(), afterCommitID) if err != nil { return nil, err } diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index 8379e448f5b..f5b9177ee0d 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -670,7 +670,7 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba fetchArg = git.BranchPrefix + fetchArg } - _, _, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg)) + _, _, err = gitcmd.NewCommand("fetch", "--no-tags").AddDashesAndList(remote, fetchArg).WithRepo(g.repo).RunStdString(ctx) if err != nil { log.Error("Fetch branch from %s failed: %v", pr.Head.CloneURL, err) return head, nil @@ -705,7 +705,8 @@ func (g *GiteaLocalUploader) updateGitForPullRequest(ctx context.Context, pr *ba // The SHA is empty log.Warn("Empty reference, no pull head for PR #%d in %s/%s", pr.Number, g.repoOwner, g.repoName) } else { - _, _, err = gitrepo.RunCmdString(ctx, g.repo, gitcmd.NewCommand("rev-list", "--quiet", "-1").AddDynamicArguments(pr.Head.SHA)) + _, _, err = gitcmd.NewCommand("rev-list", "--quiet", "-1"). + AddDynamicArguments(pr.Head.SHA).WithRepo(g.repo).RunStdString(ctx) if err != nil { // Git update-ref remove bad references with a relative path log.Warn("Deprecated local head %s for PR #%d in %s/%s, removing %s", pr.Head.SHA, pr.Number, g.repoOwner, g.repoName, pr.GetGitHeadRefName()) diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index fa8bf0e94c0..34a1cabfbc4 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -40,12 +40,12 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error remoteName := m.GetRemoteName() repo := m.GetRepository(ctx) // Remove old remote - err = gitrepo.GitRemoteRemove(ctx, repo, remoteName) + err = gitrepo.ManagedRemoteRemove(ctx, repo, remoteName) if err != nil && !git.IsRemoteNotExistError(err) { return err } - err = gitrepo.GitRemoteAdd(ctx, repo, remoteName, addr, gitrepo.RemoteOptionMirrorFetch) + err = gitrepo.ManagedRemoteAdd(ctx, repo, remoteName, addr, gitrepo.RemoteOptionMirrorFetch) if err != nil && !git.IsRemoteNotExistError(err) { return err } @@ -53,12 +53,12 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error if repo_service.HasWiki(ctx, m.Repo) { wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr) // Remove old remote of wiki - err = gitrepo.GitRemoteRemove(ctx, repo.WikiStorageRepo(), remoteName) + err = gitrepo.ManagedRemoteRemove(ctx, repo.WikiStorageRepo(), remoteName) if err != nil && !git.IsRemoteNotExistError(err) { return err } - err = gitrepo.GitRemoteAdd(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, gitrepo.RemoteOptionMirrorFetch) + err = gitrepo.ManagedRemoteAdd(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, gitrepo.RemoteOptionMirrorFetch) if err != nil && !git.IsRemoteNotExistError(err) { return err } @@ -70,10 +70,10 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error return repo_model.UpdateRepositoryColsNoAutoTime(ctx, m.Repo, "original_url") } -func pruneBrokenReferences(ctx context.Context, m *repo_model.Mirror, repoLogName string, gitRepo gitrepo.Repository, timeout time.Duration) error { +func pruneBrokenReferences(ctx context.Context, m *repo_model.Mirror, repoLogName string, gitRepo git.RepositoryFacade, timeout time.Duration) error { // Never follow HTTP redirects, see cmdFetch in runSync. cmd := gitcmd.NewCommand("remote", "prune").AddConfig("http.followRedirects", "false").AddDynamicArguments(m.GetRemoteName()).WithTimeout(timeout) - stdout, _, pruneErr := gitrepo.RunCmdString(ctx, gitRepo, cmd) + stdout, _, pruneErr := cmd.WithRepo(gitRepo).RunStdString(ctx) if pruneErr != nil { // sanitize the output, since it may contain the remote address, which may contain a password stderrMessage := util.SanitizeCredentialURLs(pruneErr.Stderr()) @@ -139,7 +139,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*repo_module.SyncResu } var err error - fetchStdout, fetchStderr, err := gitrepo.RunCmdString(ctx, m.Repo, cmdFetch()) + fetchStdout, fetchStderr, err := cmdFetch().WithRepo(m.Repo).RunStdString(ctx) if err != nil { // sanitize the output, since it may contain the remote address, which may contain a password stderrMessage := util.SanitizeCredentialURLs(fetchStderr) @@ -150,10 +150,10 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*repo_module.SyncResu log.Warn("SyncMirrors [repo: %-v]: failed to update mirror repository due to broken references:\nStdout: %s\nStderr: %s\nErr: %v\nAttempting Prune", m.Repo, stdoutMessage, stderrMessage, err) err = nil // Attempt prune - pruneErr := pruneBrokenReferences(ctx, m, m.Repo.FullName(), m.Repo, timeout) + pruneErr := pruneBrokenReferences(ctx, m, m.Repo.FullName(), m.Repo.CodeStorageRepo(), timeout) if pruneErr == nil { // Successful prune - reattempt mirror - fetchStdout, fetchStderr, err = gitrepo.RunCmdString(ctx, m.Repo, cmdFetch()) + fetchStdout, fetchStderr, err = cmdFetch().WithRepo(m.Repo).RunStdString(ctx) if err != nil { // sanitize the output, since it may contain the remote address, which may contain a password stderrMessage = util.SanitizeCredentialURLs(fetchStderr) @@ -220,7 +220,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*repo_module.SyncResu if repo_service.HasWiki(ctx, m.Repo) { log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo) // the result of "git remote update" is in stderr - stdout, stderr, err := gitrepo.RunCmdString(ctx, m.Repo.WikiStorageRepo(), cmdRemoteUpdatePrune()) + stdout, stderr, err := cmdRemoteUpdatePrune().WithRepo(m.Repo.WikiStorageRepo()).RunStdString(ctx) if err != nil { // sanitize the output, since it may contain the remote address, which may contain a password stderrMessage := util.SanitizeCredentialURLs(stderr) @@ -235,7 +235,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*repo_module.SyncResu pruneErr := pruneBrokenReferences(ctx, m, m.Repo.FullName()+".wiki", m.Repo.WikiStorageRepo(), timeout) if pruneErr == nil { // Successful prune - reattempt mirror - stdout, stderr, err = gitrepo.RunCmdString(ctx, m.Repo.WikiStorageRepo(), cmdRemoteUpdatePrune()) + stdout, stderr, err = cmdRemoteUpdatePrune().WithRepo(m.Repo.WikiStorageRepo()).RunStdString(ctx) if err != nil { stderrMessage = util.SanitizeCredentialURLs(stderr) stdoutMessage = util.SanitizeCredentialURLs(stdout) diff --git a/services/mirror/mirror_push.go b/services/mirror/mirror_push.go index 6df5a5d701c..69c180cccef 100644 --- a/services/mirror/mirror_push.go +++ b/services/mirror/mirror_push.go @@ -31,17 +31,17 @@ var stripExitStatus = regexp.MustCompile(`exit status \d+ - `) // AddPushMirrorRemote registers the push mirror remote. func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr string) error { - addRemoteAndConfig := func(storageRepo gitrepo.Repository, addr string) error { - if err := gitrepo.GitRemoteAdd(ctx, storageRepo, m.RemoteName, addr, gitrepo.RemoteOptionMirrorPush); err != nil { + addRemoteAndConfig := func(storageRepo git.RepositoryFacade, addr string) error { + if err := gitrepo.ManagedRemoteAdd(ctx, storageRepo, m.RemoteName, addr, gitrepo.RemoteOptionMirrorPush); err != nil { return err } - if err := gitrepo.GitConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*"); err != nil { + if err := gitrepo.ManagedConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*"); err != nil { return err } - return gitrepo.GitConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*") + return gitrepo.ManagedConfigAdd(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*") } - if err := addRemoteAndConfig(m.Repo, addr); err != nil { + if err := addRemoteAndConfig(m.Repo.CodeStorageRepo(), addr); err != nil { return err } @@ -60,12 +60,12 @@ func AddPushMirrorRemote(ctx context.Context, m *repo_model.PushMirror, addr str // RemovePushMirrorRemote removes the push mirror remote. func RemovePushMirrorRemote(ctx context.Context, m *repo_model.PushMirror) error { _ = m.GetRepository(ctx) - if err := gitrepo.GitRemoteRemove(ctx, m.Repo, m.RemoteName); err != nil { + if err := gitrepo.ManagedRemoteRemove(ctx, m.Repo, m.RemoteName); err != nil { return err } if repo_service.HasWiki(ctx, m.Repo) { - if err := gitrepo.GitRemoteRemove(ctx, m.Repo.WikiStorageRepo(), m.RemoteName); err != nil { + if err := gitrepo.ManagedRemoteRemove(ctx, m.Repo.WikiStorageRepo(), m.RemoteName); err != nil { // The wiki remote may not exist log.Warn("Wiki Remote[%d] could not be removed: %v", m.ID, err) } @@ -124,7 +124,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error { timeout := time.Duration(setting.Git.Timeout.Mirror) * time.Second performPush := func(repo *repo_model.Repository, isWiki bool) error { - var storageRepo gitrepo.Repository = repo + storageRepo := repo.CodeStorageRepo() if isWiki { storageRepo = repo.WikiStorageRepo() } diff --git a/services/pull/check.go b/services/pull/check.go index 64b252b0668..5a2c25b03d0 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -316,7 +316,7 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com // Check if the pull request is merged into BaseBranch cmd := gitcmd.NewCommand("merge-base", "--is-ancestor").AddDynamicArguments(prHeadRef, pr.BaseBranch) - if err := gitrepo.RunCmdWithStderr(ctx, pr.BaseRepo, cmd); err != nil { + if err := cmd.WithRepo(pr.BaseRepo).RunWithStderr(ctx); err != nil { if gitcmd.IsErrorExitCode(err, 1) { // prHeadRef is not an ancestor of the base branch return nil, nil //nolint:nilnil // return nil to indicate that the PR head is not merged @@ -346,9 +346,8 @@ func getMergeCommit(ctx context.Context, pr *issues_model.PullRequest) (*git.Com // rev-list returns one line per merge commit on the ancestry path; we // only want the first one (the oldest, with --reverse, i.e. the merge // commit that actually introduced this PR). - mergeCommit, _, err := gitrepo.RunCmdString(ctx, pr.BaseRepo, - gitcmd.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse"). - AddDynamicArguments(prHeadCommitID+".."+pr.BaseBranch)) + mergeCommit, _, err := gitcmd.NewCommand("rev-list", "--ancestry-path", "--merges", "--reverse"). + AddDynamicArguments(prHeadCommitID + ".." + pr.BaseBranch).WithRepo(pr.BaseRepo).RunStdString(ctx) if err != nil { return nil, fmt.Errorf("git rev-list --ancestry-path --merges --reverse: %w", err) } diff --git a/services/pull/merge_tree.go b/services/pull/merge_tree.go index ded501a1236..e572b0da7d7 100644 --- a/services/pull/merge_tree.go +++ b/services/pull/merge_tree.go @@ -36,8 +36,8 @@ func checkConflictsMergeTree(ctx context.Context, pr *issues_model.PullRequest, // Detect whether the pull request introduces changes by comparing the merged tree (treeHash) // against the current base commit (baseCommitID) using `git diff-tree`. The command returns exit code 0 // if there is no diff between these trees (empty patch) and exit code 1 if there is a diff. - gitErr := gitrepo.RunCmd(ctx, pr.BaseRepo, gitcmd.NewCommand("diff-tree", "-r", "--quiet"). - AddDynamicArguments(treeHash, baseCommitID)) + gitErr := gitcmd.NewCommand("diff-tree", "-r", "--quiet"). + AddDynamicArguments(treeHash, baseCommitID).WithRepo(pr.BaseRepo).Run(ctx) switch { case gitErr == nil: log.Debug("PullRequest[%d]: Patch is empty - ignoring", pr.ID) diff --git a/services/pull/pull.go b/services/pull/pull.go index 8c08bba56ad..9a57b16c318 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -586,7 +586,7 @@ func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, pre gitRefName := pr.GetGitHeadRefName() - if err := gitrepo.Push(ctx, pr.HeadRepo, pr.BaseRepo, git.PushOptions{ + if err := gitrepo.PushManaged(ctx, pr.HeadRepo, pr.BaseRepo, git.PushOptions{ Branch: prefixHeadBranch + pr.HeadBranch + ":" + gitRefName, Force: true, // Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/... diff --git a/services/release/release.go b/services/release/release.go index 66e8957a1a0..5a80340417c 100644 --- a/services/release/release.go +++ b/services/release/release.go @@ -377,9 +377,8 @@ func DeleteReleaseByID(ctx context.Context, repo *repo_model.Repository, rel *re } } - if stdout, _, err := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("tag", "-d").AddDashesAndList(rel.TagName), - ); err != nil && !strings.Contains(err.Error(), "not found") { + stdout, _, err := gitcmd.NewCommand("tag", "-d").AddDashesAndList(rel.TagName).WithRepo(repo).RunStdString(ctx) + if err != nil && !strings.Contains(err.Error(), "not found") { log.Error("DeleteReleaseByID (git tag -d): %d in %v Failed:\nStdout: %s\nError: %v", rel.ID, repo, stdout, err) return fmt.Errorf("git tag -d: %w", err) } diff --git a/services/repository/branch.go b/services/repository/branch.go index 8d2391eb8dc..352beddfaa6 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -385,7 +385,7 @@ func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo return err } - if err := gitrepo.Push(ctx, repo, repo, git.PushOptions{ + if err := gitrepo.PushManaged(ctx, repo, repo, git.PushOptions{ Branch: fmt.Sprintf("%s:%s%s", commitID, git.BranchPrefix, branchName), Env: repo_module.PushingEnvironment(doer, repo), }); err != nil { @@ -545,7 +545,7 @@ func UpdateBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git } // branch protection will be checked in the pre received hook, so that we don't need any check here - return gitrepo.Push(ctx, repo, repo, pushOpts) + return gitrepo.PushManaged(ctx, repo, repo, pushOpts) } var ErrBranchIsDefault = util.ErrorWrap(util.ErrPermissionDenied, "branch is default or pull request target") diff --git a/services/repository/check.go b/services/repository/check.go index 8b921b0eb4b..efdad3446a8 100644 --- a/services/repository/check.go +++ b/services/repository/check.go @@ -88,7 +88,7 @@ func GitGcRepo(ctx context.Context, repo *repo_model.Repository, timeout time.Du command := gitcmd.NewCommand("gc").AddArguments(args...) var stdout string var err error - stdout, _, err = gitrepo.RunCmdString(ctx, repo, command) + stdout, _, err = command.WithRepo(repo).RunStdString(ctx) if err != nil { log.Error("Repository garbage collection failed for %-v. Stdout: %s\nError: %v", repo, stdout, err) desc := fmt.Sprintf("Repository garbage collection failed (%s). Stdout: %s\nError: %v", repo.FullName(), stdout, err) diff --git a/services/repository/create.go b/services/repository/create.go index 449ab4a5362..25ae041bca5 100644 --- a/services/repository/create.go +++ b/services/repository/create.go @@ -314,7 +314,7 @@ func CreateRepositoryDirectly(ctx context.Context, doer, owner *user_model.User, licenses = append(licenses, opts.License) var stdout string - stdout, _, err = gitrepo.RunCmdString(ctx, repo, gitcmd.NewCommand("rev-parse", "HEAD")) + stdout, _, err = gitcmd.NewCommand("rev-parse", "HEAD").WithRepo(repo).RunStdString(ctx) if err != nil { log.Error("CreateRepository(git rev-parse HEAD) in %v: Stdout: %s\nError: %v", repo, stdout, err) return nil, fmt.Errorf("CreateRepository(git rev-parse HEAD): %w", err) @@ -467,8 +467,8 @@ func updateGitRepoAfterCreate(ctx context.Context, repo *repo_model.Repository) return fmt.Errorf("checkDaemonExportOK: %w", err) } - if stdout, _, err := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("update-server-info")); err != nil { + stdout, _, err := gitcmd.NewCommand("update-server-info").WithRepo(repo).RunStdString(ctx) + if err != nil { log.Error("CreateRepository(git update-server-info) in %v: Stdout: %s\nError: %v", repo, stdout, err) return fmt.Errorf("CreateRepository(git update-server-info): %w", err) } diff --git a/services/repository/fork.go b/services/repository/fork.go index 16975485418..d038dd41056 100644 --- a/services/repository/fork.go +++ b/services/repository/fork.go @@ -154,7 +154,7 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork cloneOpts.SingleBranch = true cloneOpts.Branch = opts.SingleBranch } - if err = gitrepo.Clone(ctx, opts.BaseRepo, repo, cloneOpts); err != nil { + if err = gitrepo.CloneManaged(ctx, opts.BaseRepo, repo, cloneOpts); err != nil { log.Error("Fork Repository (git clone) Failed for %v (from %v):\nError: %v", repo, opts.BaseRepo, err) return nil, fmt.Errorf("git clone: %w", err) } diff --git a/services/repository/merge_upstream.go b/services/repository/merge_upstream.go index ad45839ba9c..cabd2ca3078 100644 --- a/services/repository/merge_upstream.go +++ b/services/repository/merge_upstream.go @@ -47,7 +47,7 @@ func MergeUpstream(ctx reqctx.RequestContext, doer *user_model.User, repo *repo_ return "up-to-date", nil } - err = gitrepo.Push(ctx, repo.BaseRepo, repo, git.PushOptions{ + err = gitrepo.PushManaged(ctx, repo.BaseRepo, repo, git.PushOptions{ Branch: fmt.Sprintf("%s:%s", divergingInfo.BaseBranchName, branch), Env: repo_module.PushingEnvironment(doer, repo), }) diff --git a/services/repository/migrate.go b/services/repository/migrate.go index 2aca0666d5e..d029ce148da 100644 --- a/services/repository/migrate.go +++ b/services/repository/migrate.go @@ -227,9 +227,10 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, // this is necessary for sync local tags from remote configName := fmt.Sprintf("remote.%s.fetch", mirrorModel.GetRemoteName()) - if stdout, _, err := gitrepo.RunCmdString(ctx, repo, - gitcmd.NewCommand("config"). - AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`)); err != nil { + stdout, _, err := gitcmd.NewCommand("config"). + AddOptionValues("--add", configName, `+refs/tags/*:refs/tags/*`). + WithRepo(repo).RunStdString(ctx) + if err != nil { log.Error("MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*) in %v: Stdout: %s\nError: %v", repo, stdout, err) return repo, fmt.Errorf("error in MigrateRepositoryGitData(git config --add +refs/tags/*:refs/tags/*): %w", err) } @@ -272,13 +273,13 @@ func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo } } - err := gitrepo.GitRemoteRemove(ctx, repo, "origin") + err := gitrepo.ManagedRemoteRemove(ctx, repo, "origin") if err != nil && !git.IsRemoteNotExistError(err) { return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err) } if hasWiki { - err = gitrepo.GitRemoteRemove(ctx, repo.WikiStorageRepo(), "origin") + err = gitrepo.ManagedRemoteRemove(ctx, repo.WikiStorageRepo(), "origin") if err != nil && !git.IsRemoteNotExistError(err) { return repo, fmt.Errorf("cleanUpMigrateGitConfig (wiki): %w", err) } diff --git a/tests/integration/api_repo_git_tags_test.go b/tests/integration/api_repo_git_tags_test.go index 279d974b1e8..db983762498 100644 --- a/tests/integration/api_repo_git_tags_test.go +++ b/tests/integration/api_repo_git_tags_test.go @@ -28,8 +28,8 @@ func TestAPIGitTags(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadRepository) // Set up git config for the tagger - _ = gitrepo.GitConfigSet(t.Context(), repo, "user.name", user.Name) - _ = gitrepo.GitConfigSet(t.Context(), repo, "user.email", user.Email) + _ = gitrepo.ManagedConfigSet(t.Context(), repo, "user.name", user.Name) + _ = gitrepo.ManagedConfigSet(t.Context(), repo, "user.email", user.Email) gitRepo, _ := gitrepo.OpenRepository(repo) defer gitRepo.Close()