diff --git a/models/repo.go b/models/repo.go
index 4b2221e643..6a806b7e25 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -521,7 +521,7 @@ func CreateRepository(ctx context.Context, doer, u *user_model.User, repo *repo_
 			units = append(units, repo_model.RepoUnit{
 				RepoID: repo.ID,
 				Type:   tp,
-				Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyleMerge},
+				Config: &repo_model.PullRequestsConfig{AllowMerge: true, AllowRebase: true, AllowRebaseMerge: true, AllowSquash: true, DefaultMergeStyle: repo_model.MergeStyleMerge, AllowRebaseUpdate: true},
 			})
 		} else {
 			units = append(units, repo_model.RepoUnit{
diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go
index f526cbdf8b..37f1c70545 100644
--- a/models/repo/repo_unit.go
+++ b/models/repo/repo_unit.go
@@ -115,12 +115,15 @@ type PullRequestsConfig struct {
 	AllowSquash                   bool
 	AllowManualMerge              bool
 	AutodetectManualMerge         bool
+	AllowRebaseUpdate             bool
 	DefaultDeleteBranchAfterMerge bool
 	DefaultMergeStyle             MergeStyle
 }
 
 // FromDB fills up a PullRequestsConfig from serialized format.
 func (cfg *PullRequestsConfig) FromDB(bs []byte) error {
+	// AllowRebaseUpdate = true as default for existing PullRequestConfig in DB
+	cfg.AllowRebaseUpdate = true
 	return json.UnmarshalHandleDoubleEncode(bs, &cfg)
 }
 
diff --git a/modules/structs/repo.go b/modules/structs/repo.go
index 087ae941f4..27d0b4f3ba 100644
--- a/modules/structs/repo.go
+++ b/modules/structs/repo.go
@@ -177,6 +177,8 @@ type EditRepoOption struct {
 	AllowManualMerge *bool `json:"allow_manual_merge,omitempty"`
 	// either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur.
 	AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"`
+	// either `true` to allow updating pull request branch by rebase, or `false` to prevent it. `has_pull_requests` must be `true`.
+	AllowRebaseUpdate *bool `json:"allow_rebase_update,omitempty"`
 	// set to `true` to delete pr branch after merge by default
 	DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"`
 	// set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`.
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index f52fef3c05..6a7f9bb47c 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -1786,6 +1786,7 @@ settings.pulls.allow_rebase_merge_commit = Enable Rebasing with explicit merge c
 settings.pulls.allow_squash_commits = Enable Squashing to Merge Commits
 settings.pulls.allow_manual_merge = Enable Mark PR as manually merged
 settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
+settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
 settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
 settings.projects_desc = Enable Repository Projects
 settings.admin_settings = Administrator Settings
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 7a7fe218e8..560139c457 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -860,6 +860,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
 					AllowSquash:                   true,
 					AllowManualMerge:              true,
 					AutodetectManualMerge:         false,
+					AllowRebaseUpdate:             true,
 					DefaultDeleteBranchAfterMerge: false,
 					DefaultMergeStyle:             repo_model.MergeStyleMerge,
 				}
@@ -888,6 +889,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
 			if opts.AutodetectManualMerge != nil {
 				config.AutodetectManualMerge = *opts.AutodetectManualMerge
 			}
+			if opts.AllowRebaseUpdate != nil {
+				config.AllowRebaseUpdate = *opts.AllowRebaseUpdate
+			}
 			if opts.DefaultDeleteBranchAfterMerge != nil {
 				config.DefaultDeleteBranchAfterMerge = *opts.DefaultDeleteBranchAfterMerge
 			}
diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go
index 8e249af55d..5f7b948b8c 100644
--- a/routers/web/repo/setting.go
+++ b/routers/web/repo/setting.go
@@ -472,6 +472,7 @@ func SettingsPost(ctx *context.Context) {
 					AllowSquash:                   form.PullsAllowSquash,
 					AllowManualMerge:              form.PullsAllowManualMerge,
 					AutodetectManualMerge:         form.EnableAutodetectManualMerge,
+					AllowRebaseUpdate:             form.PullsAllowRebaseUpdate,
 					DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
 					DefaultMergeStyle:             repo_model.MergeStyle(form.PullsDefaultMergeStyle),
 				},
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index da709ef800..3760c71f2a 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -151,6 +151,7 @@ type RepoSettingForm struct {
 	PullsAllowManualMerge                 bool
 	PullsDefaultMergeStyle                string
 	EnableAutodetectManualMerge           bool
+	PullsAllowRebaseUpdate                bool
 	DefaultDeleteBranchAfterMerge         bool
 	EnableTimetracker                     bool
 	AllowOnlyContributorsToTrackTime      bool
diff --git a/services/pull/update.go b/services/pull/update.go
index f32dfad2ca..2ad58ecd29 100644
--- a/services/pull/update.go
+++ b/services/pull/update.go
@@ -10,6 +10,7 @@ import (
 
 	"code.gitea.io/gitea/models"
 	repo_model "code.gitea.io/gitea/models/repo"
+	"code.gitea.io/gitea/models/unit"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
@@ -97,7 +98,12 @@ func IsUserAllowedToUpdate(pull *models.PullRequest, user *user_model.User) (mer
 
 	// can't do rebase on protected branch because need force push
 	if pr.ProtectedBranch == nil {
-		rebaseAllowed = true
+		prUnit, err := pr.BaseRepo.GetUnit(unit.TypePullRequests)
+		if err != nil {
+			log.Error("pr.BaseRepo.GetUnit(unit.TypePullRequests): %v", err)
+			return false, false, err
+		}
+		rebaseAllowed = prUnit.PullRequestsConfig().AllowRebaseUpdate
 	}
 
 	// Update function need push permission
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index adcb6dd3df..7695345010 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -448,6 +448,12 @@
 								<label>{{.i18n.Tr "repo.settings.pulls.enable_autodetect_manual_merge"}}</label>
 							</div>
 						</div>
+						<div class="field">
+							<div class="ui checkbox">
+								<input name="pulls_allow_rebase_update" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.AllowRebaseUpdate)}}checked{{end}}>
+								<label>{{.i18n.Tr "repo.settings.pulls.allow_rebase_update"}}</label>
+							</div>
+						</div>
 						<div class="field">
 							<div class="ui checkbox">
 								<input name="default_delete_branch_after_merge" type="checkbox" {{if or (not $pullRequestEnabled) ($prUnit.PullRequestsConfig.DefaultDeleteBranchAfterMerge)}}checked{{end}}>
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 69abe24020..3bc6158183 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -14809,6 +14809,11 @@
           "type": "boolean",
           "x-go-name": "AllowRebaseMerge"
         },
+        "allow_rebase_update": {
+          "description": "either `true` to allow updating pull request branch by rebase, or `false` to prevent it. `has_pull_requests` must be `true`.",
+          "type": "boolean",
+          "x-go-name": "AllowRebaseUpdate"
+        },
         "allow_squash_merge": {
           "description": "either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`.",
           "type": "boolean",