aboutsummaryrefslogtreecommitdiff
path: root/internal/gitutil/pull_request.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/gitutil/pull_request.go')
-rw-r--r--internal/gitutil/pull_request.go69
1 files changed, 69 insertions, 0 deletions
diff --git a/internal/gitutil/pull_request.go b/internal/gitutil/pull_request.go
new file mode 100644
index 00000000..818dc230
--- /dev/null
+++ b/internal/gitutil/pull_request.go
@@ -0,0 +1,69 @@
+// Copyright 2020 The Gogs Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package gitutil
+
+import (
+ "fmt"
+ "strconv"
+ "time"
+
+ "github.com/gogs/git-module"
+ "github.com/pkg/errors"
+ log "unknwon.dev/clog/v2"
+)
+
+// PullRequestMeta contains metadata for a pull request.
+type PullRequestMeta struct {
+ // The merge base of the pull request.
+ MergeBase string
+ // The commits that are requested to be merged.
+ Commits []*git.Commit
+ // The number of files changed.
+ NumFiles int
+}
+
+func (moduler) PullRequestMeta(headPath, basePath, headBranch, baseBranch string) (*PullRequestMeta, error) {
+ tmpRemoteBranch := baseBranch
+
+ // We need to create a temporary remote when the pull request is sent from a forked repository.
+ if headPath != basePath {
+ tmpRemote := strconv.FormatInt(time.Now().UnixNano(), 10)
+ err := Module.RepoAddRemote(headPath, tmpRemote, basePath, git.AddRemoteOptions{Fetch: true})
+ if err != nil {
+ return nil, fmt.Errorf("add remote: %v", err)
+ }
+ defer func() {
+ err := Module.RepoRemoveRemote(headPath, tmpRemote)
+ if err != nil {
+ log.Error("Failed to remove remote %q [path: %s]: %v", tmpRemote, headPath, err)
+ return
+ }
+ }()
+
+ tmpRemoteBranch = "remotes/" + tmpRemote + "/" + baseBranch
+ }
+
+ mergeBase, err := Module.RepoMergeBase(headPath, tmpRemoteBranch, headBranch)
+ if err != nil {
+ return nil, errors.Wrap(err, "get merge base")
+ }
+
+ commits, err := Module.RepoLog(headPath, mergeBase+"..."+headBranch)
+ if err != nil {
+ return nil, errors.Wrap(err, "get commits")
+ }
+
+ // Count number of changed files
+ names, err := Module.RepoDiffNameOnly(headPath, tmpRemoteBranch, headBranch, git.DiffNameOnlyOptions{NeedsMergeBase: true})
+ if err != nil {
+ return nil, errors.Wrap(err, "get changed files")
+ }
+
+ return &PullRequestMeta{
+ MergeBase: mergeBase,
+ Commits: commits,
+ NumFiles: len(names),
+ }, nil
+}