mirror of
https://github.com/go-gitea/gitea.git
synced 2025-06-20 05:22:47 +00:00
Add ff_only parameter to POST /repos/{owner}/{repo}/merge-upstream (#34770)
The merge-upstream route was so far performing any kind of merge, even those that would create merge commits and thus make your branch diverge from upstream, requiring manual intervention via the git cli to undo the damage. With the new optional parameter ff_only, we can instruct gitea to error out, if a non-fast-forward merge would be performed.
This commit is contained in:
parent
7346ae7cd4
commit
b8c9a0c323
@ -136,6 +136,7 @@ type UpdateBranchProtectionPriories struct {
|
|||||||
|
|
||||||
type MergeUpstreamRequest struct {
|
type MergeUpstreamRequest struct {
|
||||||
Branch string `json:"branch"`
|
Branch string `json:"branch"`
|
||||||
|
FfOnly bool `json:"ff_only"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type MergeUpstreamResponse struct {
|
type MergeUpstreamResponse struct {
|
||||||
|
@ -1181,7 +1181,7 @@ func MergeUpstream(ctx *context.APIContext) {
|
|||||||
// "404":
|
// "404":
|
||||||
// "$ref": "#/responses/notFound"
|
// "$ref": "#/responses/notFound"
|
||||||
form := web.GetForm(ctx).(*api.MergeUpstreamRequest)
|
form := web.GetForm(ctx).(*api.MergeUpstreamRequest)
|
||||||
mergeStyle, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, form.Branch)
|
mergeStyle, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, form.Branch, form.FfOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, util.ErrInvalidArgument) {
|
if errors.Is(err, util.ErrInvalidArgument) {
|
||||||
ctx.APIError(http.StatusBadRequest, err)
|
ctx.APIError(http.StatusBadRequest, err)
|
||||||
|
@ -258,7 +258,7 @@ func CreateBranch(ctx *context.Context) {
|
|||||||
|
|
||||||
func MergeUpstream(ctx *context.Context) {
|
func MergeUpstream(ctx *context.Context) {
|
||||||
branchName := ctx.FormString("branch")
|
branchName := ctx.FormString("branch")
|
||||||
_, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, branchName)
|
_, err := repo_service.MergeUpstream(ctx, ctx.Doer, ctx.Repo.Repository, branchName, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, util.ErrNotExist) {
|
if errors.Is(err, util.ErrNotExist) {
|
||||||
ctx.JSONErrorNotFound()
|
ctx.JSONErrorNotFound()
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MergeUpstream merges the base repository's default branch into the fork repository's current branch.
|
// MergeUpstream merges the base repository's default branch into the fork repository's current branch.
|
||||||
func MergeUpstream(ctx reqctx.RequestContext, doer *user_model.User, repo *repo_model.Repository, branch string) (mergeStyle string, err error) {
|
func MergeUpstream(ctx reqctx.RequestContext, doer *user_model.User, repo *repo_model.Repository, branch string, ffOnly bool) (mergeStyle string, err error) {
|
||||||
if err = repo.MustNotBeArchived(); err != nil {
|
if err = repo.MustNotBeArchived(); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -45,6 +45,11 @@ func MergeUpstream(ctx reqctx.RequestContext, doer *user_model.User, repo *repo_
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If ff_only is requested and fast-forward failed, return error
|
||||||
|
if ffOnly {
|
||||||
|
return "", util.NewInvalidArgumentErrorf("fast-forward merge not possible: branch has diverged")
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: FakePR: it is somewhat hacky, but it is the only way to "merge" at the moment
|
// TODO: FakePR: it is somewhat hacky, but it is the only way to "merge" at the moment
|
||||||
// ideally in the future the "merge" functions should be refactored to decouple from the PullRequest
|
// ideally in the future the "merge" functions should be refactored to decouple from the PullRequest
|
||||||
fakeIssue := &issue_model.Issue{
|
fakeIssue := &issue_model.Issue{
|
||||||
|
4
templates/swagger/v1_json.tmpl
generated
4
templates/swagger/v1_json.tmpl
generated
@ -24839,6 +24839,10 @@
|
|||||||
"branch": {
|
"branch": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"x-go-name": "Branch"
|
"x-go-name": "Branch"
|
||||||
|
},
|
||||||
|
"ff_only": {
|
||||||
|
"type": "boolean",
|
||||||
|
"x-go-name": "FfOnly"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
"x-go-package": "code.gitea.io/gitea/modules/structs"
|
||||||
|
@ -147,5 +147,37 @@ func TestRepoMergeUpstream(t *testing.T) {
|
|||||||
return queryMergeUpstreamButtonLink(htmlDoc) == ""
|
return queryMergeUpstreamButtonLink(htmlDoc) == ""
|
||||||
}, 5*time.Second, 100*time.Millisecond)
|
}, 5*time.Second, 100*time.Millisecond)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("FastForwardOnly", func(t *testing.T) {
|
||||||
|
// Create a clean branch for fast-forward testing
|
||||||
|
req = NewRequestWithValues(t, "POST", fmt.Sprintf("/%s/test-repo-fork/branches/_new/branch/master", forkUser.Name), map[string]string{
|
||||||
|
"_csrf": GetUserCSRFToken(t, session),
|
||||||
|
"new_branch_name": "ff-test-branch",
|
||||||
|
})
|
||||||
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
||||||
|
|
||||||
|
// Add content to base repository that can be fast-forwarded
|
||||||
|
require.NoError(t, createOrReplaceFileInBranch(baseUser, baseRepo, "ff-test.txt", "master", "ff-content-1"))
|
||||||
|
|
||||||
|
// ff_only=true with fast-forward possible (should succeed)
|
||||||
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/test-repo-fork/merge-upstream", forkUser.Name), &api.MergeUpstreamRequest{
|
||||||
|
Branch: "ff-test-branch",
|
||||||
|
FfOnly: true,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
resp := MakeRequest(t, req, http.StatusOK)
|
||||||
|
|
||||||
|
var mergeResp api.MergeUpstreamResponse
|
||||||
|
DecodeJSON(t, resp, &mergeResp)
|
||||||
|
assert.Equal(t, "fast-forward", mergeResp.MergeStyle)
|
||||||
|
|
||||||
|
// ff_only=true when fast-forward is not possible (should fail)
|
||||||
|
require.NoError(t, createOrReplaceFileInBranch(baseUser, baseRepo, "another-file.txt", "master", "more-content"))
|
||||||
|
|
||||||
|
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/test-repo-fork/merge-upstream", forkUser.Name), &api.MergeUpstreamRequest{
|
||||||
|
Branch: "fork-branch",
|
||||||
|
FfOnly: true,
|
||||||
|
}).AddTokenAuth(token)
|
||||||
|
MakeRequest(t, req, http.StatusBadRequest)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user