pull_request.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // Copyright 2020 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package gitutil
  5. import (
  6. "fmt"
  7. "strconv"
  8. "time"
  9. "github.com/gogs/git-module"
  10. "github.com/pkg/errors"
  11. log "unknwon.dev/clog/v2"
  12. )
  13. // PullRequestMeta contains metadata for a pull request.
  14. type PullRequestMeta struct {
  15. // The merge base of the pull request.
  16. MergeBase string
  17. // The commits that are requested to be merged.
  18. Commits []*git.Commit
  19. // The number of files changed.
  20. NumFiles int
  21. }
  22. func (module) PullRequestMeta(headPath, basePath, headBranch, baseBranch string) (*PullRequestMeta, error) {
  23. tmpRemoteBranch := baseBranch
  24. // We need to create a temporary remote when the pull request is sent from a forked repository.
  25. if headPath != basePath {
  26. tmpRemote := strconv.FormatInt(time.Now().UnixNano(), 10)
  27. err := Module.RepoAddRemote(headPath, tmpRemote, basePath, git.AddRemoteOptions{Fetch: true})
  28. if err != nil {
  29. return nil, fmt.Errorf("add remote: %v", err)
  30. }
  31. defer func() {
  32. err := Module.RepoRemoveRemote(headPath, tmpRemote)
  33. if err != nil {
  34. log.Error("Failed to remove remote %q [path: %s]: %v", tmpRemote, headPath, err)
  35. return
  36. }
  37. }()
  38. tmpRemoteBranch = "remotes/" + tmpRemote + "/" + baseBranch
  39. }
  40. mergeBase, err := Module.RepoMergeBase(headPath, tmpRemoteBranch, headBranch)
  41. if err != nil {
  42. return nil, errors.Wrap(err, "get merge base")
  43. }
  44. commits, err := Module.RepoLog(headPath, mergeBase+"..."+headBranch)
  45. if err != nil {
  46. return nil, errors.Wrap(err, "get commits")
  47. }
  48. // Count number of changed files
  49. names, err := Module.RepoDiffNameOnly(headPath, tmpRemoteBranch, headBranch, git.DiffNameOnlyOptions{NeedsMergeBase: true})
  50. if err != nil {
  51. return nil, errors.Wrap(err, "get changed files")
  52. }
  53. return &PullRequestMeta{
  54. MergeBase: mergeBase,
  55. Commits: commits,
  56. NumFiles: len(names),
  57. }, nil
  58. }