Skip to content

Commit 04264d4

Browse files
newrengitster
authored andcommitted
merge-ort: add outline of get_provisional_directory_renames()
This function is based on merge-recursive.c's get_directory_renames(), except that the first half has been split out into a not-yet-implemented compute_rename_counts(). The primary difference here is our lack of the non_unique_new_dir boolean in our strmap. The lack of that field will at first cause us to fail testcase 2b of t6423; however, future optimizations will obviate the need for that ugly field so we have just left it out. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 112e111 commit 04264d4

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

merge-ort.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -721,11 +721,66 @@ static int handle_content_merge(struct merge_options *opt,
721721

722722
/*** Function Grouping: functions related to directory rename detection ***/
723723

724+
static void compute_rename_counts(struct diff_queue_struct *pairs,
725+
struct strmap *dir_rename_count,
726+
struct strset *dirs_removed)
727+
{
728+
die("Not yet implemented!");
729+
}
730+
724731
static void get_provisional_directory_renames(struct merge_options *opt,
725732
unsigned side,
726733
int *clean)
727734
{
728-
die("Not yet implemented!");
735+
struct hashmap_iter iter;
736+
struct strmap_entry *entry;
737+
struct rename_info *renames = &opt->priv->renames;
738+
739+
compute_rename_counts(&renames->pairs[side],
740+
&renames->dir_rename_count[side],
741+
&renames->dirs_removed[side]);
742+
/*
743+
* Collapse
744+
* dir_rename_count: old_directory -> {new_directory -> count}
745+
* down to
746+
* dir_renames: old_directory -> best_new_directory
747+
* where best_new_directory is the one with the unique highest count.
748+
*/
749+
strmap_for_each_entry(&renames->dir_rename_count[side], &iter, entry) {
750+
const char *source_dir = entry->key;
751+
struct strintmap *counts = entry->value;
752+
struct hashmap_iter count_iter;
753+
struct strmap_entry *count_entry;
754+
int max = 0;
755+
int bad_max = 0;
756+
const char *best = NULL;
757+
758+
strintmap_for_each_entry(counts, &count_iter, count_entry) {
759+
const char *target_dir = count_entry->key;
760+
intptr_t count = (intptr_t)count_entry->value;
761+
762+
if (count == max)
763+
bad_max = max;
764+
else if (count > max) {
765+
max = count;
766+
best = target_dir;
767+
}
768+
}
769+
770+
if (bad_max == max) {
771+
path_msg(opt, source_dir, 0,
772+
_("CONFLICT (directory rename split): "
773+
"Unclear where to rename %s to; it was "
774+
"renamed to multiple other directories, with "
775+
"no destination getting a majority of the "
776+
"files."),
777+
source_dir);
778+
*clean = 0;
779+
} else {
780+
strmap_put(&renames->dir_renames[side],
781+
source_dir, (void*)best);
782+
}
783+
}
729784
}
730785

731786
static void handle_directory_level_conflicts(struct merge_options *opt)

0 commit comments

Comments
 (0)