diff options
Diffstat (limited to 'internal/gitutil/pull_request.go')
-rw-r--r-- | internal/gitutil/pull_request.go | 69 |
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 +} |