You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2020 The Gitea 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 pull
  5. import (
  6. "fmt"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/git"
  9. "code.gitea.io/gitea/modules/log"
  10. )
  11. // Update updates pull request with base branch.
  12. func Update(pull *models.PullRequest, doer *models.User, message string) error {
  13. //use merge functions but switch repo's and branch's
  14. pr := &models.PullRequest{
  15. HeadRepoID: pull.BaseRepoID,
  16. BaseRepoID: pull.HeadRepoID,
  17. HeadBranch: pull.BaseBranch,
  18. BaseBranch: pull.HeadBranch,
  19. }
  20. if err := pr.LoadHeadRepo(); err != nil {
  21. log.Error("LoadHeadRepo: %v", err)
  22. return fmt.Errorf("LoadHeadRepo: %v", err)
  23. } else if err = pr.LoadBaseRepo(); err != nil {
  24. log.Error("LoadBaseRepo: %v", err)
  25. return fmt.Errorf("LoadBaseRepo: %v", err)
  26. }
  27. diffCount, err := GetDiverging(pull)
  28. if err != nil {
  29. return err
  30. } else if diffCount.Behind == 0 {
  31. return fmt.Errorf("HeadBranch of PR %d is up to date", pull.Index)
  32. }
  33. _, err = rawMerge(pr, doer, models.MergeStyleMerge, message)
  34. defer func() {
  35. go AddTestPullRequestTask(doer, pr.HeadRepo.ID, pr.HeadBranch, false, "", "")
  36. }()
  37. return err
  38. }
  39. // IsUserAllowedToUpdate check if user is allowed to update PR with given permissions and branch protections
  40. func IsUserAllowedToUpdate(pull *models.PullRequest, user *models.User) (bool, error) {
  41. headRepoPerm, err := models.GetUserRepoPermission(pull.HeadRepo, user)
  42. if err != nil {
  43. return false, err
  44. }
  45. pr := &models.PullRequest{
  46. HeadRepoID: pull.BaseRepoID,
  47. BaseRepoID: pull.HeadRepoID,
  48. HeadBranch: pull.BaseBranch,
  49. BaseBranch: pull.HeadBranch,
  50. }
  51. err = pr.LoadProtectedBranch()
  52. if err != nil {
  53. return false, err
  54. }
  55. // Update function need push permission
  56. if pr.ProtectedBranch != nil && !pr.ProtectedBranch.CanUserPush(user.ID) {
  57. return false, nil
  58. }
  59. return IsUserAllowedToMerge(pr, headRepoPerm, user)
  60. }
  61. // GetDiverging determines how many commits a PR is ahead or behind the PR base branch
  62. func GetDiverging(pr *models.PullRequest) (*git.DivergeObject, error) {
  63. log.Trace("GetDiverging[%d]: compare commits", pr.ID)
  64. if err := pr.LoadBaseRepo(); err != nil {
  65. return nil, err
  66. }
  67. if err := pr.LoadHeadRepo(); err != nil {
  68. return nil, err
  69. }
  70. tmpRepo, err := createTemporaryRepo(pr)
  71. if err != nil {
  72. log.Error("CreateTemporaryPath: %v", err)
  73. return nil, err
  74. }
  75. defer func() {
  76. if err := models.RemoveTemporaryPath(tmpRepo); err != nil {
  77. log.Error("Merge: RemoveTemporaryPath: %s", err)
  78. }
  79. }()
  80. diff, err := git.GetDivergingCommits(tmpRepo, "base", "tracking")
  81. return &diff, err
  82. }