mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-29 15:28:38 +00:00
Move git config/remote to gitrepo package and add global lock to resolve possible conflict when updating repository git config file
This commit is contained in:
parent
c10c4203ee
commit
a38ff9ae00
@ -9,7 +9,6 @@ import (
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
giturl "code.gitea.io/gitea/modules/git/url"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
)
|
||||
|
||||
@ -33,15 +32,6 @@ func GetRemoteAddress(ctx context.Context, repoPath, remoteName string) (string,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// GetRemoteURL returns the url of a specific remote of the repository.
|
||||
func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (*giturl.GitURL, error) {
|
||||
addr, err := GetRemoteAddress(ctx, repoPath, remoteName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return giturl.ParseGitURL(addr)
|
||||
}
|
||||
|
||||
// ErrInvalidCloneAddr represents a "InvalidCloneAddr" kind of error.
|
||||
type ErrInvalidCloneAddr struct {
|
||||
Host string
|
||||
|
@ -31,13 +31,17 @@ type GPGSettings struct {
|
||||
Format string
|
||||
}
|
||||
|
||||
const prettyLogFormat = `--pretty=format:%H`
|
||||
const PrettyLogFormat = `--pretty=format:%H`
|
||||
|
||||
// GetAllCommitsCount returns count of all commits in repository
|
||||
func (repo *Repository) GetAllCommitsCount() (int64, error) {
|
||||
return AllCommitsCount(repo.Ctx, repo.Path, false)
|
||||
}
|
||||
|
||||
func (repo *Repository) ParsePrettyFormatLogToList(logs []byte) ([]*Commit, error) {
|
||||
return repo.parsePrettyFormatLogToList(logs)
|
||||
}
|
||||
|
||||
func (repo *Repository) parsePrettyFormatLogToList(logs []byte) ([]*Commit, error) {
|
||||
var commits []*Commit
|
||||
if len(logs) == 0 {
|
||||
|
@ -79,12 +79,6 @@ func (repo *Repository) AddRemote(name, url string, fetch bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveRemote removes a remote from repository.
|
||||
func (repo *Repository) RemoveRemote(name string) error {
|
||||
_, _, err := NewCommand("remote", "rm").AddDynamicArguments(name).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
return err
|
||||
}
|
||||
|
||||
// RenameBranch rename a branch
|
||||
func (repo *Repository) RenameBranch(from, to string) error {
|
||||
_, _, err := NewCommand("branch", "-m").AddDynamicArguments(from, to).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
|
@ -59,7 +59,7 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com
|
||||
relpath = `\` + relpath
|
||||
}
|
||||
|
||||
stdout, _, runErr := NewCommand("log", "-1", prettyLogFormat).AddDynamicArguments(id.String()).AddDashesAndList(relpath).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
stdout, _, runErr := NewCommand("log", "-1", PrettyLogFormat).AddDynamicArguments(id.String()).AddDashesAndList(relpath).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
if runErr != nil {
|
||||
return nil, runErr
|
||||
}
|
||||
@ -74,7 +74,7 @@ func (repo *Repository) getCommitByPathWithID(id ObjectID, relpath string) (*Com
|
||||
|
||||
// GetCommitByPath returns the last commit of relative path.
|
||||
func (repo *Repository) GetCommitByPath(relpath string) (*Commit, error) {
|
||||
stdout, _, runErr := NewCommand("log", "-1", prettyLogFormat).AddDashesAndList(relpath).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
stdout, _, runErr := NewCommand("log", "-1", PrettyLogFormat).AddDashesAndList(relpath).RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
if runErr != nil {
|
||||
return nil, runErr
|
||||
}
|
||||
@ -94,7 +94,7 @@ func (repo *Repository) commitsByRangeWithTime(id ObjectID, page, pageSize int,
|
||||
cmd := NewCommand("log").
|
||||
AddOptionFormat("--skip=%d", (page-1)*pageSize).
|
||||
AddOptionFormat("--max-count=%d", pageSize).
|
||||
AddArguments(prettyLogFormat).
|
||||
AddArguments(PrettyLogFormat).
|
||||
AddDynamicArguments(id.String())
|
||||
|
||||
if not != "" {
|
||||
@ -141,7 +141,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([
|
||||
}
|
||||
|
||||
// create new git log command with limit of 100 commits
|
||||
cmd := NewCommand("log", "-100", prettyLogFormat).AddDynamicArguments(id.String())
|
||||
cmd := NewCommand("log", "-100", PrettyLogFormat).AddDynamicArguments(id.String())
|
||||
|
||||
// pretend that all refs along with HEAD were listed on command line as <commis>
|
||||
// https://git-scm.com/docs/git-log#Documentation/git-log.txt---all
|
||||
@ -175,7 +175,7 @@ func (repo *Repository) searchCommits(id ObjectID, opts SearchCommitsOptions) ([
|
||||
// ignore anything not matching a valid sha pattern
|
||||
if id.Type().IsValid(v) {
|
||||
// create new git log command with 1 commit limit
|
||||
hashCmd := NewCommand("log", "-1", prettyLogFormat)
|
||||
hashCmd := NewCommand("log", "-1", PrettyLogFormat)
|
||||
// add previous arguments except for --grep and --all
|
||||
addCommonSearchArgs(hashCmd)
|
||||
// add keyword as <commit>
|
||||
@ -410,7 +410,7 @@ func (repo *Repository) CommitsCountBetween(start, end string) (int64, error) {
|
||||
|
||||
// commitsBefore the limit is depth, not total number of returned commits.
|
||||
func (repo *Repository) commitsBefore(id ObjectID, limit int) ([]*Commit, error) {
|
||||
cmd := NewCommand("log", prettyLogFormat)
|
||||
cmd := NewCommand("log", PrettyLogFormat)
|
||||
if limit > 0 {
|
||||
cmd.AddOptionFormat("-%d", limit)
|
||||
}
|
||||
@ -536,7 +536,7 @@ func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error
|
||||
|
||||
// GetCommitBranchStart returns the commit where the branch diverged
|
||||
func (repo *Repository) GetCommitBranchStart(env []string, branch, endCommitID string) (string, error) {
|
||||
cmd := NewCommand("log", prettyLogFormat)
|
||||
cmd := NewCommand("log", PrettyLogFormat)
|
||||
cmd.AddDynamicArguments(endCommitID)
|
||||
|
||||
stdout, _, runErr := cmd.RunStdBytes(repo.Ctx, &RunOpts{
|
||||
|
@ -16,20 +16,8 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
logger "code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// CompareInfo represents needed information for comparing references.
|
||||
type CompareInfo struct {
|
||||
MergeBase string
|
||||
BaseCommitID string
|
||||
HeadCommitID string
|
||||
Commits []*Commit
|
||||
NumFiles int
|
||||
}
|
||||
|
||||
// GetMergeBase checks and returns merge base of two branches and the reference used as base.
|
||||
func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, string, error) {
|
||||
if tmpRemote == "" {
|
||||
@ -49,83 +37,6 @@ func (repo *Repository) GetMergeBase(tmpRemote, base, head string) (string, stri
|
||||
return strings.TrimSpace(stdout), base, err
|
||||
}
|
||||
|
||||
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
|
||||
func (repo *Repository) GetCompareInfo(basePath, baseBranch, headBranch string, directComparison, fileOnly bool) (_ *CompareInfo, err error) {
|
||||
var (
|
||||
remoteBranch string
|
||||
tmpRemote string
|
||||
)
|
||||
|
||||
// We don't need a temporary remote for same repository.
|
||||
if repo.Path != basePath {
|
||||
// Add a temporary remote
|
||||
tmpRemote = strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||
if err = repo.AddRemote(tmpRemote, basePath, false); err != nil {
|
||||
return nil, fmt.Errorf("AddRemote: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := repo.RemoveRemote(tmpRemote); err != nil {
|
||||
logger.Error("GetPullRequestInfo: RemoveRemote: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
compareInfo := new(CompareInfo)
|
||||
|
||||
compareInfo.HeadCommitID, err = GetFullCommitID(repo.Ctx, repo.Path, headBranch)
|
||||
if err != nil {
|
||||
compareInfo.HeadCommitID = headBranch
|
||||
}
|
||||
|
||||
compareInfo.MergeBase, remoteBranch, err = repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||
if err == nil {
|
||||
compareInfo.BaseCommitID, err = GetFullCommitID(repo.Ctx, repo.Path, remoteBranch)
|
||||
if err != nil {
|
||||
compareInfo.BaseCommitID = remoteBranch
|
||||
}
|
||||
separator := "..."
|
||||
baseCommitID := compareInfo.MergeBase
|
||||
if directComparison {
|
||||
separator = ".."
|
||||
baseCommitID = compareInfo.BaseCommitID
|
||||
}
|
||||
|
||||
// We have a common base - therefore we know that ... should work
|
||||
if !fileOnly {
|
||||
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
||||
var logs []byte
|
||||
logs, _, err = NewCommand("log").AddArguments(prettyLogFormat).
|
||||
AddDynamicArguments(baseCommitID+separator+headBranch).AddArguments("--").
|
||||
RunStdBytes(repo.Ctx, &RunOpts{Dir: repo.Path})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compareInfo.Commits, err = repo.parsePrettyFormatLogToList(logs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsePrettyFormatLogToList: %w", err)
|
||||
}
|
||||
} else {
|
||||
compareInfo.Commits = []*Commit{}
|
||||
}
|
||||
} else {
|
||||
compareInfo.Commits = []*Commit{}
|
||||
compareInfo.MergeBase, err = GetFullCommitID(repo.Ctx, repo.Path, remoteBranch)
|
||||
if err != nil {
|
||||
compareInfo.MergeBase = remoteBranch
|
||||
}
|
||||
compareInfo.BaseCommitID = compareInfo.MergeBase
|
||||
}
|
||||
|
||||
// Count number of changed files.
|
||||
// This probably should be removed as we need to use shortstat elsewhere
|
||||
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
||||
compareInfo.NumFiles, err = repo.GetDiffNumChangedFiles(remoteBranch, headBranch, directComparison)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return compareInfo, nil
|
||||
}
|
||||
|
||||
type lineCountWriter struct {
|
||||
numLines int
|
||||
}
|
||||
|
132
modules/gitrepo/config.go
Normal file
132
modules/gitrepo/config.go
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package gitrepo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
giturl "code.gitea.io/gitea/modules/git/url"
|
||||
"code.gitea.io/gitea/modules/globallock"
|
||||
)
|
||||
|
||||
func GetGitConfig(ctx context.Context, repo Repository, key string) (string, error) {
|
||||
result, _, err := git.NewCommand("config", "--get").
|
||||
AddDynamicArguments(key).
|
||||
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if len(result) > 0 {
|
||||
result = result[:len(result)-1] // remove trailing newline
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func getRepoConfigLockKey(repoStoragePath string) string {
|
||||
return "repo-config:" + repoStoragePath
|
||||
}
|
||||
|
||||
// AddGitConfig add a git configuration key to a specific value for the given repository.
|
||||
func AddGitConfig(ctx context.Context, repo Repository, key, value string) error {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
_, _, err = git.NewCommand("config", "--add").
|
||||
AddDynamicArguments(key, value).
|
||||
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateGitConfig 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 UpdateGitConfig(ctx context.Context, repo Repository, key, value string) (string, error) {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
value, _, err1 := git.NewCommand("config").
|
||||
AddDynamicArguments(key, value).
|
||||
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||
return value, err1
|
||||
}
|
||||
|
||||
func AddGitRemote(ctx context.Context, repo Repository, remoteName, remoteURL string, options ...string) error {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
cmd := git.NewCommand("remote", "add")
|
||||
if len(options) > 0 {
|
||||
cmd.AddDynamicArguments(options...)
|
||||
}
|
||||
_, _, err = cmd.
|
||||
AddDynamicArguments(remoteName, remoteURL).
|
||||
RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||
return err
|
||||
}
|
||||
|
||||
func RemoveGitRemote(ctx context.Context, repo Repository, remoteName string) error {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
cmd := git.NewCommand("remote", "rm").AddDynamicArguments(remoteName)
|
||||
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath(repo)})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetRemoteURL returns the url of a specific remote of the repository.
|
||||
func GetRemoteURL(ctx context.Context, repo Repository, remoteName string) (*giturl.GitURL, error) {
|
||||
addr, err := git.GetRemoteAddress(ctx, repoPath(repo), remoteName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return giturl.ParseGitURL(addr)
|
||||
}
|
||||
|
||||
// PruneRemote prunes the remote branches that no longer exist in the remote repository.
|
||||
func PruneRemote(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
return git.NewCommand("remote", "prune").AddDynamicArguments(remoteName).
|
||||
Run(ctx, &git.RunOpts{
|
||||
Timeout: timeout,
|
||||
Dir: repoPath(repo),
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
})
|
||||
}
|
||||
|
||||
func UpdateRemotePrune(ctx context.Context, repo Repository, remoteName string, timeout time.Duration, stdout, stderr io.Writer) error {
|
||||
releaser, err := globallock.Lock(ctx, getRepoConfigLockKey(repo.RelativePath()))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer releaser()
|
||||
|
||||
return git.NewCommand("remote", "update", "--prune").AddDynamicArguments(remoteName).
|
||||
Run(ctx, &git.RunOpts{
|
||||
Timeout: timeout,
|
||||
Dir: repoPath(repo),
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
})
|
||||
}
|
@ -1085,7 +1085,7 @@ func MergePullRequest(ctx *context.APIContext) {
|
||||
type parseCompareInfoResult struct {
|
||||
headRepo *repo_model.Repository
|
||||
headGitRepo *git.Repository
|
||||
compareInfo *git.CompareInfo
|
||||
compareInfo *pull_service.CompareInfo
|
||||
baseRef git.RefName
|
||||
headRef git.RefName
|
||||
}
|
||||
@ -1201,7 +1201,7 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
compareInfo, err := headGitRepo.GetCompareInfo(repo_model.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseRef.ShortName(), headRef.ShortName(), false, false)
|
||||
compareInfo, err := pull_service.GetCompareInfo(ctx, baseRepo, headGitRepo, baseRef.ShortName(), headRef.ShortName(), false, false)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
return nil, nil
|
||||
@ -1452,7 +1452,7 @@ func GetPullRequestCommits(ctx *context.APIContext) {
|
||||
return
|
||||
}
|
||||
|
||||
var prInfo *git.CompareInfo
|
||||
var prInfo *pull_service.CompareInfo
|
||||
baseGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pr.BaseRepo)
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
@ -1461,9 +1461,9 @@ func GetPullRequestCommits(ctx *context.APIContext) {
|
||||
defer closer.Close()
|
||||
|
||||
if pr.HasMerged {
|
||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitHeadRefName(), false, false)
|
||||
prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, baseGitRepo, pr.MergeBase, pr.GetGitHeadRefName(), false, false)
|
||||
} else {
|
||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitHeadRefName(), false, false)
|
||||
prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, baseGitRepo, pr.BaseBranch, pr.GetGitHeadRefName(), false, false)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
@ -1582,11 +1582,11 @@ func GetPullRequestFiles(ctx *context.APIContext) {
|
||||
|
||||
baseGitRepo := ctx.Repo.GitRepo
|
||||
|
||||
var prInfo *git.CompareInfo
|
||||
var prInfo *pull_service.CompareInfo
|
||||
if pr.HasMerged {
|
||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.MergeBase, pr.GetGitHeadRefName(), true, false)
|
||||
prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, baseGitRepo, pr.MergeBase, pr.GetGitHeadRefName(), true, false)
|
||||
} else {
|
||||
prInfo, err = baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(), pr.BaseBranch, pr.GetGitHeadRefName(), true, false)
|
||||
prInfo, err = pull_service.GetCompareInfo(ctx, pr.BaseRepo, baseGitRepo, pr.BaseBranch, pr.GetGitHeadRefName(), true, false)
|
||||
}
|
||||
if err != nil {
|
||||
ctx.APIErrorInternal(err)
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
)
|
||||
|
||||
// CompareInfo represents the collected results from ParseCompareInfo
|
||||
@ -14,7 +15,7 @@ type CompareInfo struct {
|
||||
HeadUser *user_model.User
|
||||
HeadRepo *repo_model.Repository
|
||||
HeadGitRepo *git.Repository
|
||||
CompareInfo *git.CompareInfo
|
||||
CompareInfo *pull_service.CompareInfo
|
||||
BaseBranch string
|
||||
HeadBranch string
|
||||
DirectComparison bool
|
||||
|
@ -41,6 +41,7 @@ import (
|
||||
"code.gitea.io/gitea/services/context"
|
||||
"code.gitea.io/gitea/services/context/upload"
|
||||
"code.gitea.io/gitea/services/gitdiff"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -550,7 +551,7 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
|
||||
headBranchRef = git.TagPrefix + ci.HeadBranch
|
||||
}
|
||||
|
||||
ci.CompareInfo, err = ci.HeadGitRepo.GetCompareInfo(baseRepo.RepoPath(), baseBranchRef, headBranchRef, ci.DirectComparison, fileOnly)
|
||||
ci.CompareInfo, err = pull_service.GetCompareInfo(ctx, baseRepo, ci.HeadGitRepo, baseBranchRef, headBranchRef, ci.DirectComparison, fileOnly)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetCompareInfo", err)
|
||||
return nil
|
||||
|
@ -254,7 +254,7 @@ func GetMergedBaseCommitID(ctx *context.Context, issue *issues_model.Issue) stri
|
||||
return baseCommit
|
||||
}
|
||||
|
||||
func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo {
|
||||
func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo {
|
||||
if !issue.IsPull {
|
||||
return nil
|
||||
}
|
||||
@ -265,7 +265,7 @@ func preparePullViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *g
|
||||
}
|
||||
|
||||
// prepareMergedViewPullInfo show meta information for a merged pull request view page
|
||||
func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo {
|
||||
func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo {
|
||||
pull := issue.PullRequest
|
||||
|
||||
setMergeTarget(ctx, pull)
|
||||
@ -273,7 +273,7 @@ func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
|
||||
|
||||
baseCommit := GetMergedBaseCommitID(ctx, issue)
|
||||
|
||||
compareInfo, err := ctx.Repo.GitRepo.GetCompareInfo(ctx.Repo.Repository.RepoPath(),
|
||||
compareInfo, err := pull_service.GetCompareInfo(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo,
|
||||
baseCommit, pull.GetGitHeadRefName(), false, false)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") || strings.Contains(err.Error(), "unknown revision or path not in the working tree") {
|
||||
@ -311,7 +311,7 @@ func prepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
|
||||
}
|
||||
|
||||
// prepareViewPullInfo show meta information for a pull request preview page
|
||||
func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.CompareInfo {
|
||||
func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *pull_service.CompareInfo {
|
||||
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
|
||||
|
||||
repo := ctx.Repo.Repository
|
||||
@ -373,7 +373,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
|
||||
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses)
|
||||
}
|
||||
|
||||
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
||||
compareInfo, err := pull_service.GetCompareInfo(ctx, pull.BaseRepo, baseGitRepo,
|
||||
pull.MergeBase, pull.GetGitHeadRefName(), false, false)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
||||
@ -521,7 +521,7 @@ func prepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
|
||||
}
|
||||
}
|
||||
|
||||
compareInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(),
|
||||
compareInfo, err := pull_service.GetCompareInfo(ctx, pull.BaseRepo, baseGitRepo,
|
||||
git.BranchPrefix+pull.BaseBranch, pull.GetGitHeadRefName(), false, false)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "fatal: Not a valid object name") {
|
||||
|
@ -16,6 +16,7 @@ import (
|
||||
unit_model "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/indexer/code"
|
||||
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
|
||||
"code.gitea.io/gitea/modules/indexer/stats"
|
||||
@ -258,7 +259,7 @@ func handleSettingsPostMirror(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
u, err := git.GetRemoteURL(ctx, ctx.Repo.Repository.RepoPath(), pullMirror.GetRemoteName())
|
||||
u, err := gitrepo.GetRemoteURL(ctx, ctx.Repo.Repository, pullMirror.GetRemoteName())
|
||||
if err != nil {
|
||||
ctx.Data["Err_MirrorAddress"] = true
|
||||
handleSettingRemoteAddrError(ctx, err, form)
|
||||
|
@ -91,18 +91,13 @@ func checkEnablePushOptions(ctx context.Context, logger log.Logger, autofix bool
|
||||
|
||||
if err := iterateRepositories(ctx, func(repo *repo_model.Repository) error {
|
||||
numRepos++
|
||||
r, err := gitrepo.OpenRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
if autofix {
|
||||
_, _, err := git.NewCommand("config", "receive.advertisePushOptions", "true").RunStdString(ctx, &git.RunOpts{Dir: r.Path})
|
||||
_, err := gitrepo.UpdateGitConfig(ctx, repo, "receive.advertisePushOptions", "true")
|
||||
return err
|
||||
}
|
||||
|
||||
value, _, err := git.NewCommand("config", "receive.advertisePushOptions").RunStdString(ctx, &git.RunOpts{Dir: r.Path})
|
||||
value, err := gitrepo.GetGitConfig(ctx, repo, "receive.advertisePushOptions")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
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"
|
||||
@ -18,19 +19,19 @@ import (
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func getMergeBase(repo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) {
|
||||
func getMergeBase(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) {
|
||||
// Add a temporary remote
|
||||
tmpRemote := fmt.Sprintf("mergebase-%d-%d", pr.ID, time.Now().UnixNano())
|
||||
if err := repo.AddRemote(tmpRemote, repo.Path, false); err != nil {
|
||||
return "", fmt.Errorf("AddRemote: %w", err)
|
||||
if err := gitrepo.AddGitRemote(ctx, repo, tmpRemote, gitRepo.Path); err != nil {
|
||||
return "", fmt.Errorf("AddGitRemote: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := repo.RemoveRemote(tmpRemote); err != nil {
|
||||
log.Error("getMergeBase: RemoveRemote: %v", err)
|
||||
if err := gitrepo.RemoveGitRemote(ctx, repo, tmpRemote); err != nil {
|
||||
log.Error("getMergeBase: RemoveGitRemote: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
mergeBase, _, err := repo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||
mergeBase, _, err := gitRepo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||
return mergeBase, err
|
||||
}
|
||||
|
||||
@ -97,7 +98,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
|
||||
}
|
||||
|
||||
// get the mergebase
|
||||
mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName())
|
||||
mergeBase, err := getMergeBase(ctx, pr.BaseRepo, repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -506,6 +506,7 @@ func (g *RepositoryDumper) handlePullRequest(ctx context.Context, pr *base.PullR
|
||||
// ... let's try something less nice
|
||||
remote = "head-pr-" + strconv.FormatInt(pr.Number, 10)
|
||||
}
|
||||
|
||||
// ... now add the remote
|
||||
err := g.gitRepo.AddRemote(remote, pr.Head.CloneURL, true)
|
||||
if err != nil {
|
||||
|
@ -39,30 +39,27 @@ func UpdateAddress(ctx context.Context, m *repo_model.Mirror, addr string) error
|
||||
}
|
||||
|
||||
remoteName := m.GetRemoteName()
|
||||
repoPath := m.GetRepository(ctx).RepoPath()
|
||||
repo := m.GetRepository(ctx)
|
||||
// Remove old remote
|
||||
_, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: repoPath})
|
||||
err = gitrepo.RemoveGitRemote(ctx, repo, remoteName)
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(addr)
|
||||
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: repoPath})
|
||||
err = gitrepo.AddGitRemote(ctx, repo, remoteName, addr, "--mirror=fetch")
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Repo.HasWiki() {
|
||||
wikiPath := m.Repo.WikiPath()
|
||||
wikiRemotePath := repo_module.WikiRemoteURL(ctx, addr)
|
||||
// Remove old remote of wiki
|
||||
_, _, err = git.NewCommand("remote", "rm").AddDynamicArguments(remoteName).RunStdString(ctx, &git.RunOpts{Dir: wikiPath})
|
||||
err = gitrepo.RemoveGitRemote(ctx, repo.WikiStorageRepo(), remoteName)
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd = git.NewCommand("remote", "add").AddDynamicArguments(remoteName).AddArguments("--mirror=fetch").AddDynamicArguments(wikiRemotePath)
|
||||
_, _, err = cmd.RunStdString(ctx, &git.RunOpts{Dir: wikiPath})
|
||||
err = gitrepo.AddGitRemote(ctx, repo.WikiStorageRepo(), remoteName, wikiRemotePath, "--mirror=fetch")
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
@ -197,25 +194,21 @@ func parseRemoteUpdateOutput(output, remoteName string) []*mirrorSyncResult {
|
||||
|
||||
func pruneBrokenReferences(ctx context.Context,
|
||||
m *repo_model.Mirror,
|
||||
repoPath string,
|
||||
timeout time.Duration,
|
||||
stdoutBuilder, stderrBuilder *strings.Builder,
|
||||
isWiki bool,
|
||||
) error {
|
||||
wiki := ""
|
||||
var storageRepo gitrepo.Repository = m.Repo
|
||||
if isWiki {
|
||||
wiki = "Wiki "
|
||||
storageRepo = m.Repo.WikiStorageRepo()
|
||||
}
|
||||
|
||||
stderrBuilder.Reset()
|
||||
stdoutBuilder.Reset()
|
||||
pruneErr := git.NewCommand("remote", "prune").AddDynamicArguments(m.GetRemoteName()).
|
||||
Run(ctx, &git.RunOpts{
|
||||
Timeout: timeout,
|
||||
Dir: repoPath,
|
||||
Stdout: stdoutBuilder,
|
||||
Stderr: stderrBuilder,
|
||||
})
|
||||
|
||||
pruneErr := gitrepo.PruneRemote(ctx, storageRepo, m.GetRemoteName(), timeout, stdoutBuilder, stderrBuilder)
|
||||
if pruneErr != nil {
|
||||
stdout := stdoutBuilder.String()
|
||||
stderr := stderrBuilder.String()
|
||||
@ -226,7 +219,7 @@ func pruneBrokenReferences(ctx context.Context,
|
||||
stdoutMessage := util.SanitizeCredentialURLs(stdout)
|
||||
|
||||
log.Error("Failed to prune mirror repository %s%-v references:\nStdout: %s\nStderr: %s\nErr: %v", wiki, m.Repo, stdoutMessage, stderrMessage, pruneErr)
|
||||
desc := fmt.Sprintf("Failed to prune mirror repository %s'%s' references: %s", wiki, repoPath, stderrMessage)
|
||||
desc := fmt.Sprintf("Failed to prune mirror repository %s'%s' references: %s", wiki, storageRepo.RelativePath(), stderrMessage)
|
||||
if err := system_model.CreateRepositoryNotice(desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
@ -268,7 +261,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
||||
}
|
||||
cmd.AddArguments("--tags").AddDynamicArguments(m.GetRemoteName())
|
||||
|
||||
remoteURL, remoteErr := git.GetRemoteURL(ctx, repoPath, m.GetRemoteName())
|
||||
remoteURL, remoteErr := gitrepo.GetRemoteURL(ctx, m.Repo, m.GetRemoteName())
|
||||
if remoteErr != nil {
|
||||
log.Error("SyncMirrors [repo: %-v]: GetRemoteAddress Error %v", m.Repo, remoteErr)
|
||||
return nil, false
|
||||
@ -298,7 +291,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
||||
err = nil
|
||||
|
||||
// Attempt prune
|
||||
pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, false)
|
||||
pruneErr := pruneBrokenReferences(ctx, m, timeout, &stdoutBuilder, &stderrBuilder, false)
|
||||
if pruneErr == nil {
|
||||
// Successful prune - reattempt mirror
|
||||
stderrBuilder.Reset()
|
||||
@ -371,13 +364,9 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
||||
log.Trace("SyncMirrors [repo: %-v Wiki]: running git remote update...", m.Repo)
|
||||
stderrBuilder.Reset()
|
||||
stdoutBuilder.Reset()
|
||||
if err := git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()).
|
||||
Run(ctx, &git.RunOpts{
|
||||
Timeout: timeout,
|
||||
Dir: wikiPath,
|
||||
Stdout: &stdoutBuilder,
|
||||
Stderr: &stderrBuilder,
|
||||
}); err != nil {
|
||||
|
||||
if err := gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
||||
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
||||
stdout := stdoutBuilder.String()
|
||||
stderr := stderrBuilder.String()
|
||||
|
||||
@ -391,19 +380,14 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo
|
||||
err = nil
|
||||
|
||||
// Attempt prune
|
||||
pruneErr := pruneBrokenReferences(ctx, m, repoPath, timeout, &stdoutBuilder, &stderrBuilder, true)
|
||||
pruneErr := pruneBrokenReferences(ctx, m, timeout, &stdoutBuilder, &stderrBuilder, true)
|
||||
if pruneErr == nil {
|
||||
// Successful prune - reattempt mirror
|
||||
stderrBuilder.Reset()
|
||||
stdoutBuilder.Reset()
|
||||
|
||||
if err = git.NewCommand("remote", "update", "--prune").AddDynamicArguments(m.GetRemoteName()).
|
||||
Run(ctx, &git.RunOpts{
|
||||
Timeout: timeout,
|
||||
Dir: wikiPath,
|
||||
Stdout: &stdoutBuilder,
|
||||
Stderr: &stderrBuilder,
|
||||
}); err != nil {
|
||||
if err = gitrepo.UpdateRemotePrune(ctx, m.Repo.WikiStorageRepo(), m.GetRemoteName(),
|
||||
timeout, &stdoutBuilder, &stderrBuilder); err != nil {
|
||||
stdout := stdoutBuilder.String()
|
||||
stderr := stderrBuilder.String()
|
||||
stderrMessage = util.SanitizeCredentialURLs(stderr)
|
||||
|
@ -29,28 +29,24 @@ 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(addr, path string) error {
|
||||
cmd := git.NewCommand("remote", "add", "--mirror=push").AddDynamicArguments(m.RemoteName, addr)
|
||||
if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil {
|
||||
addRemoteAndConfig := func(storageRepo gitrepo.Repository, addr string) error {
|
||||
if err := gitrepo.AddGitRemote(ctx, storageRepo, m.RemoteName, addr, "--mirror=push"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil {
|
||||
if err := gitrepo.AddGitConfig(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/heads/*:refs/heads/*"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, _, err := git.NewCommand("config", "--add").AddDynamicArguments("remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*").RunStdString(ctx, &git.RunOpts{Dir: path}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return gitrepo.AddGitConfig(ctx, storageRepo, "remote."+m.RemoteName+".push", "+refs/tags/*:refs/tags/*")
|
||||
}
|
||||
|
||||
if err := addRemoteAndConfig(addr, m.Repo.RepoPath()); err != nil {
|
||||
if err := addRemoteAndConfig(m.Repo, addr); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Repo.HasWiki() {
|
||||
wikiRemoteURL := repository.WikiRemoteURL(ctx, addr)
|
||||
if len(wikiRemoteURL) > 0 {
|
||||
if err := addRemoteAndConfig(wikiRemoteURL, m.Repo.WikiPath()); err != nil {
|
||||
if err := addRemoteAndConfig(m.Repo.WikiStorageRepo(), wikiRemoteURL); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -61,15 +57,13 @@ 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 {
|
||||
cmd := git.NewCommand("remote", "rm").AddDynamicArguments(m.RemoteName)
|
||||
_ = m.GetRepository(ctx)
|
||||
|
||||
if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.RepoPath()}); err != nil {
|
||||
if err := gitrepo.RemoveGitRemote(ctx, m.Repo, m.RemoteName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Repo.HasWiki() {
|
||||
if _, _, err := cmd.RunStdString(ctx, &git.RunOpts{Dir: m.Repo.WikiPath()}); err != nil {
|
||||
if err := gitrepo.RemoveGitRemote(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)
|
||||
}
|
||||
@ -128,11 +122,13 @@ 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
|
||||
path := repo.RepoPath()
|
||||
if isWiki {
|
||||
storageRepo = repo.WikiStorageRepo()
|
||||
path = repo.WikiPath()
|
||||
}
|
||||
remoteURL, err := git.GetRemoteURL(ctx, path, m.RemoteName)
|
||||
remoteURL, err := gitrepo.GetRemoteURL(ctx, storageRepo, m.RemoteName)
|
||||
if err != nil {
|
||||
log.Error("GetRemoteAddress(%s) Error %v", path, err)
|
||||
return errors.New("Unexpected error")
|
||||
@ -141,12 +137,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
|
||||
if setting.LFS.StartServer {
|
||||
log.Trace("SyncMirrors [repo: %-v]: syncing LFS objects...", m.Repo)
|
||||
|
||||
var gitRepo *git.Repository
|
||||
if isWiki {
|
||||
gitRepo, err = gitrepo.OpenRepository(ctx, repo.WikiStorageRepo())
|
||||
} else {
|
||||
gitRepo, err = gitrepo.OpenRepository(ctx, repo)
|
||||
}
|
||||
gitRepo, err := gitrepo.OpenRepository(ctx, storageRepo)
|
||||
if err != nil {
|
||||
log.Error("OpenRepository: %v", err)
|
||||
return errors.New("Unexpected error")
|
||||
|
102
services/pull/compare.go
Normal file
102
services/pull/compare.go
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package pull
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/gitrepo"
|
||||
logger "code.gitea.io/gitea/modules/log"
|
||||
)
|
||||
|
||||
// CompareInfo represents needed information for comparing references.
|
||||
type CompareInfo struct {
|
||||
MergeBase string
|
||||
BaseCommitID string
|
||||
HeadCommitID string
|
||||
Commits []*git.Commit
|
||||
NumFiles int
|
||||
}
|
||||
|
||||
// GetCompareInfo generates and returns compare information between base and head branches of repositories.
|
||||
func GetCompareInfo(ctx context.Context, baseRepo *repo_model.Repository, headGitRepo *git.Repository, baseBranch, headBranch string, directComparison, fileOnly bool) (_ *CompareInfo, err error) {
|
||||
var (
|
||||
remoteBranch string
|
||||
tmpRemote string
|
||||
)
|
||||
|
||||
// We don't need a temporary remote for same repository.
|
||||
if baseRepo.RepoPath() != headGitRepo.Path {
|
||||
// Add a temporary remote
|
||||
tmpRemote = strconv.FormatInt(time.Now().UnixNano(), 10)
|
||||
if err = gitrepo.AddGitRemote(ctx, baseRepo, tmpRemote, headGitRepo.Path); err != nil {
|
||||
return nil, fmt.Errorf("AddRemote: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := gitrepo.RemoveGitRemote(ctx, baseRepo, tmpRemote); err != nil {
|
||||
logger.Error("GetPullRequestInfo: RemoveGitRemote: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
compareInfo := new(CompareInfo)
|
||||
|
||||
compareInfo.HeadCommitID, err = git.GetFullCommitID(ctx, headGitRepo.Path, headBranch)
|
||||
if err != nil {
|
||||
compareInfo.HeadCommitID = headBranch
|
||||
}
|
||||
|
||||
compareInfo.MergeBase, remoteBranch, err = headGitRepo.GetMergeBase(tmpRemote, baseBranch, headBranch)
|
||||
if err == nil {
|
||||
compareInfo.BaseCommitID, err = git.GetFullCommitID(ctx, headGitRepo.Path, remoteBranch)
|
||||
if err != nil {
|
||||
compareInfo.BaseCommitID = remoteBranch
|
||||
}
|
||||
separator := "..."
|
||||
baseCommitID := compareInfo.MergeBase
|
||||
if directComparison {
|
||||
separator = ".."
|
||||
baseCommitID = compareInfo.BaseCommitID
|
||||
}
|
||||
|
||||
// We have a common base - therefore we know that ... should work
|
||||
if !fileOnly {
|
||||
// avoid: ambiguous argument 'refs/a...refs/b': unknown revision or path not in the working tree. Use '--': 'git <command> [<revision>...] -- [<file>...]'
|
||||
var logs []byte
|
||||
logs, _, err = git.NewCommand("log").AddArguments(git.PrettyLogFormat).
|
||||
AddDynamicArguments(baseCommitID+separator+headBranch).AddArguments("--").
|
||||
RunStdBytes(ctx, &git.RunOpts{Dir: headGitRepo.Path})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compareInfo.Commits, err = headGitRepo.ParsePrettyFormatLogToList(logs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsePrettyFormatLogToList: %w", err)
|
||||
}
|
||||
} else {
|
||||
compareInfo.Commits = []*git.Commit{}
|
||||
}
|
||||
} else {
|
||||
compareInfo.Commits = []*git.Commit{}
|
||||
compareInfo.MergeBase, err = git.GetFullCommitID(ctx, headGitRepo.Path, remoteBranch)
|
||||
if err != nil {
|
||||
compareInfo.MergeBase = remoteBranch
|
||||
}
|
||||
compareInfo.BaseCommitID = compareInfo.MergeBase
|
||||
}
|
||||
|
||||
// Count number of changed files.
|
||||
// This probably should be removed as we need to use shortstat elsewhere
|
||||
// Now there is git diff --shortstat but this appears to be slower than simply iterating with --nameonly
|
||||
compareInfo.NumFiles, err = headGitRepo.GetDiffNumChangedFiles(remoteBranch, headBranch, directComparison)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return compareInfo, nil
|
||||
}
|
@ -142,7 +142,7 @@ func NewPullRequest(ctx context.Context, opts *NewPullRequestOptions) error {
|
||||
return err
|
||||
}
|
||||
|
||||
compareInfo, err := baseGitRepo.GetCompareInfo(pr.BaseRepo.RepoPath(),
|
||||
compareInfo, err := GetCompareInfo(ctx, pr.BaseRepo, baseGitRepo,
|
||||
git.BranchPrefix+pr.BaseBranch, pr.GetGitHeadRefName(), false, false)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -1077,7 +1077,7 @@ func GetPullCommits(ctx *gitea_context.Context, issue *issues_model.Issue) ([]Co
|
||||
if pull.HasMerged {
|
||||
baseBranch = pull.MergeBase
|
||||
}
|
||||
prInfo, err := baseGitRepo.GetCompareInfo(pull.BaseRepo.RepoPath(), baseBranch, pull.GetGitHeadRefName(), true, false)
|
||||
prInfo, err := GetCompareInfo(ctx, pull.BaseRepo, baseGitRepo, baseBranch, pull.GetGitHeadRefName(), true, false)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
@ -261,20 +261,6 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
||||
return repo, committer.Commit()
|
||||
}
|
||||
|
||||
// cleanUpMigrateGitConfig removes mirror info which prevents "push --all".
|
||||
// This also removes possible user credentials.
|
||||
func cleanUpMigrateGitConfig(ctx context.Context, repoPath string) error {
|
||||
cmd := git.NewCommand("remote", "rm", "origin")
|
||||
// if the origin does not exist
|
||||
_, _, err := cmd.RunStdString(ctx, &git.RunOpts{
|
||||
Dir: repoPath,
|
||||
})
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors.
|
||||
func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) {
|
||||
if err := gitrepo.CreateDelegateHooks(ctx, repo); err != nil {
|
||||
@ -286,13 +272,14 @@ func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo
|
||||
}
|
||||
}
|
||||
|
||||
_, _, err := git.NewCommand("remote", "rm", "origin").RunStdString(ctx, &git.RunOpts{Dir: repo.RepoPath()})
|
||||
err := gitrepo.RemoveGitRemote(ctx, repo, "origin")
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return repo, fmt.Errorf("CleanUpMigrateInfo: %w", err)
|
||||
}
|
||||
|
||||
if repo.HasWiki() {
|
||||
if err := cleanUpMigrateGitConfig(ctx, repo.WikiPath()); err != nil {
|
||||
err = gitrepo.RemoveGitRemote(ctx, repo.WikiStorageRepo(), "origin")
|
||||
if err != nil && !git.IsRemoteNotExistError(err) {
|
||||
return repo, fmt.Errorf("cleanUpMigrateGitConfig (wiki): %w", err)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user