diff options
author | Elijah Newren <newren@gmail.com> | 2021-03-13 22:22:06 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2021-03-18 14:32:56 -0700 |
commit | bf238b71377e924066ca5155a787c167177f706c (patch) | |
tree | edecc467c8b8d4a34b43d029ef2645d0cf51012a | |
parent | diffcore-rename: check if we have enough renames for directories early on (diff) | |
download | tgif-bf238b71377e924066ca5155a787c167177f706c.tar.xz |
diffcore-rename: add computation of number of unknown renames
The previous commit can only be effective if we have a computation of
the number of paths under a given directory which are still have pending
renames, and expected this number to be recorded in the dir_rename_count
map under the key UNKNOWN_DIR. Add the code necessary to compute these
values.
Note that this change means dir_rename_count might have a directory
whose only entry (for UNKNOWN_DIR) was removed by the time merge-ort
goes to check it. To account for this, merge-ort needs to check for the
case where the max count is 0.
With this change we are now computing the necessary value for each
directory in dirs_removed, but are not using that value anywhere. The
next two commits will make use of the values stored in dirs_removed in
order to compute whether each relevant_source (that is needed only for
directory rename detection) has become unnecessary.
Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | diffcore-rename.c | 41 | ||||
-rw-r--r-- | merge-ort.c | 3 |
2 files changed, 40 insertions, 4 deletions
diff --git a/diffcore-rename.c b/diffcore-rename.c index 8fa29076e0..9844cd4878 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -699,7 +699,8 @@ static void cleanup_dir_rename_info(struct dir_rename_info *info, /* * Although dir_rename_count was passed in * diffcore_rename_extended() and we want to keep it around and - * return it to that caller, we first want to remove any data + * return it to that caller, we first want to remove any counts in + * the maps associated with UNKNOWN_DIR entries and any data * associated with directories that weren't renamed. */ strmap_for_each_entry(info->dir_rename_count, &iter, entry) { @@ -711,6 +712,9 @@ static void cleanup_dir_rename_info(struct dir_rename_info *info, strintmap_clear(counts); continue; } + + if (strintmap_contains(counts, UNKNOWN_DIR)) + strintmap_remove(counts, UNKNOWN_DIR); } for (i = 0; i < to_remove.nr; ++i) strmap_remove(info->dir_rename_count, @@ -1125,6 +1129,7 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info, * a majority. */ + int i; struct hashmap_iter iter; struct strmap_entry *entry; @@ -1134,10 +1139,38 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info, return; /* culling incompatbile with break detection */ /* - * FIXME: Supplement dir_rename_count with number of potential - * renames, marking all potential rename sources as mapping to - * UNKNOWN_DIR. + * Supplement dir_rename_count with number of potential renames, + * marking all potential rename sources as mapping to UNKNOWN_DIR. */ + for (i = 0; i < rename_src_nr; i++) { + char *old_dir; + struct diff_filespec *one = rename_src[i].p->one; + + /* + * sources that are part of a rename will have already been + * removed by a prior call to remove_unneeded_paths_from_src() + */ + assert(!one->rename_used); + + old_dir = get_dirname(one->path); + while (*old_dir != '\0' && + NOT_RELEVANT != strintmap_get(dirs_removed, old_dir)) { + char *freeme = old_dir; + + increment_count(info, old_dir, UNKNOWN_DIR); + old_dir = get_dirname(old_dir); + + /* Free resources we don't need anymore */ + free(freeme); + } + /* + * old_dir and new_dir free'd in increment_count, but + * get_dirname() gives us a new pointer we need to free for + * old_dir. Also, if the loop runs 0 times we need old_dir + * to be freed. + */ + free(old_dir); + } /* * For any directory which we need a potential rename detected for diff --git a/merge-ort.c b/merge-ort.c index e2606c73ad..f2b259986e 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1546,6 +1546,9 @@ static void get_provisional_directory_renames(struct merge_options *opt, } } + if (max == 0) + continue; + if (bad_max == max) { path_msg(opt, source_dir, 0, _("CONFLICT (directory rename split): " |