@@ -97,11 +97,11 @@ func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.
9797}
9898
9999// IsUserAllowedToUpdate check if user is allowed to update PR with given permissions and branch protections
100+ // update PR means send new commits to PR head branch from base branch
100101func IsUserAllowedToUpdate (ctx context.Context , pull * issues_model.PullRequest , user * user_model.User ) (mergeAllowed , rebaseAllowed bool , err error ) {
101102 if pull .Flow == issues_model .PullRequestFlowAGit {
102103 return false , false , nil
103104 }
104-
105105 if user == nil {
106106 return false , false , nil
107107 }
@@ -117,61 +117,56 @@ func IsUserAllowedToUpdate(ctx context.Context, pull *issues_model.PullRequest,
117117 return false , false , err
118118 }
119119
120- pr := & issues_model.PullRequest {
121- HeadRepoID : pull .BaseRepoID ,
122- HeadRepo : pull .BaseRepo ,
123- BaseRepoID : pull .HeadRepoID ,
124- BaseRepo : pull .HeadRepo ,
125- HeadBranch : pull .BaseBranch ,
126- BaseBranch : pull .HeadBranch ,
127- }
128-
129- pb , err := git_model .GetFirstMatchProtectedBranchRule (ctx , pr .BaseRepoID , pr .BaseBranch )
130- if err != nil {
131- return false , false , err
132- }
133-
134- if err := pr .LoadBaseRepo (ctx ); err != nil {
135- return false , false , err
136- }
137- prUnit , err := pr .BaseRepo .GetUnit (ctx , unit .TypePullRequests )
138- if err != nil {
120+ // 1. check base repository's AllowRebaseUpdate configuration
121+ // it is a config in base repo but controls the head (fork) repo's "Update" behavior
122+ {
123+ prBaseUnit , err := pull .BaseRepo .GetUnit (ctx , unit .TypePullRequests )
139124 if repo_model .IsErrUnitTypeNotExist (err ) {
140- return false , false , nil
125+ return false , false , nil // the PR unit is disabled in base repo
126+ } else if err != nil {
127+ return false , false , fmt .Errorf ("get base repo unit: %v" , err )
141128 }
142- log .Error ("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v" , err )
143- return false , false , err
129+ rebaseAllowed = prBaseUnit .PullRequestsConfig ().AllowRebaseUpdate
144130 }
145131
146- rebaseAllowed = prUnit .PullRequestsConfig ().AllowRebaseUpdate
147-
148- // If branch protected, disable rebase unless user is whitelisted to force push (which extends regular push)
149- if pb != nil {
150- pb .Repo = pull .BaseRepo
151- if ! pb .CanUserForcePush (ctx , user ) {
152- rebaseAllowed = false
132+ // 2. check head branch protection whether rebase is allowed, if pb not found then rebase depends on the above setting
133+ {
134+ pb , err := git_model .GetFirstMatchProtectedBranchRule (ctx , pull .HeadRepoID , pull .HeadBranch )
135+ if err != nil {
136+ return false , false , err
137+ }
138+ // If branch protected, disable rebase unless user is whitelisted to force push (which extends regular push)
139+ if pb != nil {
140+ pb .Repo = pull .HeadRepo
141+ rebaseAllowed = rebaseAllowed && pb .CanUserForcePush (ctx , user )
153142 }
154143 }
155144
145+ // 3. check whether user has write access to head branch
156146 baseRepoPerm , err := access_model .GetUserRepoPermission (ctx , pull .BaseRepo , user )
157147 if err != nil {
158148 return false , false , err
159149 }
160150
161- mergeAllowed , err = IsUserAllowedToMerge (ctx , pr , headRepoPerm , user )
151+ mergeAllowed , err = isUserAllowedToMergeInRepoBranch (ctx , pull . HeadRepoID , pull . HeadBranch , headRepoPerm , user )
162152 if err != nil {
163153 return false , false , err
164154 }
165155
156+ // 4. if the pull creator allows maintainer to edit, it means the write permissions of the head branch has been
157+ // granted to the user with write permission of the base repository
166158 if pull .AllowMaintainerEdit {
167- mergeAllowedMaintainer , err := IsUserAllowedToMerge (ctx , pr , baseRepoPerm , user )
159+ mergeAllowedMaintainer , err := isUserAllowedToMergeInRepoBranch (ctx , pull . BaseRepoID , pull . BaseBranch , baseRepoPerm , user )
168160 if err != nil {
169161 return false , false , err
170162 }
171163
172164 mergeAllowed = mergeAllowed || mergeAllowedMaintainer
173165 }
174166
167+ // if merge is not allowed, rebase is also not allowed
168+ rebaseAllowed = rebaseAllowed && mergeAllowed
169+
175170 return mergeAllowed , rebaseAllowed , nil
176171}
177172
0 commit comments