Skip to content

Commit d3b244c

Browse files
committed
diffcore-rename: check if we have enough renames for directories early on
As noted in the past two commits, we only need to track dir_rename_count for directories that we directly need directory renames for. Further, now that we are tracking the number of unmatched pairs for each directory left to count, we can determine if a directory already has enough renames to determine how directory rename detection will go for that directory. For such directories, demote them from RELEVANT_FOR_SELF to RELEVANT_FOR_ANCESTOR, as there still may be an ancestor of that directory that we need renames for. The next commit will use this information to update individual paths in relevant_sources. Signed-off-by: Elijah Newren <[email protected]>
1 parent 4764514 commit d3b244c

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

diffcore-rename.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,26 @@ static const char *get_highest_rename_path(struct strintmap *counts)
409409

410410
static char *UNKNOWN_DIR = "/"; /* placeholder -- short, illegal directory */
411411

412+
static int dir_rename_already_determinable(struct strintmap *counts)
413+
{
414+
struct hashmap_iter iter;
415+
struct strmap_entry *entry;
416+
int first = 0, second = 0, unknown = 0;
417+
strintmap_for_each_entry(counts, &iter, entry) {
418+
const char *destination_dir = entry->key;
419+
intptr_t count = (intptr_t)entry->value;
420+
if (!strcmp(destination_dir, UNKNOWN_DIR)) {
421+
unknown = count;
422+
} else if (count >= first) {
423+
second = first;
424+
first = count;
425+
} else if (count >= second) {
426+
second = count;
427+
}
428+
}
429+
return first > second + unknown;
430+
}
431+
412432
static void increment_count(struct dir_rename_info *info,
413433
char *old_dir,
414434
char *new_dir)
@@ -1103,6 +1123,8 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info,
11031123
struct strintmap *dirs_removed)
11041124
{
11051125
int i;
1126+
struct hashmap_iter iter;
1127+
struct strmap_entry *entry;
11061128

11071129
if (!dirs_removed || !relevant_sources)
11081130
return; /* nothing to cull */
@@ -1138,6 +1160,18 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info,
11381160
*/
11391161
free(old_dir);
11401162
}
1163+
1164+
strmap_for_each_entry(info->dir_rename_count, &iter, entry) {
1165+
/* entry->key is source_dir */
1166+
struct strintmap *counts = entry->value;
1167+
1168+
if (strintmap_get(dirs_removed, entry->key) ==
1169+
RELEVANT_FOR_SELF &&
1170+
dir_rename_already_determinable(counts)) {
1171+
strintmap_set(dirs_removed, entry->key,
1172+
RELEVANT_FOR_ANCESTOR);
1173+
}
1174+
}
11411175
}
11421176

11431177
void diffcore_rename_extended(struct diff_options *options,

0 commit comments

Comments
 (0)