feat: Add default PR branch update style setting (#37410)

Adds repository-level settings for pull request branch updates so admins
can choose the default update method and disable merge or rebase
updates.

<img width="1025" height="158"
src="https://github.com/user-attachments/assets/d030973b-0ddd-4035-b04f-145c445084d7"
/>

---------

Co-authored-by: OpenAI Codex (GPT-5) <codex@openai.com>
Co-authored-by: silverwind <me@silverwind.io>
Co-authored-by: Claude (Opus 4.7) <noreply@anthropic.com>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Nicolas
2026-05-16 10:06:40 +00:00
committed by GitHub
co-authored by OpenAI Codex silverwind Claude wxiaoguang
parent 16189a68c4
commit 34fd3c9f06
20 changed files with 493 additions and 60 deletions
+44
View File
@@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/gitrepo"
api "code.gitea.io/gitea/modules/structs"
mirror_service "code.gitea.io/gitea/services/mirror"
"code.gitea.io/gitea/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -69,6 +70,9 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
allowRebaseMerge := false
allowSquash := false
allowFastForwardOnly := false
allowMergeUpdate := false
allowRebaseUpdate := false
defaultUpdateStyle := string(repo_model.UpdateStyleMerge)
if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil {
config := unit.PullRequestsConfig()
hasPullRequests = true
@@ -78,6 +82,9 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
allowRebaseMerge = config.AllowRebaseMerge
allowSquash = config.AllowSquash
allowFastForwardOnly = config.AllowFastForwardOnly
allowMergeUpdate = config.AllowMergeUpdate
allowRebaseUpdate = config.AllowRebaseUpdate
defaultUpdateStyle = string(config.DefaultUpdateStyle)
}
archived := repo.IsArchived
hasProjects := false
@@ -122,6 +129,9 @@ func getRepoEditOptionFromRepo(repo *repo_model.Repository) *api.EditRepoOption
AllowRebaseMerge: &allowRebaseMerge,
AllowSquash: &allowSquash,
AllowFastForwardOnly: &allowFastForwardOnly,
AllowMergeUpdate: &allowMergeUpdate,
AllowRebaseUpdate: &allowRebaseUpdate,
DefaultUpdateStyle: &defaultUpdateStyle,
Archived: &archived,
}
}
@@ -148,6 +158,9 @@ func getNewRepoEditOption(opts *api.EditRepoOption) *api.EditRepoOption {
allowRebase := !*opts.AllowRebase
allowRebaseMerge := !*opts.AllowRebaseMerge
allowSquash := !*opts.AllowSquash
allowMergeUpdate := false
allowRebaseUpdate := true
defaultUpdateStyle := string(repo_model.UpdateStyleRebase)
archived := !*opts.Archived
return &api.EditRepoOption{
@@ -169,6 +182,9 @@ func getNewRepoEditOption(opts *api.EditRepoOption) *api.EditRepoOption {
AllowRebase: &allowRebase,
AllowRebaseMerge: &allowRebaseMerge,
AllowSquash: &allowSquash,
AllowMergeUpdate: &allowMergeUpdate,
AllowRebaseUpdate: &allowRebaseUpdate,
DefaultUpdateStyle: &defaultUpdateStyle,
Archived: &archived,
}
}
@@ -488,3 +504,31 @@ func TestAPIRepoEdit(t *testing.T) {
assert.Equal(t, token, password)
})
}
func TestAPIRepoEditPullUpdateSettingsValidation(t *testing.T) {
defer tests.PrepareTestEnv(t)()
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
repoURL := fmt.Sprintf("/api/v1/repos/%s/%s", user2.Name, repo1.Name)
allowMergeUpdate := false
allowRebaseUpdate := false
req := NewRequestWithJSON(t, "PATCH", repoURL, &api.EditRepoOption{
AllowMergeUpdate: &allowMergeUpdate,
AllowRebaseUpdate: &allowRebaseUpdate,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusUnprocessableEntity)
allowRebaseUpdate = true
defaultUpdateStyle := string(repo_model.UpdateStyleMerge)
req = NewRequestWithJSON(t, "PATCH", repoURL, &api.EditRepoOption{
AllowMergeUpdate: &allowMergeUpdate,
AllowRebaseUpdate: &allowRebaseUpdate,
DefaultUpdateStyle: &defaultUpdateStyle,
}).AddTokenAuth(token)
MakeRequest(t, req, http.StatusUnprocessableEntity)
}