Subject: Re: [PATCH v5] Add default merge options for all branches

From: Jonathan Nieder <[email-masked]>
Date: Fri, 6 May 2011 16:32:57 -0500

Junio C Hamano wrote:

> Subject: [PATCH] merge: fix branch.<name>.mergeoptions

To be more precise, if I understand correctly:

	merge: allow branch.<name>.mergeoptions to override merge.*

> This patch should fix it, even though I now strongly suspect that
> branch.<name>.mergeoptions that gives a single command line that
> needs to be parsed was likely to be an ill-conceived idea to begin
> with.  Sigh...

Yes, and introducing branch.<name>.ff and branch.<name>.log might
still be a good idea.

The patch looks mostly good.  I see only one actual problem, marked
with [*] below.

> --- a/builtin-merge.c
> +++ b/builtin-merge.c
> @@ -54,6 +54,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
>  static const char **xopts;
>  static size_t xopts_nr, xopts_alloc;
>  static const char *branch;
> +static char *branch_mergeoptions;
>  static int verbosity;
>  static int allow_rerere_auto;
>  
> @@ -474,25 +475,33 @@ cleanup:
>  	strbuf_release(&bname);
>  }
>  
> +static void parse_branch_merge_options(char *bmo)
> +{
> +	const char **argv;
> +	int argc;
> +	char *buf;
> +
> +	if (!bmo)
> +		return;
> +	argc = split_cmdline(bmo, &argv);
> +	if (argc < 0)
> +		die("Bad branch.%s.mergeoptions string", branch);
> +	argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
> +	memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));

This is not new code, but it might make sense to do

	argv[0] = "merge.*.options";

for a saner error message when someone tries

	[branch "master"]
		mergeoptions = --nonsense

> +	argc++;
> +	parse_options(argc, argv, NULL, builtin_merge_options,
> +		      builtin_merge_usage, 0);
> +	free(buf);

[*]
This buf seems to be left over.  (I don't think the intent is to
call free on an uninitialized pointer. ;-))

[...]
> -		free(buf);
> +		free(branch_mergeoptions);
> +		branch_mergeoptions = xstrdup(v);

It is tempting to do

	size_t len;

	len = strlen(v);
	branch_mergeoptions = xrealloc(branch_mergeoptions, len + 1);
	memcpy(branch_mergeoptions, v, len + 1);

but free + xstrdup is simpler and clearer.  Makes sense.

> +test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
> +	(
> +		git config --remove-section branch.master
> +		git config --remove-section merge
> +	)

Since this patch is meant to apply to a very old git, we cannot use
test_might_fail.  Makes sense: it can be fixed up later to use
&&-friendly syntax as part of a series introducing checks to make
sure we don't regress in that.

Thanks and hope that helps,
Jonathan