]> git.ipfire.org Git - thirdparty/git.git/commitdiff
merge-ort: implement compute_rename_counts()
authorElijah Newren <newren@gmail.com>
Tue, 19 Jan 2021 19:53:43 +0000 (19:53 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 21 Jan 2021 06:18:55 +0000 (22:18 -0800)
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>
merge-ort.c

index eb609ab006309c192f1bd548bd2d9d69ed587f20..8aa415c542f7494308fd1653d62d8f30061e9b55 100644 (file)
@@ -721,7 +721,6 @@ static int handle_content_merge(struct merge_options *opt,
 
 /*** Function Grouping: functions related to directory rename detection ***/
 
-MAYBE_UNUSED
 static void get_renamed_dir_portion(const char *old_path, const char *new_path,
                                    char **old_dir, char **new_dir)
 {
@@ -825,11 +824,62 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
        *new_dir = xstrndup(new_path, end_of_new - new_path);
 }
 
+static void increment_count(struct strmap *dir_rename_count,
+                           char *old_dir,
+                           char *new_dir)
+{
+       struct strintmap *counts;
+       struct strmap_entry *e;
+
+       /* Get the {new_dirs -> counts} mapping using old_dir */
+       e = strmap_get_entry(dir_rename_count, old_dir);
+       if (e) {
+               counts = e->value;
+       } else {
+               counts = xmalloc(sizeof(*counts));
+               strintmap_init_with_options(counts, 0, NULL, 1);
+               strmap_put(dir_rename_count, old_dir, counts);
+       }
+
+       /* Increment the count for new_dir */
+       strintmap_incr(counts, new_dir, 1);
+}
+
 static void compute_rename_counts(struct diff_queue_struct *pairs,
                                  struct strmap *dir_rename_count,
                                  struct strset *dirs_removed)
 {
-       die("Not yet implemented!");
+       int i;
+
+       for (i = 0; i < pairs->nr; ++i) {
+               char *old_dir, *new_dir;
+               struct diff_filepair *pair = pairs->queue[i];
+
+               /* File not part of directory rename if it wasn't renamed */
+               if (pair->status != 'R')
+                       continue;
+
+               /* Get the old and new directory names */
+               get_renamed_dir_portion(pair->one->path, pair->two->path,
+                                       &old_dir,        &new_dir);
+               if (!old_dir)
+                       /* Directory didn't change at all; ignore this one. */
+                       continue;
+
+               /*
+                * Make dir_rename_count contain a map of a map:
+                *   old_directory -> {new_directory -> count}
+                * In other words, for every pair look at the directories for
+                * the old filename and the new filename and count how many
+                * times that pairing occurs.
+                */
+               if (strset_contains(dirs_removed, old_dir))
+                       increment_count(dir_rename_count, old_dir, new_dir);
+
+               /* Free resources we don't need anymore */
+               free(old_dir);
+               free(new_dir);
+       }
 }
 
 static void get_provisional_directory_renames(struct merge_options *opt,