From 47b59658629f47e0ac559559a305b867740cae9c Mon Sep 17 00:00:00 2001 From: Chris Copeland Date: Mon, 12 Feb 2024 14:37:23 -0800 Subject: Add merge style `fast-forward-only` (#28954) With this option, it is possible to require a linear commit history with the following benefits over the next best option `Rebase+fast-forward`: The original commits continue existing, with the original signatures continuing to stay valid instead of being rewritten, there is no merge commit, and reverting commits becomes easier. Closes #24906 --- services/pull/merge.go | 11 +++++++++++ services/pull/merge_ff_only.go | 21 +++++++++++++++++++++ services/pull/merge_merge.go | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 services/pull/merge_ff_only.go (limited to 'services/pull') diff --git a/services/pull/merge.go b/services/pull/merge.go index 63f0268beb..d4c0c821d6 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -267,6 +267,10 @@ func doMergeAndPush(ctx context.Context, pr *issues_model.PullRequest, doer *use if err := doMergeStyleSquash(mergeCtx, message); err != nil { return "", err } + case repo_model.MergeStyleFastForwardOnly: + if err := doMergeStyleFastForwardOnly(mergeCtx); err != nil { + return "", err + } default: return "", models.ErrInvalidMergeStyle{ID: pr.BaseRepo.ID, Style: mergeStyle} } @@ -377,6 +381,13 @@ func runMergeCommand(ctx *mergeContext, mergeStyle repo_model.MergeStyle, cmd *g StdErr: ctx.errbuf.String(), Err: err, } + } else if mergeStyle == repo_model.MergeStyleFastForwardOnly && strings.Contains(ctx.errbuf.String(), "Not possible to fast-forward, aborting") { + log.Debug("MergeDivergingFastForwardOnly %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) + return models.ErrMergeDivergingFastForwardOnly{ + StdOut: ctx.outbuf.String(), + StdErr: ctx.errbuf.String(), + Err: err, + } } log.Error("git merge %-v: %v\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) return fmt.Errorf("git merge %v: %w\n%s\n%s", ctx.pr, err, ctx.outbuf.String(), ctx.errbuf.String()) diff --git a/services/pull/merge_ff_only.go b/services/pull/merge_ff_only.go new file mode 100644 index 0000000000..f57c732104 --- /dev/null +++ b/services/pull/merge_ff_only.go @@ -0,0 +1,21 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package pull + +import ( + repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" +) + +// doMergeStyleFastForwardOnly merges the tracking into the current HEAD - which is assumed to be staging branch (equal to the pr.BaseBranch) +func doMergeStyleFastForwardOnly(ctx *mergeContext) error { + cmd := git.NewCommand(ctx, "merge", "--ff-only").AddDynamicArguments(trackingBranch) + if err := runMergeCommand(ctx, repo_model.MergeStyleFastForwardOnly, cmd); err != nil { + log.Error("%-v Unable to merge tracking into base: %v", ctx.pr, err) + return err + } + + return nil +} diff --git a/services/pull/merge_merge.go b/services/pull/merge_merge.go index 0f7664297a..bf56c071db 100644 --- a/services/pull/merge_merge.go +++ b/services/pull/merge_merge.go @@ -9,7 +9,7 @@ import ( "code.gitea.io/gitea/modules/log" ) -// doMergeStyleMerge merges the tracking into the current HEAD - which is assumed to tbe staging branch (equal to the pr.BaseBranch) +// doMergeStyleMerge merges the tracking branch into the current HEAD - which is assumed to be the staging branch (equal to the pr.BaseBranch) func doMergeStyleMerge(ctx *mergeContext, message string) error { cmd := git.NewCommand(ctx, "merge", "--no-ff", "--no-commit").AddDynamicArguments(trackingBranch) if err := runMergeCommand(ctx, repo_model.MergeStyleMerge, cmd); err != nil { -- cgit v1.2.3