Subject: Re: [PATCH v4 0/2] merge-tree: add new --quiet option

From: Phillip Wood <[email-masked]>
Date: Mon, 19 May 2025 10:05:09 +0100

Hi Elijah

On 16/05/2025 21:04, Elijah Newren via GitGitGadget wrote:
> Changes since v3:
> 
>   * Renamed --dry-run -> --quiet . Any further naming suggestions?

Thanks for re-rolling this version looks good to me.

Thanks

Phillip

> Changes since v2:
> 
>   * Converted locations missed in v1 in changing --mergeability-only ->
>     --dry-run
> 
> Changes since v1:
> 
>   * Renamed --mergeability-only flag to --dry-run, as per suggestion from
>     Junio
>   * added some commit message clarifications
> 
> This adds a new flag, --dry-run, to git merge-tree, which suppresses all
> output and leaves only the exit status (reflecting successful merge or
> conflict). This is useful for Git Forges in cases where they are only
> interested in whether two branches can be merged, without needing the actual
> merge result or conflict details.
> 
> The advantage of the flag is two fold:
> 
>   * The merge machinery can exit once it detects a conflict, instead of
>     continuing to compute merge result information
>   * The merge machinery can avoid writing merged blobs and trees to the
>     object store when in the outer layer of the merging process (more details
>     in the first commit message).
> 
> Elijah Newren (2):
>    merge-ort: add a new mergeability_only option
>    merge-tree: add a new --quiet flag
> 
>   Documentation/git-merge-tree.adoc |  6 +++++
>   builtin/merge-tree.c              | 18 +++++++++++++++
>   merge-ort.c                       | 38 +++++++++++++++++++++++++------
>   merge-ort.h                       |  1 +
>   t/t4301-merge-tree-write-tree.sh  | 38 +++++++++++++++++++++++++++++++
>   5 files changed, 94 insertions(+), 7 deletions(-)
> 
> 
> base-commit: 6c0bd1fc70efaf053abe4e57c976afdc72d15377
> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1920%2Fnewren%2Fmergeability-only-v4
> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1920/newren/mergeability-only-v4
> Pull-Request: https://github.com/gitgitgadget/git/pull/1920
> 
> Range-diff vs v3:
> 
>   1:  4757c4810d3 = 1:  4757c4810d3 merge-ort: add a new mergeability_only option
>   2:  f11824317a8 ! 2:  7c40d3c9216 merge-tree: add a new --dry-run flag
>       @@ Metadata
>        Author: Elijah Newren <[email-masked]>
>        
>         ## Commit message ##
>       -    merge-tree: add a new --dry-run flag
>       +    merge-tree: add a new --quiet flag
>        
>            Git Forges may be interested in whether two branches can be merged while
>            not being interested in what the resulting merge tree is nor which files
>       -    conflicted.  For such cases, add a new --dry-run flag which
>       +    conflicted.  For such cases, add a new --quiet flag which
>            will make use of the new mergeability_only flag added to merge-ort in
>            the previous commit.  This option allows the merge machinery to, in the
>            outer layer of the merge:
>       @@ Documentation/git-merge-tree.adoc: OPTIONS
>         	default is to include these messages if there are merge
>         	conflicts, and to omit them otherwise.
>         
>       -+--dry-run::
>       ++--quiet::
>        +	Disable all output from the program.  Useful when you are only
>        +	interested in the exit status.  Allows merge-tree to exit
>        +	early when it finds a conflict, and allows it to avoid writing
>       @@ builtin/merge-tree.c: int cmd_merge_tree(int argc,
>         	int original_argc;
>         	const char *merge_base = NULL;
>         	int ret;
>       -+	int dry_run = 0;
>       ++	int quiet = 0;
>         
>         	const char * const merge_tree_usage[] = {
>         		N_("git merge-tree [--write-tree] [<options>] <branch1> <branch2>"),
>       @@ builtin/merge-tree.c: int cmd_merge_tree(int argc,
>         			    N_("do a trivial merge only"), MODE_TRIVIAL),
>         		OPT_BOOL(0, "messages", &o.show_messages,
>         			 N_("also show informational/conflict messages")),
>       -+		OPT_BOOL_F(0, "dry-run",
>       -+			   &dry_run,
>       ++		OPT_BOOL_F(0, "quiet",
>       ++			   &quiet,
>        +			   N_("suppress all output; only exit status wanted"),
>        +			   PARSE_OPT_NONEG),
>         		OPT_SET_INT('z', NULL, &line_termination,
>       @@ builtin/merge-tree.c: int cmd_merge_tree(int argc,
>         	argc = parse_options(argc, argv, prefix, mt_options,
>         			     merge_tree_usage, PARSE_OPT_STOP_AT_NON_OPTION);
>         
>       -+	if (dry_run && o.show_messages == -1)
>       ++	if (quiet && o.show_messages == -1)
>        +		o.show_messages = 0;
>       -+	o.merge_options.mergeability_only = dry_run;
>       -+	die_for_incompatible_opt2(dry_run, "--dry-run",
>       -+				  o.show_messages, "--messages");
>       -+	die_for_incompatible_opt2(dry_run, "--dry-run",
>       -+				  o.name_only, "--name-only");
>       -+	die_for_incompatible_opt2(dry_run, "--dry-run",
>       -+				  o.use_stdin, "--stdin");
>       -+	die_for_incompatible_opt2(dry_run, "--dry-run",
>       -+				  !line_termination, "-z");
>       ++	o.merge_options.mergeability_only = quiet;
>       ++	die_for_incompatible_opt2(quiet, "--quiet", o.show_messages, "--messages");
>       ++	die_for_incompatible_opt2(quiet, "--quiet", o.name_only, "--name-only");
>       ++	die_for_incompatible_opt2(quiet, "--quiet", o.use_stdin, "--stdin");
>       ++	die_for_incompatible_opt2(quiet, "--quiet", !line_termination, "-z");
>        +
>         	if (xopts.nr && o.mode == MODE_TRIVIAL)
>         		die(_("--trivial-merge is incompatible with all other options"));
>       @@ t/t4301-merge-tree-write-tree.sh: test_expect_success setup '
>         	git commit -m first-commit
>         '
>         
>       -+test_expect_success '--dry-run on clean merge' '
>       ++test_expect_success '--quiet on clean merge' '
>        +	# Get rid of loose objects to start with
>        +	git gc &&
>        +	echo "0 objects, 0 kilobytes" >expect &&
>       @@ t/t4301-merge-tree-write-tree.sh: test_expect_success setup '
>        +	test_cmp expect actual &&
>        +
>        +	# Ensure merge is successful (exit code of 0)
>       -+	git merge-tree --write-tree --dry-run side1 side3 >output &&
>       ++	git merge-tree --write-tree --quiet side1 side3 >output &&
>        +
>        +	# Ensure there is no output
>        +	test_must_be_empty output &&
>       @@ t/t4301-merge-tree-write-tree.sh: test_expect_success 'Failed merge without rena
>         	grep "CONFLICT (modify/delete): numbers deleted" out
>         '
>         
>       -+test_expect_success  '--dry-run on conflicted merge' '
>       ++test_expect_success  '--quiet on conflicted merge' '
>        +	# Get rid of loose objects to start with
>        +	git gc &&
>        +	echo "0 objects, 0 kilobytes" >expect &&
>       @@ t/t4301-merge-tree-write-tree.sh: test_expect_success 'Failed merge without rena
>        +	test_cmp expect actual &&
>        +
>        +	# Ensure merge has conflict
>       -+	test_expect_code 1 git merge-tree --write-tree --dry-run side1 side2 >output &&
>       ++	test_expect_code 1 git merge-tree --write-tree --quiet side1 side2 >output &&
>        +
>        +	# Ensure there is no output
>        +	test_must_be_empty output &&
>