Skip to content

Commit 9e84c3d

Browse files
committed
diffcore-rename: relevant_sources needed for location might be skippable
As noted a few commits ago, when a source file rename is used as part of directory rename detection, we need to increment counts for each ancestor directory in dirs_removed with value RELEVANT_FOR_SELF. However, due to the last commit, we may have downgraded all relevant ancestor directories from RELEVANT_FOR_SELF to RELEVANT_FOR_ANCESTOR. If no ancestor directory is found in dirs_removed with a value of RELEVANT_FOR_SELF, then we can downgrade relevant_source[PATH] from RELEVANT_LOCATION to RELEVANT_NO_MORE. This change does not yet affect things, as handle_early_known_dir_renames() has not yet been hooked into the code and called from anywhere. The next commit will change that. Signed-off-by: Elijah Newren <[email protected]>
1 parent 9dbadbe commit 9e84c3d

File tree

1 file changed

+50
-1
lines changed

1 file changed

+50
-1
lines changed

diffcore-rename.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,7 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info,
10911091
struct strintmap *relevant_sources,
10921092
struct strintmap *dirs_removed)
10931093
{
1094-
int i;
1094+
int i, new_num_src;
10951095
struct hashmap_iter iter;
10961096
struct strmap_entry *entry;
10971097

@@ -1141,6 +1141,55 @@ static void handle_early_known_dir_renames(struct dir_rename_info *info,
11411141
RELEVANT_FOR_ANCESTOR);
11421142
}
11431143
}
1144+
1145+
for (i = 0, new_num_src = 0; i < rename_src_nr; i++) {
1146+
struct diff_filespec *one = rename_src[i].p->one;
1147+
int val;
1148+
1149+
val = strintmap_get(relevant_sources, one->path);
1150+
1151+
/*
1152+
* sources that were not found in relevant_sources should
1153+
* have already been removed by a prior call to
1154+
* remove_unneeded_paths_from_src()
1155+
*/
1156+
assert(val != -1);
1157+
1158+
if (val == RELEVANT_LOCATION) {
1159+
int removable = 1;
1160+
char *dir = get_dirname(one->path);
1161+
while (1) {
1162+
char *freeme = dir;
1163+
int res = strintmap_get(dirs_removed, dir);
1164+
1165+
/* Quit if not found or irrelevant */
1166+
if (res == NOT_RELEVANT)
1167+
break;
1168+
/* If RELEVANT_FOR_SELF, can't remove */
1169+
if (res == RELEVANT_FOR_SELF) {
1170+
removable = 0;
1171+
break;
1172+
}
1173+
/* Else continue searching upwards */
1174+
assert(res == RELEVANT_FOR_ANCESTOR);
1175+
dir = get_dirname(dir);
1176+
free(freeme);
1177+
}
1178+
free(dir);
1179+
if (removable) {
1180+
strintmap_set(relevant_sources, one->path,
1181+
RELEVANT_NO_MORE);
1182+
continue;
1183+
}
1184+
}
1185+
1186+
if (new_num_src < i)
1187+
memcpy(&rename_src[new_num_src], &rename_src[i],
1188+
sizeof(struct diff_rename_src));
1189+
new_num_src++;
1190+
}
1191+
1192+
rename_src_nr = new_num_src;
11441193
}
11451194

11461195
void diffcore_rename_extended(struct diff_options *options,

0 commit comments

Comments
 (0)