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.

update.go 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. if user == nil {
  42. return false, nil
  43. }
  44. headRepoPerm, err := models.GetUserRepoPermission(pull.HeadRepo, user)
  45. if err != nil {
  46. return false, err
  47. }
  48. pr := &models.PullRequest{
  49. HeadRepoID: pull.BaseRepoID,
  50. BaseRepoID: pull.HeadRepoID,
  51. HeadBranch: pull.BaseBranch,
  52. BaseBranch: pull.HeadBranch,
  53. }
  54. err = pr.LoadProtectedBranch()
  55. if err != nil {
  56. return false, err
  57. }
  58. // Update function need push permission
  59. if pr.ProtectedBranch != nil && !pr.ProtectedBranch.CanUserPush(user.ID) {
  60. return false, nil
  61. }
  62. return IsUserAllowedToMerge(pr, headRepoPerm, user)
  63. }
  64. // GetDiverging determines how many commits a PR is ahead or behind the PR base branch
  65. func GetDiverging(pr *models.PullRequest) (*git.DivergeObject, error) {
  66. log.Trace("GetDiverging[%d]: compare commits", pr.ID)
  67. if err := pr.LoadBaseRepo(); err != nil {
  68. return nil, err
  69. }
  70. if err := pr.LoadHeadRepo(); err != nil {
  71. return nil, err
  72. }
  73. tmpRepo, err := createTemporaryRepo(pr)
  74. if err != nil {
  75. log.Error("CreateTemporaryPath: %v", err)
  76. return nil, err
  77. }
  78. defer func() {
  79. if err := models.RemoveTemporaryPath(tmpRepo); err != nil {
  80. log.Error("Merge: RemoveTemporaryPath: %s", err)
  81. }
  82. }()
  83. diff, err := git.GetDivergingCommits(tmpRepo, "base", "tracking")
  84. return &diff, err
  85. }