merge-recursive: split internal fields into a separate struct

merge_options has several internal fields that should not be set or read by external callers. This just complicates the API. Move them into an opaque merge_options_internal struct that is defined only in merge-recursive.c and keep these out of merge-recursive.h. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Aug 17, 2019 at 11:41 UTC 5bf7e5779ec6d5293b3135554d49e6fcee88d399
2 files changed +105 -97
merge-recursive.c
+98 -87
@@ -29,6 +29,15 @@
29 #include "revision.h"
30 #include "commit-reach.h"
31
32 +struct merge_options_internal {
33 + int call_depth;
34 + int needed_rename_limit;
35 + struct hashmap current_file_dir_set;
36 + struct string_list df_conflict_file_set;
37 + struct unpack_trees_options unpack_opts;
38 + struct index_state orig_index;
39 +};
40 +
41 struct path_hashmap_entry {
42 struct hashmap_entry e;
43 char path[FLEX_ARRAY];
@@ -309,7 +318,8 @@ static inline void setup_rename_conflict_info(enum rename_type rename_type,
318
319 static int show(struct merge_options *opt, int v)
320 {
312 - return (!opt->call_depth && opt->verbosity >= v) || opt->verbosity >= 5;
321 + return (!opt->priv->call_depth && opt->verbosity >= v) ||
322 + opt->verbosity >= 5;
323 }
324
325 __attribute__((format (printf, 3, 4)))
@@ -320,7 +330,7 @@ static void output(struct merge_options *opt, int v, const char *fmt, ...)
330 if (!show(opt, v))
331 return;
332
323 - strbuf_addchars(&opt->obuf, ' ', opt->call_depth * 2);
333 + strbuf_addchars(&opt->obuf, ' ', opt->priv->call_depth * 2);
334
335 va_start(ap, fmt);
336 strbuf_vaddf(&opt->obuf, fmt, ap);
@@ -335,7 +345,7 @@ static void output_commit_title(struct merge_options *opt, struct commit *commit
345 {
346 struct merge_remote_desc *desc;
347
338 - strbuf_addchars(&opt->obuf, ' ', opt->call_depth * 2);
348 + strbuf_addchars(&opt->obuf, ' ', opt->priv->call_depth * 2);
349 desc = merge_remote_util(commit);
350 if (desc)
351 strbuf_addf(&opt->obuf, "virtual %s\n", desc->name);
@@ -403,43 +413,43 @@ static int unpack_trees_start(struct merge_options *opt,
413 struct tree_desc t[3];
414 struct index_state tmp_index = { NULL };
415
406 - memset(&opt->unpack_opts, 0, sizeof(opt->unpack_opts));
407 - if (opt->call_depth)
408 - opt->unpack_opts.index_only = 1;
416 + memset(&opt->priv->unpack_opts, 0, sizeof(opt->priv->unpack_opts));
417 + if (opt->priv->call_depth)
418 + opt->priv->unpack_opts.index_only = 1;
419 else
410 - opt->unpack_opts.update = 1;
411 - opt->unpack_opts.merge = 1;
412 - opt->unpack_opts.head_idx = 2;
413 - opt->unpack_opts.fn = threeway_merge;
414 - opt->unpack_opts.src_index = opt->repo->index;
415 - opt->unpack_opts.dst_index = &tmp_index;
416 - opt->unpack_opts.aggressive = !merge_detect_rename(opt);
417 - setup_unpack_trees_porcelain(&opt->unpack_opts, "merge");
420 + opt->priv->unpack_opts.update = 1;
421 + opt->priv->unpack_opts.merge = 1;
422 + opt->priv->unpack_opts.head_idx = 2;
423 + opt->priv->unpack_opts.fn = threeway_merge;
424 + opt->priv->unpack_opts.src_index = opt->repo->index;
425 + opt->priv->unpack_opts.dst_index = &tmp_index;
426 + opt->priv->unpack_opts.aggressive = !merge_detect_rename(opt);
427 + setup_unpack_trees_porcelain(&opt->priv->unpack_opts, "merge");
428
429 init_tree_desc_from_tree(t+0, common);
430 init_tree_desc_from_tree(t+1, head);
431 init_tree_desc_from_tree(t+2, merge);
432
423 - rc = unpack_trees(3, t, &opt->unpack_opts);
433 + rc = unpack_trees(3, t, &opt->priv->unpack_opts);
434 cache_tree_free(&opt->repo->index->cache_tree);
435
436 /*
427 - * Update opt->repo->index to match the new results, AFTER saving a copy
428 - * in opt->orig_index. Update src_index to point to the saved copy.
429 - * (verify_uptodate() checks src_index, and the original index is
430 - * the one that had the necessary modification timestamps.)
437 + * Update opt->repo->index to match the new results, AFTER saving a
438 + * copy in opt->priv->orig_index. Update src_index to point to the
439 + * saved copy. (verify_uptodate() checks src_index, and the original
440 + * index is the one that had the necessary modification timestamps.)
441 */
432 - opt->orig_index = *opt->repo->index;
442 + opt->priv->orig_index = *opt->repo->index;
443 *opt->repo->index = tmp_index;
434 - opt->unpack_opts.src_index = &opt->orig_index;
444 + opt->priv->unpack_opts.src_index = &opt->priv->orig_index;
445
446 return rc;
447 }
448
449 static void unpack_trees_finish(struct merge_options *opt)
450 {
441 - discard_index(&opt->orig_index);
442 - clear_unpack_trees_porcelain(&opt->unpack_opts);
451 + discard_index(&opt->priv->orig_index);
452 + clear_unpack_trees_porcelain(&opt->priv->unpack_opts);
453 }
454
455 static int save_files_dirs(const struct object_id *oid,
@@ -454,7 +464,7 @@ static int save_files_dirs(const struct object_id *oid,
464
465 FLEX_ALLOC_MEM(entry, path, base->buf, base->len);
466 hashmap_entry_init(entry, path_hash(entry->path));
457 - hashmap_add(&opt->current_file_dir_set, entry);
467 + hashmap_add(&opt->priv->current_file_dir_set, entry);
468
469 strbuf_setlen(base, baselen);
470 return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
@@ -585,7 +595,7 @@ static void record_df_conflict_files(struct merge_options *opt,
595 * If we're merging merge-bases, we don't want to bother with
596 * any working directory changes.
597 */
588 - if (opt->call_depth)
598 + if (opt->priv->call_depth)
599 return;
600
601 /* Ensure D/F conflicts are adjacent in the entries list. */
@@ -597,7 +607,7 @@ static void record_df_conflict_files(struct merge_options *opt,
607 df_sorted_entries.cmp = string_list_df_name_compare;
608 string_list_sort(&df_sorted_entries);
609
600 - string_list_clear(&opt->df_conflict_file_set, 1);
610 + string_list_clear(&opt->priv->df_conflict_file_set, 1);
611 for (i = 0; i < df_sorted_entries.nr; i++) {
612 const char *path = df_sorted_entries.items[i].string;
613 int len = strlen(path);
@@ -613,7 +623,7 @@ static void record_df_conflict_files(struct merge_options *opt,
623 len > last_len &&
624 memcmp(path, last_file, last_len) == 0 &&
625 path[last_len] == '/') {
616 - string_list_insert(&opt->df_conflict_file_set, last_file);
626 + string_list_insert(&opt->priv->df_conflict_file_set, last_file);
627 }
628
629 /*
@@ -680,8 +690,8 @@ static void update_entry(struct stage_data *entry,
690 static int remove_file(struct merge_options *opt, int clean,
691 const char *path, int no_wd)
692 {
683 - int update_cache = opt->call_depth || clean;
684 - int update_working_directory = !opt->call_depth && !no_wd;
693 + int update_cache = opt->priv->call_depth || clean;
694 + int update_working_directory = !opt->priv->call_depth && !no_wd;
695
696 if (update_cache) {
697 if (remove_file_from_index(opt->repo->index, path))
@@ -724,16 +734,16 @@ static char *unique_path(struct merge_options *opt,
734 add_flattened_path(&newpath, branch);
735
736 base_len = newpath.len;
727 - while (hashmap_get_from_hash(&opt->current_file_dir_set,
737 + while (hashmap_get_from_hash(&opt->priv->current_file_dir_set,
738 path_hash(newpath.buf), newpath.buf) ||
729 - (!opt->call_depth && file_exists(newpath.buf))) {
739 + (!opt->priv->call_depth && file_exists(newpath.buf))) {
740 strbuf_setlen(&newpath, base_len);
741 strbuf_addf(&newpath, "_%d", suffix++);
742 }
743
744 FLEX_ALLOC_MEM(entry, path, newpath.buf, newpath.len);
745 hashmap_entry_init(entry, path_hash(entry->path));
736 - hashmap_add(&opt->current_file_dir_set, entry);
746 + hashmap_add(&opt->priv->current_file_dir_set, entry);
747 return strbuf_detach(&newpath, NULL);
748 }
749
@@ -775,7 +785,7 @@ static int dir_in_way(struct index_state *istate, const char *path,
785 static int was_tracked_and_matches(struct merge_options *opt, const char *path,
786 const struct diff_filespec *blob)
787 {
778 - int pos = index_name_pos(&opt->orig_index, path, strlen(path));
788 + int pos = index_name_pos(&opt->priv->orig_index, path, strlen(path));
789 struct cache_entry *ce;
790
791 if (0 > pos)
@@ -783,7 +793,7 @@ static int was_tracked_and_matches(struct merge_options *opt, const char *path,
793 return 0;
794
795 /* See if the file we were tracking before matches */
786 - ce = opt->orig_index.cache[pos];
796 + ce = opt->priv->orig_index.cache[pos];
797 return (oid_eq(&ce->oid, &blob->oid) && ce->ce_mode == blob->mode);
798 }
799
@@ -792,7 +802,7 @@ static int was_tracked_and_matches(struct merge_options *opt, const char *path,
802 */
803 static int was_tracked(struct merge_options *opt, const char *path)
804 {
795 - int pos = index_name_pos(&opt->orig_index, path, strlen(path));
805 + int pos = index_name_pos(&opt->priv->orig_index, path, strlen(path));
806
807 if (0 <= pos)
808 /* we were tracking this path before the merge */
@@ -849,12 +859,12 @@ static int was_dirty(struct merge_options *opt, const char *path)
859 struct cache_entry *ce;
860 int dirty = 1;
861
852 - if (opt->call_depth || !was_tracked(opt, path))
862 + if (opt->priv->call_depth || !was_tracked(opt, path))
863 return !dirty;
864
855 - ce = index_file_exists(opt->unpack_opts.src_index,
865 + ce = index_file_exists(opt->priv->unpack_opts.src_index,
866 path, strlen(path), ignore_case);
857 - dirty = verify_uptodate(ce, &opt->unpack_opts) != 0;
867 + dirty = verify_uptodate(ce, &opt->priv->unpack_opts) != 0;
868 return dirty;
869 }
870
@@ -864,8 +874,8 @@ static int make_room_for_path(struct merge_options *opt, const char *path)
874 const char *msg = _("failed to create path '%s'%s");
875
876 /* Unlink any D/F conflict files that are in the way */
867 - for (i = 0; i < opt->df_conflict_file_set.nr; i++) {
868 - const char *df_path = opt->df_conflict_file_set.items[i].string;
877 + for (i = 0; i < opt->priv->df_conflict_file_set.nr; i++) {
878 + const char *df_path = opt->priv->df_conflict_file_set.items[i].string;
879 size_t pathlen = strlen(path);
880 size_t df_pathlen = strlen(df_path);
881 if (df_pathlen < pathlen &&
@@ -875,7 +885,7 @@ static int make_room_for_path(struct merge_options *opt, const char *path)
885 _("Removing %s to make room for subdirectory\n"),
886 df_path);
887 unlink(df_path);
878 - unsorted_string_list_delete_item(&opt->df_conflict_file_set,
888 + unsorted_string_list_delete_item(&opt->priv->df_conflict_file_set,
889 i, 0);
890 break;
891 }
@@ -916,7 +926,7 @@ static int update_file_flags(struct merge_options *opt,
926 {
927 int ret = 0;
928
919 - if (opt->call_depth)
929 + if (opt->priv->call_depth)
930 update_wd = 0;
931
932 if (update_wd) {
@@ -1001,7 +1011,7 @@ static int update_file(struct merge_options *opt,
1011 const char *path)
1012 {
1013 return update_file_flags(opt, contents, path,
1004 - opt->call_depth || clean, !opt->call_depth);
1014 + opt->priv->call_depth || clean, !opt->priv->call_depth);
1015 }
1016
1017 /* Low level file merging, update and removal */
@@ -1030,7 +1040,7 @@ static int merge_3way(struct merge_options *opt,
1040 ll_opts.extra_marker_size = extra_marker_size;
1041 ll_opts.xdl_opts = opt->xdl_opts;
1042
1033 - if (opt->call_depth) {
1043 + if (opt->priv->call_depth) {
1044 ll_opts.virtual_ancestor = 1;
1045 ll_opts.variant = 0;
1046 } else {
@@ -1161,7 +1171,7 @@ static int merge_submodule(struct merge_options *opt,
1171 struct object_array merges;
1172
1173 int i;
1164 - int search = !opt->call_depth;
1174 + int search = !opt->priv->call_depth;
1175
1176 /* store a in result in case we fail */
1177 oidcpy(result, a);
@@ -1383,7 +1393,7 @@ static int handle_rename_via_dir(struct merge_options *opt,
1393 MERGE_DIRECTORY_RENAMES_CONFLICT);
1394 assert(ren->dir_rename_original_dest);
1395
1386 - if (!opt->call_depth && would_lose_untracked(opt, dest->path)) {
1396 + if (!opt->priv->call_depth && would_lose_untracked(opt, dest->path)) {
1397 mark_conflicted = 1;
1398 file_path = unique_path(opt, dest->path, ren->branch);
1399 output(opt, 1, _("Error: Refusing to lose untracked file at %s; "
@@ -1426,12 +1436,12 @@ static int handle_change_delete(struct merge_options *opt,
1436 const char *update_path = path;
1437 int ret = 0;
1438
1429 - if (dir_in_way(opt->repo->index, path, !opt->call_depth, 0) ||
1430 - (!opt->call_depth && would_lose_untracked(opt, path))) {
1439 + if (dir_in_way(opt->repo->index, path, !opt->priv->call_depth, 0) ||
1440 + (!opt->priv->call_depth && would_lose_untracked(opt, path))) {
1441 update_path = alt_path = unique_path(opt, path, change_branch);
1442 }
1443
1434 - if (opt->call_depth) {
1444 + if (opt->priv->call_depth) {
1445 /*
1446 * We cannot arbitrarily accept either a_sha or b_sha as
1447 * correct; since there is no true "middle point" between
@@ -1506,14 +1516,14 @@ static int handle_rename_delete(struct merge_options *opt,
1516 opt->branch2 : opt->branch1);
1517
1518 if (handle_change_delete(opt,
1509 - opt->call_depth ? orig->path : dest->path,
1510 - opt->call_depth ? NULL : orig->path,
1519 + opt->priv->call_depth ? orig->path : dest->path,
1520 + opt->priv->call_depth ? NULL : orig->path,
1521 orig, dest,
1522 rename_branch, delete_branch,
1523 _("rename"), _("renamed")))
1524 return -1;
1525
1516 - if (opt->call_depth)
1526 + if (opt->priv->call_depth)
1527 return remove_file_from_index(opt->repo->index, dest->path);
1528 else
1529 return update_stages(opt, dest->path, NULL,
@@ -1550,7 +1560,7 @@ static int handle_file_collision(struct merge_options *opt,
1560 /*
1561 * In the recursive case, we just opt to undo renames
1562 */
1553 - if (opt->call_depth && (prev_path1 || prev_path2)) {
1563 + if (opt->priv->call_depth && (prev_path1 || prev_path2)) {
1564 /* Put first file (a->oid, a->mode) in its original spot */
1565 if (prev_path1) {
1566 if (update_file(opt, 1, a, prev_path1))
@@ -1579,10 +1589,10 @@ static int handle_file_collision(struct merge_options *opt,
1589 /* Remove rename sources if rename/add or rename/rename(2to1) */
1590 if (prev_path1)
1591 remove_file(opt, 1, prev_path1,
1582 - opt->call_depth || would_lose_untracked(opt, prev_path1));
1592 + opt->priv->call_depth || would_lose_untracked(opt, prev_path1));
1593 if (prev_path2)
1594 remove_file(opt, 1, prev_path2,
1585 - opt->call_depth || would_lose_untracked(opt, prev_path2));
1595 + opt->priv->call_depth || would_lose_untracked(opt, prev_path2));
1596
1597 /*
1598 * Remove the collision path, if it wouldn't cause dirty contents
@@ -1624,12 +1634,12 @@ static int handle_file_collision(struct merge_options *opt,
1634 null.mode = 0;
1635
1636 if (merge_mode_and_contents(opt, &null, a, b, collide_path,
1627 - branch1, branch2, opt->call_depth * 2, &mfi))
1637 + branch1, branch2, opt->priv->call_depth * 2, &mfi))
1638 return -1;
1639 mfi.clean &= !alt_path;
1640 if (update_file(opt, mfi.clean, &mfi.blob, update_path))
1641 return -1;
1632 - if (!mfi.clean && !opt->call_depth &&
1642 + if (!mfi.clean && !opt->priv->call_depth &&
1643 update_stages(opt, collide_path, NULL, a, b))
1644 return -1;
1645 free(alt_path);
@@ -1669,7 +1679,7 @@ static int handle_rename_add(struct merge_options *opt,
1679 &ci->ren1->src_entry->stages[other_stage],
1680 prev_path_desc,
1681 opt->branch1, opt->branch2,
1672 - 1 + opt->call_depth * 2, &mfi))
1682 + 1 + opt->priv->call_depth * 2, &mfi))
1683 return -1;
1684 free(prev_path_desc);
1685
@@ -1687,7 +1697,7 @@ static char *find_path_for_conflict(struct merge_options *opt,
1697 const char *branch2)
1698 {
1699 char *new_path = NULL;
1690 - if (dir_in_way(opt->repo->index, path, !opt->call_depth, 0)) {
1700 + if (dir_in_way(opt->repo->index, path, !opt->priv->call_depth, 0)) {
1701 new_path = unique_path(opt, path, branch1);
1702 output(opt, 1, _("%s is a directory in %s adding "
1703 "as %s instead"),
@@ -1718,17 +1728,17 @@ static int handle_rename_rename_1to2(struct merge_options *opt,
1728 "rename \"%s\"->\"%s\" in \"%s\"%s"),
1729 o->path, a->path, ci->ren1->branch,
1730 o->path, b->path, ci->ren2->branch,
1721 - opt->call_depth ? _(" (left unresolved)") : "");
1731 + opt->priv->call_depth ? _(" (left unresolved)") : "");
1732
1733 path_desc = xstrfmt("%s and %s, both renamed from %s",
1734 a->path, b->path, o->path);
1735 if (merge_mode_and_contents(opt, o, a, b, path_desc,
1736 ci->ren1->branch, ci->ren2->branch,
1727 - opt->call_depth * 2, &mfi))
1737 + opt->priv->call_depth * 2, &mfi))
1738 return -1;
1739 free(path_desc);
1740
1731 - if (opt->call_depth) {
1741 + if (opt->priv->call_depth) {
1742 /*
1743 * FIXME: For rename/add-source conflicts (if we could detect
1744 * such), this is wrong. We should instead find a unique
@@ -1843,12 +1853,12 @@ static int handle_rename_rename_2to1(struct merge_options *opt,
1853 &ci->ren1->src_entry->stages[ostage1],
1854 path_side_1_desc,
1855 opt->branch1, opt->branch2,
1846 - 1 + opt->call_depth * 2, &mfi_c1) ||
1856 + 1 + opt->priv->call_depth * 2, &mfi_c1) ||
1857 merge_mode_and_contents(opt, b,
1858 &ci->ren2->src_entry->stages[ostage2],
1859 c2, path_side_2_desc,
1860 opt->branch1, opt->branch2,
1851 - 1 + opt->call_depth * 2, &mfi_c2))
1861 + 1 + opt->priv->call_depth * 2, &mfi_c2))
1862 return -1;
1863 free(path_side_1_desc);
1864 free(path_side_2_desc);
@@ -1889,8 +1899,8 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *opt,
1899 diff_setup_done(&opts);
1900 diff_tree_oid(&o_tree->object.oid, &tree->object.oid, "", &opts);
1901 diffcore_std(&opts);
1892 - if (opts.needed_rename_limit > opt->needed_rename_limit)
1893 - opt->needed_rename_limit = opts.needed_rename_limit;
1902 + if (opts.needed_rename_limit > opt->priv->needed_rename_limit)
1903 + opt->priv->needed_rename_limit = opts.needed_rename_limit;
1904
1905 ret = xmalloc(sizeof(*ret));
1906 *ret = diff_queued_diff;
@@ -2865,7 +2875,7 @@ static int detect_and_process_renames(struct merge_options *opt,
2875
2876 if ((opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_TRUE) ||
2877 (opt->detect_directory_renames == MERGE_DIRECTORY_RENAMES_CONFLICT &&
2868 - !opt->call_depth)) {
2878 + !opt->priv->call_depth)) {
2879 dir_re_head = get_directory_renames(head_pairs);
2880 dir_re_merge = get_directory_renames(merge_pairs);
2881
@@ -3022,13 +3032,13 @@ static int handle_content_merge(struct merge_file_info *mfi,
3032 reason = _("add/add");
3033
3034 assert(o->path && a->path && b->path);
3025 - if (ci && dir_in_way(opt->repo->index, path, !opt->call_depth,
3035 + if (ci && dir_in_way(opt->repo->index, path, !opt->priv->call_depth,
3036 S_ISGITLINK(ci->ren1->pair->two->mode)))
3037 df_conflict_remains = 1;
3038
3039 if (merge_mode_and_contents(opt, o, a, b, path,
3040 opt->branch1, opt->branch2,
3031 - opt->call_depth * 2, mfi))
3041 + opt->priv->call_depth * 2, mfi))
3042 return -1;
3043
3044 /*
@@ -3044,7 +3054,7 @@ static int handle_content_merge(struct merge_file_info *mfi,
3054
3055 output(opt, 3, _("Skipped %s (merged same as existing)"), path);
3056 if (add_cacheinfo(opt, &mfi->blob, path,
3047 - 0, (!opt->call_depth && !is_dirty), 0))
3057 + 0, (!opt->priv->call_depth && !is_dirty), 0))
3058 return -1;
3059 /*
3060 * However, add_cacheinfo() will delete the old cache entry
@@ -3052,8 +3062,8 @@ static int handle_content_merge(struct merge_file_info *mfi,
3062 * flag to avoid making the file appear as if it were
3063 * deleted by the user.
3064 */
3055 - pos = index_name_pos(&opt->orig_index, path, strlen(path));
3056 - ce = opt->orig_index.cache[pos];
3065 + pos = index_name_pos(&opt->priv->orig_index, path, strlen(path));
3066 + ce = opt->priv->orig_index.cache[pos];
3067 if (ce_skip_worktree(ce)) {
3068 pos = index_name_pos(opt->repo->index, path, strlen(path));
3069 ce = opt->repo->index->cache[pos];
@@ -3074,7 +3084,7 @@ static int handle_content_merge(struct merge_file_info *mfi,
3084
3085 if (df_conflict_remains || is_dirty) {
3086 char *new_path;
3077 - if (opt->call_depth) {
3087 + if (opt->priv->call_depth) {
3088 remove_file_from_index(opt->repo->index, path);
3089 } else {
3090 if (!mfi->clean) {
@@ -3333,7 +3343,7 @@ static int process_entry(struct merge_options *opt,
3343 conf = _("directory/file");
3344 }
3345 if (dir_in_way(opt->repo->index, path,
3336 - !opt->call_depth && !S_ISGITLINK(a->mode),
3346 + !opt->priv->call_depth && !S_ISGITLINK(a->mode),
3347 0)) {
3348 char *new_path = unique_path(opt, path, add_branch);
3349 clean_merge = 0;
@@ -3342,7 +3352,7 @@ static int process_entry(struct merge_options *opt,
3352 conf, path, other_branch, path, new_path);
3353 if (update_file(opt, 0, contents, new_path))
3354 clean_merge = -1;
3345 - else if (opt->call_depth)
3355 + else if (opt->priv->call_depth)
3356 remove_file_from_index(opt->repo->index, path);
3357 free(new_path);
3358 } else {
@@ -3407,7 +3417,7 @@ static int merge_trees_internal(struct merge_options *opt,
3417 code = unpack_trees_start(opt, merge_base, head, merge);
3418
3419 if (code != 0) {
3410 - if (show(opt, 4) || opt->call_depth)
3420 + if (show(opt, 4) || opt->priv->call_depth)
3421 err(opt, _("merging of trees %s and %s failed"),
3422 oid_to_hex(&head->object.oid),
3423 oid_to_hex(&merge->object.oid));
@@ -3426,7 +3436,7 @@ static int merge_trees_internal(struct merge_options *opt,
3436 * opposed to decaring a local hashmap is for convenience
3437 * so that we don't have to pass it to around.
3438 */
3429 - hashmap_init(&opt->current_file_dir_set, path_hashmap_cmp,
3439 + hashmap_init(&opt->priv->current_file_dir_set, path_hashmap_cmp,
3440 NULL, 512);
3441 get_files_dirs(opt, head);
3442 get_files_dirs(opt, merge);
@@ -3463,7 +3473,7 @@ static int merge_trees_internal(struct merge_options *opt,
3473 string_list_clear(entries, 1);
3474 free(entries);
3475
3466 - hashmap_free(&opt->current_file_dir_set, 1);
3476 + hashmap_free(&opt->priv->current_file_dir_set, 1);
3477
3478 if (clean < 0) {
3479 unpack_trees_finish(opt);
@@ -3475,7 +3485,7 @@ static int merge_trees_internal(struct merge_options *opt,
3485
3486 unpack_trees_finish(opt);
3487
3478 - if (opt->call_depth &&
3488 + if (opt->priv->call_depth &&
3489 !(*result = write_in_core_index_as_tree(opt->repo)))
3490 return -1;
3491
@@ -3550,7 +3560,7 @@ static int merge_recursive_internal(struct merge_options *opt,
3560
3561 for (iter = merge_bases; iter; iter = iter->next) {
3562 const char *saved_b1, *saved_b2;
3553 - opt->call_depth++;
3563 + opt->priv->call_depth++;
3564 /*
3565 * When the merge fails, the result contains files
3566 * with conflict markers. The cleanness flag is
@@ -3569,14 +3579,14 @@ static int merge_recursive_internal(struct merge_options *opt,
3579 return -1;
3580 opt->branch1 = saved_b1;
3581 opt->branch2 = saved_b2;
3572 - opt->call_depth--;
3582 + opt->priv->call_depth--;
3583
3584 if (!merged_merge_bases)
3585 return err(opt, _("merge returned no commit"));
3586 }
3587
3588 discard_index(opt->repo->index);
3579 - if (!opt->call_depth)
3589 + if (!opt->priv->call_depth)
3590 repo_read_index(opt->repo);
3591
3592 opt->ancestor = ancestor_name;
@@ -3592,7 +3602,7 @@ static int merge_recursive_internal(struct merge_options *opt,
3602 return clean;
3603 }
3604
3595 - if (opt->call_depth) {
3605 + if (opt->priv->call_depth) {
3606 *result = make_virtual_commit(opt->repo, result_tree,
3607 "merged tree");
3608 commit_list_insert(h1, &(*result)->parents);
@@ -3612,17 +3622,20 @@ static int merge_start(struct merge_options *opt, struct tree *head)
3622 return -1;
3623 }
3624
3625 + opt->priv = xcalloc(1, sizeof(*opt->priv));
3626 + string_list_init(&opt->priv->df_conflict_file_set, 1);
3627 return 0;
3628 }
3629
3630 static void merge_finalize(struct merge_options *opt)
3631 {
3632 flush_output(opt);
3621 - if (!opt->call_depth && opt->buffer_output < 2)
3633 + if (!opt->priv->call_depth && opt->buffer_output < 2)
3634 strbuf_release(&opt->obuf);
3635 if (show(opt, 2))
3636 diff_warn_rename_limit("merge.renamelimit",
3625 - opt->needed_rename_limit, 0);
3637 + opt->priv->needed_rename_limit, 0);
3638 + FREE_AND_NULL(opt->priv);
3639 }
3640
3641 int merge_trees(struct merge_options *opt,
@@ -3767,8 +3780,6 @@ void init_merge_options(struct merge_options *opt,
3780
3781 opt->renormalize = 0;
3782
3770 - string_list_init(&opt->df_conflict_file_set, 1);
3771 -
3783 merge_recursive_config(opt);
3784 merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
3785 if (merge_verbosity)
merge-recursive.h
+7 -10
@@ -1,13 +1,15 @@
1 #ifndef MERGE_RECURSIVE_H
2 #define MERGE_RECURSIVE_H
3
4 -#include "string-list.h"
5 -#include "unpack-trees.h"
4 +#include "strbuf.h"
5
6 struct commit;
8 -
7 +struct commit_list;
8 +struct object_id;
9 struct repository;
10 +struct tree;
11
12 +struct merge_options_internal;
13 struct merge_options {
14 struct repository *repo;
15
@@ -45,13 +47,8 @@ struct merge_options {
47 const char *subtree_shift;
48 unsigned renormalize : 1;
49
48 - /* internal fields used by the implementation (do NOT set these) */
49 - int call_depth;
50 - int needed_rename_limit;
51 - struct hashmap current_file_dir_set;
52 - struct string_list df_conflict_file_set;
53 - struct unpack_trees_options unpack_opts;
54 - struct index_state orig_index;
50 + /* internal fields used by the implementation */
51 + struct merge_options_internal *priv;
52 };
53
54 void init_merge_options(struct merge_options *opt, struct repository *repo);