merge-ort: implement compute_rename_counts()

This function is based on the first half of get_directory_renames() from merge-recursive.c; as part of the implementation, factor out a routine, increment_count(), to update the bookkeeping to track the number of items renamed into new directories. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Jan 19, 2021 at 19:53 UTC 2f620a4f1983efcb70dee55917240b08065f2c4e
1 file changed +52 -2
merge-ort.c
+52 -2
@@ -721,7 +721,6 @@ static int handle_content_merge(struct merge_options *opt,
721
722 /*** Function Grouping: functions related to directory rename detection ***/
723
724 -MAYBE_UNUSED
724 static void get_renamed_dir_portion(const char *old_path, const char *new_path,
725 char **old_dir, char **new_dir)
726 {
@@ -825,11 +824,62 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
824 *new_dir = xstrndup(new_path, end_of_new - new_path);
825 }
826
827 +static void increment_count(struct strmap *dir_rename_count,
828 + char *old_dir,
829 + char *new_dir)
830 +{
831 + struct strintmap *counts;
832 + struct strmap_entry *e;
833 +
834 + /* Get the {new_dirs -> counts} mapping using old_dir */
835 + e = strmap_get_entry(dir_rename_count, old_dir);
836 + if (e) {
837 + counts = e->value;
838 + } else {
839 + counts = xmalloc(sizeof(*counts));
840 + strintmap_init_with_options(counts, 0, NULL, 1);
841 + strmap_put(dir_rename_count, old_dir, counts);
842 + }
843 +
844 + /* Increment the count for new_dir */
845 + strintmap_incr(counts, new_dir, 1);
846 +}
847 +
848 static void compute_rename_counts(struct diff_queue_struct *pairs,
849 struct strmap *dir_rename_count,
850 struct strset *dirs_removed)
851 {
832 - die("Not yet implemented!");
852 + int i;
853 +
854 + for (i = 0; i < pairs->nr; ++i) {
855 + char *old_dir, *new_dir;
856 + struct diff_filepair *pair = pairs->queue[i];
857 +
858 + /* File not part of directory rename if it wasn't renamed */
859 + if (pair->status != 'R')
860 + continue;
861 +
862 + /* Get the old and new directory names */
863 + get_renamed_dir_portion(pair->one->path, pair->two->path,
864 + &old_dir, &new_dir);
865 + if (!old_dir)
866 + /* Directory didn't change at all; ignore this one. */
867 + continue;
868 +
869 + /*
870 + * Make dir_rename_count contain a map of a map:
871 + * old_directory -> {new_directory -> count}
872 + * In other words, for every pair look at the directories for
873 + * the old filename and the new filename and count how many
874 + * times that pairing occurs.
875 + */
876 + if (strset_contains(dirs_removed, old_dir))
877 + increment_count(dir_rename_count, old_dir, new_dir);
878 +
879 + /* Free resources we don't need anymore */
880 + free(old_dir);
881 + free(new_dir);
882 + }
883 }
884
885 static void get_provisional_directory_renames(struct merge_options *opt,