543
strmap_partial_clear(dir_rename_count, 1);
544
}
545
546
-static void cleanup_dir_rename_info(struct dir_rename_info *info)
546
+static void cleanup_dir_rename_info(struct dir_rename_info *info,
547
+ struct strset *dirs_removed,
548
+ int keep_dir_rename_count)
549
{
550
+ struct hashmap_iter iter;
551
+ struct strmap_entry *entry;
552
+ struct string_list to_remove = STRING_LIST_INIT_NODUP;
553
+ int i;
554
+
555
if (!info->setup)
556
return;
557
562
strmap_clear(&info->dir_rename_guess, 1);
563
564
/* dir_rename_count */
558
- partial_clear_dir_rename_count(info->dir_rename_count);
559
- strmap_clear(info->dir_rename_count, 1);
565
+ if (!keep_dir_rename_count) {
566
+ partial_clear_dir_rename_count(info->dir_rename_count);
567
+ strmap_clear(info->dir_rename_count, 1);
568
+ FREE_AND_NULL(info->dir_rename_count);
569
+ return;
570
+ }
571
+
572
+ /*
573
+ * Although dir_rename_count was passed in
574
+ * diffcore_rename_extended() and we want to keep it around and
575
+ * return it to that caller, we first want to remove any data
576
+ * associated with directories that weren't renamed.
577
+ */
578
+ strmap_for_each_entry(info->dir_rename_count, &iter, entry) {
579
+ const char *source_dir = entry->key;
580
+ struct strintmap *counts = entry->value;
581
+
582
+ if (!strset_contains(dirs_removed, source_dir)) {
583
+ string_list_append(&to_remove, source_dir);
584
+ strintmap_clear(counts);
585
+ continue;
586
+ }
587
+ }
588
+ for (i = 0; i < to_remove.nr; ++i)
589
+ strmap_remove(info->dir_rename_count,
590
+ to_remove.items[i].string, 1);
591
+ string_list_clear(&to_remove, 0);
592
}
593
594
static const char *get_basename(const char *filename)
1250
if (rename_dst[i].filespec_to_free)
1251
free_filespec(rename_dst[i].filespec_to_free);
1252
1221
- cleanup_dir_rename_info(&info);
1253
+ cleanup_dir_rename_info(&info, dirs_removed, dir_rename_count != NULL);
1254
FREE_AND_NULL(rename_dst);
1255
rename_dst_nr = rename_dst_alloc = 0;
1256
FREE_AND_NULL(rename_src);