|
26 | 26 | #include "cache-tree.h"
|
27 | 27 | #include "commit.h"
|
28 | 28 | #include "commit-reach.h"
|
| 29 | +#include "config.h" |
29 | 30 | #include "diff.h"
|
30 | 31 | #include "diffcore.h"
|
31 | 32 | #include "dir.h"
|
@@ -5322,3 +5323,161 @@ void merge_incore_recursive(struct merge_options *opt,
|
5322 | 5323 | merge_ort_internal(opt, merge_bases, side1, side2, result);
|
5323 | 5324 | trace2_region_leave("merge", "incore_recursive", opt->repo);
|
5324 | 5325 | }
|
| 5326 | + |
| 5327 | +static void merge_recursive_config(struct merge_options *opt, int ui) |
| 5328 | +{ |
| 5329 | + char *value = NULL; |
| 5330 | + int renormalize = 0; |
| 5331 | + git_config_get_int("merge.verbosity", &opt->verbosity); |
| 5332 | + git_config_get_int("diff.renamelimit", &opt->rename_limit); |
| 5333 | + git_config_get_int("merge.renamelimit", &opt->rename_limit); |
| 5334 | + git_config_get_bool("merge.renormalize", &renormalize); |
| 5335 | + opt->renormalize = renormalize; |
| 5336 | + if (!git_config_get_string("diff.renames", &value)) { |
| 5337 | + opt->detect_renames = git_config_rename("diff.renames", value); |
| 5338 | + free(value); |
| 5339 | + } |
| 5340 | + if (!git_config_get_string("merge.renames", &value)) { |
| 5341 | + opt->detect_renames = git_config_rename("merge.renames", value); |
| 5342 | + free(value); |
| 5343 | + } |
| 5344 | + if (!git_config_get_string("merge.directoryrenames", &value)) { |
| 5345 | + int boolval = git_parse_maybe_bool(value); |
| 5346 | + if (0 <= boolval) { |
| 5347 | + opt->detect_directory_renames = boolval ? |
| 5348 | + MERGE_DIRECTORY_RENAMES_TRUE : |
| 5349 | + MERGE_DIRECTORY_RENAMES_NONE; |
| 5350 | + } else if (!strcasecmp(value, "conflict")) { |
| 5351 | + opt->detect_directory_renames = |
| 5352 | + MERGE_DIRECTORY_RENAMES_CONFLICT; |
| 5353 | + } /* avoid erroring on values from future versions of git */ |
| 5354 | + free(value); |
| 5355 | + } |
| 5356 | + if (ui) { |
| 5357 | + if (!git_config_get_string("diff.algorithm", &value)) { |
| 5358 | + long diff_algorithm = parse_algorithm_value(value); |
| 5359 | + if (diff_algorithm < 0) |
| 5360 | + die(_("unknown value for config '%s': %s"), "diff.algorithm", value); |
| 5361 | + opt->xdl_opts = (opt->xdl_opts & ~XDF_DIFF_ALGORITHM_MASK) | diff_algorithm; |
| 5362 | + free(value); |
| 5363 | + } |
| 5364 | + } |
| 5365 | + git_config(git_xmerge_config, NULL); |
| 5366 | +} |
| 5367 | + |
| 5368 | +static void init_merge_options(struct merge_options *opt, |
| 5369 | + struct repository *repo, int ui) |
| 5370 | +{ |
| 5371 | + const char *merge_verbosity; |
| 5372 | + memset(opt, 0, sizeof(struct merge_options)); |
| 5373 | + |
| 5374 | + opt->repo = repo; |
| 5375 | + |
| 5376 | + opt->detect_renames = -1; |
| 5377 | + opt->detect_directory_renames = MERGE_DIRECTORY_RENAMES_CONFLICT; |
| 5378 | + opt->rename_limit = -1; |
| 5379 | + |
| 5380 | + opt->verbosity = 2; |
| 5381 | + opt->buffer_output = 1; |
| 5382 | + strbuf_init(&opt->obuf, 0); |
| 5383 | + |
| 5384 | + opt->renormalize = 0; |
| 5385 | + |
| 5386 | + opt->conflict_style = -1; |
| 5387 | + opt->xdl_opts = DIFF_WITH_ALG(opt, HISTOGRAM_DIFF); |
| 5388 | + |
| 5389 | + merge_recursive_config(opt, ui); |
| 5390 | + merge_verbosity = getenv("GIT_MERGE_VERBOSITY"); |
| 5391 | + if (merge_verbosity) |
| 5392 | + opt->verbosity = strtol(merge_verbosity, NULL, 10); |
| 5393 | + if (opt->verbosity >= 5) |
| 5394 | + opt->buffer_output = 0; |
| 5395 | +} |
| 5396 | + |
| 5397 | +void init_ui_merge_options(struct merge_options *opt, |
| 5398 | + struct repository *repo) |
| 5399 | +{ |
| 5400 | + init_merge_options(opt, repo, 1); |
| 5401 | +} |
| 5402 | + |
| 5403 | +void init_basic_merge_options(struct merge_options *opt, |
| 5404 | + struct repository *repo) |
| 5405 | +{ |
| 5406 | + init_merge_options(opt, repo, 0); |
| 5407 | +} |
| 5408 | + |
| 5409 | +/* |
| 5410 | + * For now, members of merge_options do not need deep copying, but |
| 5411 | + * it may change in the future, in which case we would need to update |
| 5412 | + * this, and also make a matching change to clear_merge_options() to |
| 5413 | + * release the resources held by a copied instance. |
| 5414 | + */ |
| 5415 | +void copy_merge_options(struct merge_options *dst, struct merge_options *src) |
| 5416 | +{ |
| 5417 | + *dst = *src; |
| 5418 | +} |
| 5419 | + |
| 5420 | +void clear_merge_options(struct merge_options *opt UNUSED) |
| 5421 | +{ |
| 5422 | + ; /* no-op as our copy is shallow right now */ |
| 5423 | +} |
| 5424 | + |
| 5425 | +int parse_merge_opt(struct merge_options *opt, const char *s) |
| 5426 | +{ |
| 5427 | + const char *arg; |
| 5428 | + |
| 5429 | + if (!s || !*s) |
| 5430 | + return -1; |
| 5431 | + if (!strcmp(s, "ours")) |
| 5432 | + opt->recursive_variant = MERGE_VARIANT_OURS; |
| 5433 | + else if (!strcmp(s, "theirs")) |
| 5434 | + opt->recursive_variant = MERGE_VARIANT_THEIRS; |
| 5435 | + else if (!strcmp(s, "subtree")) |
| 5436 | + opt->subtree_shift = ""; |
| 5437 | + else if (skip_prefix(s, "subtree=", &arg)) |
| 5438 | + opt->subtree_shift = arg; |
| 5439 | + else if (!strcmp(s, "patience")) |
| 5440 | + opt->xdl_opts = DIFF_WITH_ALG(opt, PATIENCE_DIFF); |
| 5441 | + else if (!strcmp(s, "histogram")) |
| 5442 | + opt->xdl_opts = DIFF_WITH_ALG(opt, HISTOGRAM_DIFF); |
| 5443 | + else if (skip_prefix(s, "diff-algorithm=", &arg)) { |
| 5444 | + long value = parse_algorithm_value(arg); |
| 5445 | + if (value < 0) |
| 5446 | + return -1; |
| 5447 | + /* clear out previous settings */ |
| 5448 | + DIFF_XDL_CLR(opt, NEED_MINIMAL); |
| 5449 | + opt->xdl_opts &= ~XDF_DIFF_ALGORITHM_MASK; |
| 5450 | + opt->xdl_opts |= value; |
| 5451 | + } |
| 5452 | + else if (!strcmp(s, "ignore-space-change")) |
| 5453 | + DIFF_XDL_SET(opt, IGNORE_WHITESPACE_CHANGE); |
| 5454 | + else if (!strcmp(s, "ignore-all-space")) |
| 5455 | + DIFF_XDL_SET(opt, IGNORE_WHITESPACE); |
| 5456 | + else if (!strcmp(s, "ignore-space-at-eol")) |
| 5457 | + DIFF_XDL_SET(opt, IGNORE_WHITESPACE_AT_EOL); |
| 5458 | + else if (!strcmp(s, "ignore-cr-at-eol")) |
| 5459 | + DIFF_XDL_SET(opt, IGNORE_CR_AT_EOL); |
| 5460 | + else if (!strcmp(s, "renormalize")) |
| 5461 | + opt->renormalize = 1; |
| 5462 | + else if (!strcmp(s, "no-renormalize")) |
| 5463 | + opt->renormalize = 0; |
| 5464 | + else if (!strcmp(s, "no-renames")) |
| 5465 | + opt->detect_renames = 0; |
| 5466 | + else if (!strcmp(s, "find-renames")) { |
| 5467 | + opt->detect_renames = 1; |
| 5468 | + opt->rename_score = 0; |
| 5469 | + } |
| 5470 | + else if (skip_prefix(s, "find-renames=", &arg) || |
| 5471 | + skip_prefix(s, "rename-threshold=", &arg)) { |
| 5472 | + if ((opt->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0) |
| 5473 | + return -1; |
| 5474 | + opt->detect_renames = 1; |
| 5475 | + } |
| 5476 | + /* |
| 5477 | + * Please update $__git_merge_strategy_options in |
| 5478 | + * git-completion.bash when you add new options |
| 5479 | + */ |
| 5480 | + else |
| 5481 | + return -1; |
| 5482 | + return 0; |
| 5483 | +} |
0 commit comments