merge-recursive: introduce new functions to handle rename logic

The amount of logic in merge_trees() relative to renames was just a few lines, but split it out into new handle_renames() and cleanup_renames() functions to prepare for additional logic to be added to each. No code or logic changes, just a new place to put stuff for when the rename detection gains additional checks. Note that process_renames() records pointers to various information (such as diff_filepairs) into rename_conflict_info structs. Even though the rename string_lists are not directly used once handle_renames() completes, we should not immediately free the lists at the end of that function because they store the information referenced in the rename_conflict_info, which is used later in process_entry(). Thus the reason for a separate cleanup_renames(). Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Feb 14, 2018 at 10:51 UTC 2dd6f8aa8495d30c9b16ed361c0b280bbed4bc14
1 file changed +33 -10
merge-recursive.c
+33 -10
@@ -1636,6 +1636,32 @@ cleanup_and_return:
1636 return clean_merge;
1637 }
1638
1639 +struct rename_info {
1640 + struct string_list *head_renames;
1641 + struct string_list *merge_renames;
1642 +};
1643 +
1644 +static int handle_renames(struct merge_options *o,
1645 + struct tree *common,
1646 + struct tree *head,
1647 + struct tree *merge,
1648 + struct string_list *entries,
1649 + struct rename_info *ri)
1650 +{
1651 + ri->head_renames = get_renames(o, head, common, head, merge, entries);
1652 + ri->merge_renames = get_renames(o, merge, common, head, merge, entries);
1653 + return process_renames(o, ri->head_renames, ri->merge_renames);
1654 +}
1655 +
1656 +static void cleanup_renames(struct rename_info *re_info)
1657 +{
1658 + string_list_clear(re_info->head_renames, 0);
1659 + string_list_clear(re_info->merge_renames, 0);
1660 +
1661 + free(re_info->head_renames);
1662 + free(re_info->merge_renames);
1663 +}
1664 +
1665 static struct object_id *stage_oid(const struct object_id *oid, unsigned mode)
1666 {
1667 return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid;
@@ -1995,7 +2021,8 @@ int merge_trees(struct merge_options *o,
2021 }
2022
2023 if (unmerged_cache()) {
1998 - struct string_list *entries, *re_head, *re_merge;
2024 + struct string_list *entries;
2025 + struct rename_info re_info;
2026 int i;
2027 /*
2028 * Only need the hashmap while processing entries, so
@@ -2009,9 +2036,8 @@ int merge_trees(struct merge_options *o,
2036 get_files_dirs(o, merge);
2037
2038 entries = get_unmerged();
2012 - re_head = get_renames(o, head, common, head, merge, entries);
2013 - re_merge = get_renames(o, merge, common, head, merge, entries);
2014 - clean = process_renames(o, re_head, re_merge);
2039 + clean = handle_renames(o, common, head, merge, entries,
2040 + &re_info);
2041 record_df_conflict_files(o, entries);
2042 if (clean < 0)
2043 goto cleanup;
@@ -2036,16 +2062,13 @@ int merge_trees(struct merge_options *o,
2062 }
2063
2064 cleanup:
2039 - string_list_clear(re_merge, 0);
2040 - string_list_clear(re_head, 0);
2065 + cleanup_renames(&re_info);
2066 +
2067 string_list_clear(entries, 1);
2068 + free(entries);
2069
2070 hashmap_free(&o->current_file_dir_set, 1);
2071
2045 - free(re_merge);
2046 - free(re_head);
2047 - free(entries);
2048 -
2072 if (clean < 0)
2073 return clean;
2074 }