diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/convert/pull.go | 20 | ||||
-rw-r--r-- | modules/git/git.go | 61 | ||||
-rw-r--r-- | modules/git/repo_branch.go | 8 | ||||
-rw-r--r-- | modules/private/hook.go | 46 | ||||
-rw-r--r-- | modules/repository/hooks.go | 9 |
5 files changed, 143 insertions, 1 deletions
diff --git a/modules/convert/pull.go b/modules/convert/pull.go index 8bdf17a049..6c5d15c82e 100644 --- a/modules/convert/pull.go +++ b/modules/convert/pull.go @@ -95,7 +95,25 @@ func ToAPIPullRequest(pr *models.PullRequest) *api.PullRequest { } } - if pr.HeadRepo != nil { + if pr.Flow == models.PullRequestFlowAGit { + gitRepo, err := git.OpenRepository(pr.BaseRepo.RepoPath()) + if err != nil { + log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err) + return nil + } + defer gitRepo.Close() + + apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) + if err != nil { + log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) + return nil + } + apiPullRequest.Head.RepoID = pr.BaseRepoID + apiPullRequest.Head.Repository = apiPullRequest.Base.Repository + apiPullRequest.Head.Name = "" + } + + if pr.HeadRepo != nil && pr.Flow == models.PullRequestFlowGithub { apiPullRequest.Head.RepoID = pr.HeadRepo.ID apiPullRequest.Head.Repository = ToRepo(pr.HeadRepo, models.AccessModeNone) diff --git a/modules/git/git.go b/modules/git/git.go index ef6ec0c2bf..7ab11736e8 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -37,6 +37,9 @@ var ( // will be checked on Init goVersionLessThan115 = true + + // SupportProcReceive version >= 2.29.0 + SupportProcReceive bool ) // LocalVersion returns current Git version from shell. @@ -183,6 +186,19 @@ func Init(ctx context.Context) error { } } + if CheckGitVersionAtLeast("2.29") == nil { + // set support for AGit flow + if err := checkAndAddConfig("receive.procReceiveRefs", "refs/for"); err != nil { + return err + } + SupportProcReceive = true + } else { + if err := checkAndRemoveConfig("receive.procReceiveRefs", "refs/for"); err != nil { + return err + } + SupportProcReceive = false + } + if runtime.GOOS == "windows" { if err := checkAndSetConfig("core.longpaths", "true", true); err != nil { return err @@ -232,6 +248,51 @@ func checkAndSetConfig(key, defaultValue string, forceToDefault bool) error { return nil } +func checkAndAddConfig(key, value string) error { + _, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key, value) + if err != nil { + perr, ok := err.(*process.Error) + if !ok { + return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) + } + eerr, ok := perr.Err.(*exec.ExitError) + if !ok || eerr.ExitCode() != 1 { + return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) + } + if eerr.ExitCode() == 1 { + if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", "--add", key, value); err != nil { + return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr) + } + return nil + } + } + + return nil +} + +func checkAndRemoveConfig(key, value string) error { + _, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key, value) + if err != nil { + perr, ok := err.(*process.Error) + if !ok { + return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) + } + eerr, ok := perr.Err.(*exec.ExitError) + if !ok || eerr.ExitCode() != 1 { + return fmt.Errorf("Failed to get git %s(%v) errType %T: %s", key, err, err, stderr) + } + if eerr.ExitCode() == 1 { + return nil + } + } + + if _, stderr, err = process.GetManager().Exec(fmt.Sprintf("git.Init(set %s)", key), "git", "config", "--global", "--unset-all", key, value); err != nil { + return fmt.Errorf("Failed to set git %s(%s): %s", key, err, stderr) + } + + return nil +} + // Fsck verifies the connectivity and validity of the objects in the database func Fsck(ctx context.Context, repoPath string, timeout time.Duration, args ...string) error { // Make sure timeout makes sense. diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 58781eb1c7..7c30b1fb20 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -13,6 +13,14 @@ import ( // BranchPrefix base dir of the branch information file store on git const BranchPrefix = "refs/heads/" +// AGit Flow + +// PullRequestPrefix sepcial ref to create a pull request: refs/for/<targe-branch>/<topic-branch> +// or refs/for/<targe-branch> -o topic='<topic-branch>' +const PullRequestPrefix = "refs/for/" + +// TODO: /refs/for-review for suggest change interface + // IsReferenceExist returns true if given reference exists in the repository. func IsReferenceExist(repoPath, name string) bool { _, err := NewCommand("show-ref", "--verify", "--", name).RunInDir(repoPath) diff --git a/modules/private/hook.go b/modules/private/hook.go index 9596f5f4da..4d0b5d22bf 100644 --- a/modules/private/hook.go +++ b/modules/private/hook.go @@ -6,6 +6,7 @@ package private import ( "context" + "errors" "fmt" "net/http" "net/url" @@ -56,6 +57,7 @@ type HookOptions struct { GitPushOptions GitPushOptions PullRequestID int64 IsDeployKey bool + IsWiki bool } // SSHLogOption ssh log options @@ -79,6 +81,23 @@ type HookPostReceiveBranchResult struct { URL string } +// HockProcReceiveResult represents an individual result from ProcReceive +type HockProcReceiveResult struct { + Results []HockProcReceiveRefResult + Err string +} + +// HockProcReceiveRefResult represents an individual result from ProcReceive +type HockProcReceiveRefResult struct { + OldOID string + NewOID string + Ref string + OriginalRef string + IsForcePush bool + IsNotMatched bool + Err string +} + // HookPreReceive check whether the provided commits are allowed func HookPreReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (int, string) { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/pre-receive/%s/%s", @@ -130,6 +149,33 @@ func HookPostReceive(ctx context.Context, ownerName, repoName string, opts HookO return res, "" } +// HookProcReceive proc-receive hook +func HookProcReceive(ctx context.Context, ownerName, repoName string, opts HookOptions) (*HockProcReceiveResult, error) { + reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/proc-receive/%s/%s", + url.PathEscape(ownerName), + url.PathEscape(repoName), + ) + + req := newInternalRequest(ctx, reqURL, "POST") + req = req.Header("Content-Type", "application/json") + req.SetTimeout(60*time.Second, time.Duration(60+len(opts.OldCommitIDs))*time.Second) + jsonBytes, _ := json.Marshal(opts) + req.Body(jsonBytes) + resp, err := req.Response() + if err != nil { + return nil, fmt.Errorf("Unable to contact gitea: %v", err.Error()) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return nil, errors.New(decodeJSONError(resp).Err) + } + res := &HockProcReceiveResult{} + _ = json.NewDecoder(resp.Body).Decode(res) + + return res, nil +} + // SetDefaultBranch will set the default branch to the provided branch for the provided repository func SetDefaultBranch(ctx context.Context, ownerName, repoName, branch string) error { reqURL := setting.LocalURL + fmt.Sprintf("api/internal/hook/set-default-branch/%s/%s/%s", diff --git a/modules/repository/hooks.go b/modules/repository/hooks.go index ed6036851e..8b4e7d6302 100644 --- a/modules/repository/hooks.go +++ b/modules/repository/hooks.go @@ -12,6 +12,7 @@ import ( "path/filepath" "code.gitea.io/gitea/models" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" @@ -75,6 +76,14 @@ done fmt.Sprintf("#!/usr/bin/env %s\n%s hook --config=%s update $1 $2 $3\n", setting.ScriptType, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf)), fmt.Sprintf("#!/usr/bin/env %s\n%s hook --config=%s post-receive\n", setting.ScriptType, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf)), } + + if git.SupportProcReceive { + hookNames = append(hookNames, "proc-receive") + hookTpls = append(hookTpls, + fmt.Sprintf("#!/usr/bin/env %s\n%s hook --config=%s proc-receive\n", setting.ScriptType, util.ShellEscape(setting.AppPath), util.ShellEscape(setting.CustomConf))) + giteaHookTpls = append(giteaHookTpls, "") + } + return } |