merge: make branch.<name>.mergeoptions correctly override merge.<option>

The parsing of the additional command line parameters supplied to the branch.<name>.mergeoptions configuration variable was implemented at the wrong stage. If any merge-related variable came after we read branch.<name>.mergeoptions, the earlier value was overwritten. We should first read all the merge.* configuration, override them by reading from branch.<name>.mergeoptions and then finally read from the command line. 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... Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed May 4, 2011 at 17:42 UTC 0d8fc3efc65df74a2b39b3f9798861a1b2055b62
2 files changed +57 -14
builtin-merge.c
+25 -14
@@ -54,6 +54,7 @@ static size_t use_strategies_nr, use_strategies_alloc;
54 static const char **xopts;
55 static size_t xopts_nr, xopts_alloc;
56 static const char *branch;
57 +static char *branch_mergeoptions;
58 static int verbosity;
59 static int allow_rerere_auto;
60
@@ -474,25 +475,33 @@ cleanup:
475 strbuf_release(&bname);
476 }
477
478 +static void parse_branch_merge_options(char *bmo)
479 +{
480 + const char **argv;
481 + int argc;
482 +
483 + if (!bmo)
484 + return;
485 + argc = split_cmdline(bmo, &argv);
486 + if (argc < 0)
487 + die("Bad branch.%s.mergeoptions string", branch);
488 + argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
489 + memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
490 + argc++;
491 + argv[0] = "branch.*.mergeoptions";
492 + parse_options(argc, argv, NULL, builtin_merge_options,
493 + builtin_merge_usage, 0);
494 + free(argv);
495 +}
496 +
497 static int git_merge_config(const char *k, const char *v, void *cb)
498 {
499 if (branch && !prefixcmp(k, "branch.") &&
500 !prefixcmp(k + 7, branch) &&
501 !strcmp(k + 7 + strlen(branch), ".mergeoptions")) {
482 - const char **argv;
483 - int argc;
484 - char *buf;
485 -
486 - buf = xstrdup(v);
487 - argc = split_cmdline(buf, &argv);
488 - if (argc < 0)
489 - die("Bad branch.%s.mergeoptions string", branch);
490 - argv = xrealloc(argv, sizeof(*argv) * (argc + 2));
491 - memmove(argv + 1, argv, sizeof(*argv) * (argc + 1));
492 - argc++;
493 - parse_options(argc, argv, NULL, builtin_merge_options,
494 - builtin_merge_usage, 0);
495 - free(buf);
502 + free(branch_mergeoptions);
503 + branch_mergeoptions = xstrdup(v);
504 + return 0;
505 }
506
507 if (!strcmp(k, "merge.diffstat") || !strcmp(k, "merge.stat"))
@@ -918,6 +927,8 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
927 if (diff_use_color_default == -1)
928 diff_use_color_default = git_use_color_default;
929
930 + if (branch_mergeoptions)
931 + parse_branch_merge_options(branch_mergeoptions);
932 argc = parse_options(argc, argv, prefix, builtin_merge_options,
933 builtin_merge_usage, 0);
934 if (verbosity < 0)
t/t7600-merge.sh
+32
@@ -372,6 +372,38 @@ test_expect_success 'merge c1 with c2 (no-commit in config)' '
372
373 test_debug 'gitk --all'
374
375 +test_expect_success 'merge c1 with c2 (log in config)' '
376 + git config branch.master.mergeoptions "" &&
377 + git reset --hard c1 &&
378 + git merge --log c2 &&
379 + git show -s --pretty=tformat:%s%n%b >expect &&
380 +
381 + git config branch.master.mergeoptions --log &&
382 + git reset --hard c1 &&
383 + git merge c2 &&
384 + git show -s --pretty=tformat:%s%n%b >actual &&
385 +
386 + test_cmp expect actual
387 +'
388 +
389 +test_expect_success 'merge c1 with c2 (log in config gets overridden)' '
390 + (
391 + git config --remove-section branch.master
392 + git config --remove-section merge
393 + )
394 + git reset --hard c1 &&
395 + git merge c2 &&
396 + git show -s --pretty=tformat:%s%n%b >expect &&
397 +
398 + git config branch.master.mergeoptions "--no-log" &&
399 + git config merge.log true &&
400 + git reset --hard c1 &&
401 + git merge c2 &&
402 + git show -s --pretty=tformat:%s%n%b >actual &&
403 +
404 + test_cmp expect actual
405 +'
406 +
407 test_expect_success 'merge c1 with c2 (squash in config)' '
408 git reset --hard c1 &&
409 git config branch.master.mergeoptions "--squash" &&