git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] merge: --ff-one-only to apply FF if commit is one

From
Ruslan Yakauleu via GitGitGadget <gitgitgadget@gmail.com>
Date
Oct 25, 2023, 08:58 UTC
Message-ID
<pull.1599.git.git.1698224280816.gitgitgadget@gmail.com>
From: Ruslan Yakauleu <ruslan.yakauleu@gmail.com>

A new option --ff-one-only to control the merging strategy. For one commit option works like -ff to avoid extra merge commit. In other cases the option works like --no-ff to create merge commit for complex features.

Signed-off-by: Ruslan Yakauleu <ruslan.yakauleu@gmail.com>
---
    merge: --ff-one-only to apply FF if commit is one
    
    A new option --ff-one-only to control the merging strategy. For one
    commit option works like -ff to avoid extra merge commit. In other cases
    the option works like --no-ff to create merge commit for complex
    features.
    
    Plenty of developers want to simplify merge history. We have two main
    merging strategies:
    
     * Fast-forward (--ff) - There we can lose merge commits for complex
       features and if we need to roll back some feature we can't revert
       just one commit.
     * Merge (--no-ff) - There we have extra merges for extra simple
       changes.
    
    Before, the user had to choose between --ff/--no-ff every time to have
    history without extra merges for simple changes and to use merges for
    complex features.
    
    Ways to use the new option: git merge --ff-one-only git config merge.ff
    one-only git config branch.master.mergeoptions --ff-one-only
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1599%2FQuAzI%2Fmerge%2Fff-one-only-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1599/QuAzI/merge/ff-one-only-v1
Pull-Request: https://github.com/git/git/pull/1599
 Documentation/config/merge.txt |  3 +++
 builtin/merge.c                | 18 +++++++++++++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/Documentation/config/merge.txt b/Documentation/config/merge.txt
index 8851b6cedef..6cd5daa4d64 100644
--- a/Documentation/config/merge.txt
+++ b/Documentation/config/merge.txt
@@ -31,6 +31,9 @@ merge.ff::
 	a case (equivalent to giving the `--no-ff` option from the command
 	line). When set to `only`, only such fast-forward merges are
 	allowed (equivalent to giving the `--ff-only` option from the
+	command line). When set to `one-only`, fast-forward merge allowed
+	only for one commit, in other way extra merge commit should be
+	created (equivalent to giving the `--ff-one-only` option from the
 	command line).
 
 merge.verifySignatures::
diff --git a/builtin/merge.c b/builtin/merge.c
index d748d46e135..100f0021e56 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -110,7 +110,8 @@ static const char *pull_twohead, *pull_octopus;
 enum ff_type {
 	FF_NO,
 	FF_ALLOW,
-	FF_ONLY
+	FF_ONLY,
+	FF_ONE_ONLY
 };
 
 static enum ff_type fast_forward = FF_ALLOW;
@@ -258,6 +259,7 @@ static struct option builtin_merge_options[] = {
 		N_("edit message before committing")),
 	OPT_CLEANUP(&cleanup_arg),
 	OPT_SET_INT(0, "ff", &fast_forward, N_("allow fast-forward (default)"), FF_ALLOW),
+	OPT_SET_INT(0, "ff-one-only", &fast_forward, N_("allow fast-forward if only one commit"), FF_ONE_ONLY),
 	OPT_SET_INT_F(0, "ff-only", &fast_forward,
 		      N_("abort if fast-forward is not possible"),
 		      FF_ONLY, PARSE_OPT_NONEG),
@@ -631,6 +633,8 @@ static int git_merge_config(const char *k, const char *v,
 			fast_forward = boolval ? FF_ALLOW : FF_NO;
 		} else if (v && !strcmp(v, "only")) {
 			fast_forward = FF_ONLY;
+		} else if (v && !strcmp(v, "one-only")) {
+			fast_forward = FF_ONE_ONLY;
 		} /* do not barf on values from future versions of git */
 		return 0;
 	} else if (!strcmp(k, "merge.defaulttoupstream")) {
@@ -1527,6 +1531,18 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 		free(list);
 	}
 
+	if (fast_forward == FF_ONE_ONLY) {
+		fast_forward = FF_NO;
+
+		/* check that we have one and only one commit to merge */
+		if (squash || ((!remoteheads->next &&
+				!common->next &&
+				oideq(&common->item->object.oid, &head_commit->object.oid)) &&
+				oideq(&remoteheads->item->parents->item->object.oid, &head_commit->object.oid))) {
+			fast_forward = FF_ALLOW;
+		}
+	}
+
 	update_ref("updating ORIG_HEAD", "ORIG_HEAD",
 		   &head_commit->object.oid, NULL, 0, UPDATE_REFS_DIE_ON_ERR);
 

base-commit: 2e8e77cbac8ac17f94eee2087187fa1718e38b14
-- 
gitgitgadget
Next: Kristoffer Haugsbakk
Message 1 of 15 in “merge: --ff-one-only to apply FF if commit is one”
  1. merge: --ff-one-only to apply FF if commit is oneRuslan Yakauleu via GitGitGadget, Oct 25, 2023
  2. Kristoffer HaugsbakkOct 25, 2023
  3. Ruslan YakauleuOct 25, 2023
  4. Kristoffer HaugsbakkOct 25, 2023
  5. Taylor BlauOct 30, 2023
  6. Junio C HamanoOct 31, 2023
  7. Ruslan YakauleuOct 31, 2023
  8. Junio C HamanoOct 31, 2023
  9. Kristoffer HaugsbakkOct 31, 2023
  10. Junio C HamanoNov 1, 2023
  11. Ruslan YakauleuNov 1, 2023
  12. Kristoffer HaugsbakkNov 1, 2023
  13. Junio C HamanoNov 1, 2023
  14. Ruslan YakauleuOct 31, 2023
  15. Ruslan YakauleuOct 26, 2023

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.