Skip to content

Commit fb52938

Browse files
newrengitster
authored andcommitted
merge-ort: record the reason that we want a rename for a directory
When one side of history renames a directory, and the other side of history added files to the old directory, directory rename detection is used to warn about the location of the added files so the user can move them to the old directory or keep them with the new one. This sets up three different types of directories: * directories that had new files added to them * directories underneath a directory that had new files added to them * directories where no new files were added to it or any leading path Save this information in dirs_removed; the next several commits will make use of this information. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a49b55d commit fb52938

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

diffcore-rename.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ static void cleanup_dir_rename_info(struct dir_rename_info *info,
667667
const char *source_dir = entry->key;
668668
struct strintmap *counts = entry->value;
669669

670-
if (!strintmap_contains(dirs_removed, source_dir)) {
670+
if (!strintmap_get(dirs_removed, source_dir)) {
671671
string_list_append(&to_remove, source_dir);
672672
strintmap_clear(counts);
673673
continue;

diffcore.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ struct diff_filepair *diff_queue(struct diff_queue_struct *,
161161
struct diff_filespec *);
162162
void diff_q(struct diff_queue_struct *, struct diff_filepair *);
163163

164+
/* dir_rename_relevance: the reason we want rename information for a dir */
165+
enum dir_rename_relevance {
166+
NOT_RELEVANT = 0,
167+
RELEVANT_FOR_ANCESTOR = 1,
168+
RELEVANT_FOR_SELF = 2
169+
};
170+
164171
void partial_clear_dir_rename_count(struct strmap *dir_rename_count);
165172

166173
void diffcore_break(struct repository *, int);

merge-ort.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ struct rename_info {
7373

7474
/*
7575
* dirs_removed: directories removed on a given side of history.
76+
*
77+
* The keys of dirs_removed[side] are the directories that were removed
78+
* on the given side of history. The value of the strintmap for each
79+
* directory is a value from enum dir_rename_relevance.
7680
*/
7781
struct strintmap dirs_removed[3];
7882

@@ -729,10 +733,41 @@ static void collect_rename_info(struct merge_options *opt,
729733
if (dirmask == 1 || dirmask == 3 || dirmask == 5) {
730734
/* absent_mask = 0x07 - dirmask; sides = absent_mask/2 */
731735
unsigned sides = (0x07 - dirmask)/2;
736+
unsigned relevance = (renames->dir_rename_mask == 0x07) ?
737+
RELEVANT_FOR_ANCESTOR : NOT_RELEVANT;
738+
/*
739+
* Record relevance of this directory. However, note that
740+
* when collect_merge_info_callback() recurses into this
741+
* directory and calls collect_rename_info() on paths
742+
* within that directory, if we find a path that was added
743+
* to this directory on the other side of history, we will
744+
* upgrade this value to RELEVANT_FOR_SELF; see below.
745+
*/
732746
if (sides & 1)
733-
strintmap_set(&renames->dirs_removed[1], fullname, 1);
747+
strintmap_set(&renames->dirs_removed[1], fullname,
748+
relevance);
734749
if (sides & 2)
735-
strintmap_set(&renames->dirs_removed[2], fullname, 1);
750+
strintmap_set(&renames->dirs_removed[2], fullname,
751+
relevance);
752+
}
753+
754+
/*
755+
* Here's the block that potentially upgrades to RELEVANT_FOR_SELF.
756+
* When we run across a file added to a directory. In such a case,
757+
* find the directory of the file and upgrade its relevance.
758+
*/
759+
if (renames->dir_rename_mask == 0x07 &&
760+
(filemask == 2 || filemask == 4)) {
761+
/*
762+
* Need directory rename for parent directory on other side
763+
* of history from added file. Thus
764+
* side = (~filemask & 0x06) >> 1
765+
* or
766+
* side = 3 - (filemask/2).
767+
*/
768+
unsigned side = 3 - (filemask >> 1);
769+
strintmap_set(&renames->dirs_removed[side], dirname,
770+
RELEVANT_FOR_SELF);
736771
}
737772

738773
if (filemask == 0 || filemask == 7)
@@ -3446,7 +3481,7 @@ static void merge_start(struct merge_options *opt, struct merge_result *result)
34463481
renames = &opt->priv->renames;
34473482
for (i = MERGE_SIDE1; i <= MERGE_SIDE2; i++) {
34483483
strintmap_init_with_options(&renames->dirs_removed[i],
3449-
0, NULL, 0);
3484+
NOT_RELEVANT, NULL, 0);
34503485
strmap_init_with_options(&renames->dir_rename_count[i],
34513486
NULL, 1);
34523487
strmap_init_with_options(&renames->dir_renames[i],

0 commit comments

Comments
 (0)