| 1157 | } |
| 1158 | |
| 1159 | static void remove_unneeded_paths_from_src(int detecting_copies, |
| 1160 | struct strintmap *interesting) |
| 1161 | { |
| 1162 | int i, new_num_src; |
| 1163 | |
| 1164 | if (detecting_copies && !interesting) |
| 1165 | return; /* nothing to remove */ |
| 1166 | if (break_idx) |
| 1167 | return; /* culling incompatible with break detection */ |
| 1168 | |
| 1169 | /* |
| 1170 | * Note on reasons why we cull unneeded sources but not destinations: |
| 1171 | * 1) Pairings are stored in rename_dst (not rename_src), which we |
| 1172 | * need to keep around. So, we just can't cull rename_dst even |
| 1173 | * if we wanted to. But doing so wouldn't help because... |
| 1174 | * |
| 1175 | * 2) There is a matrix pairwise comparison that follows the |
| 1176 | * "Performing inexact rename detection" progress message. |
| 1177 | * Iterating over the destinations is done in the outer loop, |
| 1178 | * hence we only iterate over each of those once and we can |
| 1179 | * easily skip the outer loop early if the destination isn't |
| 1180 | * relevant. That's only one check per destination path to |
| 1181 | * skip. |
| 1182 | * |
| 1183 | * By contrast, the sources are iterated in the inner loop; if |
| 1184 | * we check whether a source can be skipped, then we'll be |
| 1185 | * checking it N separate times, once for each destination. |
| 1186 | * We don't want to have to iterate over known-not-needed |
| 1187 | * sources N times each, so avoid that by removing the sources |
| 1188 | * from rename_src here. |
| 1189 | */ |
| 1190 | for (i = 0, new_num_src = 0; i < rename_src_nr; i++) { |
| 1191 | struct diff_filespec *one = rename_src[i].p->one; |
| 1192 | |
| 1193 | /* |
| 1194 | * renames are stored in rename_dst, so if a rename has |
| 1195 | * already been detected using this source, we can just |
| 1196 | * remove the source knowing rename_dst has its info. |
| 1197 | */ |
| 1198 | if (!detecting_copies && one->rename_used) |
| 1199 | continue; |
| 1200 | |
| 1201 | /* If we don't care about the source path, skip it */ |
| 1202 | if (interesting && !strintmap_contains(interesting, one->path)) |
| 1203 | continue; |
| 1204 | |
| 1205 | if (new_num_src < i) |
| 1206 | memcpy(&rename_src[new_num_src], &rename_src[i], |
| 1207 | sizeof(struct diff_rename_src)); |
| 1208 | new_num_src++; |
| 1209 | } |
| 1210 | |
| 1211 | rename_src_nr = new_num_src; |
| 1212 | } |
| 1213 | |
| 1214 | static void handle_early_known_dir_renames(struct dir_rename_info *info, |
| 1215 | struct strintmap *relevant_sources, |
no test coverage detected