aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/convert/pull.go20
-rw-r--r--modules/git/git.go61
-rw-r--r--modules/git/repo_branch.go8
-rw-r--r--modules/private/hook.go46
-rw-r--r--modules/repository/hooks.go9
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
}