summaryrefslogtreecommitdiff
path: root/merge-ort.c
diff options
context:
space:
mode:
authorLibravatar Elijah Newren <newren@gmail.com>2021-02-27 00:30:42 +0000
committerLibravatar Junio C Hamano <gitster@pobox.com>2021-02-26 17:53:11 -0800
commit0c4fd732f043be570e08b51c475ff9f2e2066912 (patch)
tree3571da9673190b17d3badd22f225d1a3f553346c /merge-ort.c
parentdiffcore-rename: add a mapping of destination names to their indices (diff)
downloadtgif-0c4fd732f043be570e08b51c475ff9f2e2066912.tar.xz
Move computation of dir_rename_count from merge-ort to diffcore-rename
Move the computation of dir_rename_count from merge-ort.c to diffcore-rename.c, making slight adjustments to the data structures based on the move. While the diffstat looks large, viewing this commit with --color-moved makes it clear that only about 20 lines changed. With this patch, the computation of dir_rename_count is still only done after inexact rename detection, but subsequent commits will add a preliminary computation of dir_rename_count after exact rename detection, followed by some updates after inexact rename detection. Reviewed-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'merge-ort.c')
-rw-r--r--merge-ort.c132
1 files changed, 3 insertions, 129 deletions
diff --git a/merge-ort.c b/merge-ort.c
index 603d30c521..c4467e073b 100644
--- a/merge-ort.c
+++ b/merge-ort.c
@@ -1302,131 +1302,6 @@ static char *handle_path_level_conflicts(struct merge_options *opt,
return new_path;
}
-static void dirname_munge(char *filename)
-{
- char *slash = strrchr(filename, '/');
- if (!slash)
- slash = filename;
- *slash = '\0';
-}
-
-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 update_dir_rename_counts(struct strmap *dir_rename_count,
- struct strset *dirs_removed,
- const char *oldname,
- const char *newname)
-{
- char *old_dir = xstrdup(oldname);
- char *new_dir = xstrdup(newname);
- char new_dir_first_char = new_dir[0];
- int first_time_in_loop = 1;
-
- while (1) {
- dirname_munge(old_dir);
- dirname_munge(new_dir);
-
- /*
- * When renaming
- * "a/b/c/d/e/foo.c" -> "a/b/some/thing/else/e/foo.c"
- * then this suggests that both
- * a/b/c/d/e/ => a/b/some/thing/else/e/
- * a/b/c/d/ => a/b/some/thing/else/
- * so we want to increment counters for both. We do NOT,
- * however, also want to suggest that there was the following
- * rename:
- * a/b/c/ => a/b/some/thing/
- * so we need to quit at that point.
- *
- * Note the when first_time_in_loop, we only strip off the
- * basename, and we don't care if that's different.
- */
- if (!first_time_in_loop) {
- char *old_sub_dir = strchr(old_dir, '\0')+1;
- char *new_sub_dir = strchr(new_dir, '\0')+1;
- if (!*new_dir) {
- /*
- * Special case when renaming to root directory,
- * i.e. when new_dir == "". In this case, we had
- * something like
- * a/b/subdir => subdir
- * and so dirname_munge() sets things up so that
- * old_dir = "a/b\0subdir\0"
- * new_dir = "\0ubdir\0"
- * We didn't have a '/' to overwrite a '\0' onto
- * in new_dir, so we have to compare differently.
- */
- if (new_dir_first_char != old_sub_dir[0] ||
- strcmp(old_sub_dir+1, new_sub_dir))
- break;
- } else {
- if (strcmp(old_sub_dir, new_sub_dir))
- break;
- }
- }
-
- if (strset_contains(dirs_removed, old_dir))
- increment_count(dir_rename_count, old_dir, new_dir);
- else
- break;
-
- /* If we hit toplevel directory ("") for old or new dir, quit */
- if (!*old_dir || !*new_dir)
- break;
-
- first_time_in_loop = 0;
- }
-
- /* Free resources we don't need anymore */
- free(old_dir);
- free(new_dir);
-}
-
-static void compute_rename_counts(struct diff_queue_struct *pairs,
- struct strmap *dir_rename_count,
- struct strset *dirs_removed)
-{
- int i;
-
- for (i = 0; i < pairs->nr; ++i) {
- struct diff_filepair *pair = pairs->queue[i];
-
- /* File not part of directory rename if it wasn't renamed */
- if (pair->status != 'R')
- 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.
- */
- update_dir_rename_counts(dir_rename_count, dirs_removed,
- pair->one->path,
- pair->two->path);
- }
-}
-
static void get_provisional_directory_renames(struct merge_options *opt,
unsigned side,
int *clean)
@@ -1435,9 +1310,6 @@ static void get_provisional_directory_renames(struct merge_options *opt,
struct strmap_entry *entry;
struct rename_info *renames = &opt->priv->renames;
- compute_rename_counts(&renames->pairs[side],
- &renames->dir_rename_count[side],
- &renames->dirs_removed[side]);
/*
* Collapse
* dir_rename_count: old_directory -> {new_directory -> count}
@@ -2162,7 +2034,9 @@ static void detect_regular_renames(struct merge_options *opt,
diff_queued_diff = renames->pairs[side_index];
trace2_region_enter("diff", "diffcore_rename", opt->repo);
- diffcore_rename(&diff_opts);
+ diffcore_rename_extended(&diff_opts,
+ &renames->dirs_removed[side_index],
+ &renames->dir_rename_count[side_index]);
trace2_region_leave("diff", "diffcore_rename", opt->repo);
resolve_diffpair_statuses(&diff_queued_diff);