@@ -101,11 +101,11 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.
101101}
102102
103103// IsUserAllowedToUpdate check if user is allowed to update PR with given permissions and branch protections
104+ // update PR means send new commits to PR head branch from base branch
104105func IsUserAllowedToUpdate (ctx context.Context , pull * issues_model.PullRequest , user * user_model.User ) (mergeAllowed , rebaseAllowed bool , err error ) {
105106 if pull .Flow == issues_model .PullRequestFlowAGit {
106107 return false , false , nil
107108 }
108-
109109 if user == nil {
110110 return false , false , nil
111111 }
@@ -121,61 +121,55 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest,
121121 return false , false , err
122122 }
123123
124- pr := & issues_model.PullRequest {
125- HeadRepoID : pull .BaseRepoID ,
126- HeadRepo : pull .BaseRepo ,
127- BaseRepoID : pull .HeadRepoID ,
128- BaseRepo : pull .HeadRepo ,
129- HeadBranch : pull .BaseBranch ,
130- BaseBranch : pull .HeadBranch ,
131- }
132-
133- pb , err := git_model .GetFirstMatchProtectedBranchRule (ctx , pr .BaseRepoID , pr .BaseBranch )
134- if err != nil {
135- return false , false , err
124+ // 1. check base repository's AllowRebaseUpdate configuration
125+ // it is a config in base repo but controls the head (fork) repo's "Update" behavior
126+ prBaseUnit , err := pull .BaseRepo .GetUnit (ctx , unit .TypePullRequests )
127+ if repo_model .IsErrUnitTypeNotExist (err ) {
128+ return false , false , nil // the PR unit is disabled in base repo
129+ } else if err != nil {
130+ return false , false , fmt .Errorf ("get base repo unit: %v" , err )
131+ } else {
132+ rebaseAllowed = prBaseUnit .PullRequestsConfig ().AllowRebaseUpdate
136133 }
137134
138- if err := pr .LoadBaseRepo (ctx ); err != nil {
139- return false , false , err
140- }
141- prUnit , err := pr .BaseRepo .GetUnit (ctx , unit .TypePullRequests )
142- if err != nil {
143- if repo_model .IsErrUnitTypeNotExist (err ) {
144- return false , false , nil
135+ // 2. check head branch protection whether rebase is allowed, if pb not found then rebase depends on the above setting
136+ {
137+ pb , err := git_model .GetFirstMatchProtectedBranchRule (ctx , pull .HeadRepoID , pull .HeadBranch )
138+ if err != nil {
139+ return false , false , err
145140 }
146- log .Error ("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v" , err )
147- return false , false , err
148- }
149-
150- rebaseAllowed = prUnit .PullRequestsConfig ().AllowRebaseUpdate
151-
152- // If branch protected, disable rebase unless user is whitelisted to force push (which extends regular push)
153- if pb != nil {
154- pb .Repo = pull .BaseRepo
155- if ! pb .CanUserForcePush (ctx , user ) {
156- rebaseAllowed = false
141+ // If branch protected, disable rebase unless user is whitelisted to force push (which extends regular push)
142+ if pb != nil {
143+ pb .Repo = pull .HeadRepo
144+ rebaseAllowed = rebaseAllowed && pb .CanUserForcePush (ctx , user )
157145 }
158146 }
159147
148+ // 3. check whether user has write access to head branch
160149 baseRepoPerm , err := access_model .GetUserRepoPermission (ctx , pull .BaseRepo , user )
161150 if err != nil {
162151 return false , false , err
163152 }
164153
165- mergeAllowed , err = IsUserAllowedToMerge (ctx , pr , headRepoPerm , user )
154+ mergeAllowed , err = isUserAllowedToMergeInRepoBranch (ctx , pull . HeadRepoID , pull . HeadBranch , headRepoPerm , user )
166155 if err != nil {
167156 return false , false , err
168157 }
169158
159+ // 4. if the pull creator allows maintainer to edit, it means the write permissions of the head branch has been
160+ // granted to the user with write permission of the base repository
170161 if pull .AllowMaintainerEdit {
171- mergeAllowedMaintainer , err := IsUserAllowedToMerge (ctx , pr , baseRepoPerm , user )
162+ mergeAllowedMaintainer , err := isUserAllowedToMergeInRepoBranch (ctx , pull . BaseRepoID , pull . BaseBranch , baseRepoPerm , user )
172163 if err != nil {
173164 return false , false , err
174165 }
175166
176167 mergeAllowed = mergeAllowed || mergeAllowedMaintainer
177168 }
178169
170+ // if merge is not allowed, rebase is also not allowed
171+ rebaseAllowed = rebaseAllowed && mergeAllowed
172+
179173 return mergeAllowed , rebaseAllowed , nil
180174}
181175
0 commit comments