merge-ort: implement check_for_directory_rename()
This is copied from merge-recursive.c, with minor tweaks due to using strmap API and the fact that it can use opt->priv->paths to get all pathnames that exist instead of taking a tree object. This depends on a new function, handle_path_level_conflicts(), which just has a placeholder die-not-yet-implemented implementation for now; a subsequent patch will implement it. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
parent
fbcfc0cc17
commit
47325e8533
67
merge-ort.c
67
merge-ort.c
|
@ -864,6 +864,21 @@ static void get_renamed_dir_portion(const char *old_path, const char *new_path,
|
||||||
*new_dir = xstrndup(new_path, end_of_new - new_path);
|
*new_dir = xstrndup(new_path, end_of_new - new_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See if there is a directory rename for path, and if there are any file
|
||||||
|
* level conflicts on the given side for the renamed location. If there is
|
||||||
|
* a rename and there are no conflicts, return the new name. Otherwise,
|
||||||
|
* return NULL.
|
||||||
|
*/
|
||||||
|
static char *handle_path_level_conflicts(struct merge_options *opt,
|
||||||
|
const char *path,
|
||||||
|
unsigned side_index,
|
||||||
|
struct strmap_entry *rename_info,
|
||||||
|
struct strmap *collisions)
|
||||||
|
{
|
||||||
|
die("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
static void increment_count(struct strmap *dir_rename_count,
|
static void increment_count(struct strmap *dir_rename_count,
|
||||||
char *old_dir,
|
char *old_dir,
|
||||||
char *new_dir)
|
char *new_dir)
|
||||||
|
@ -1078,7 +1093,57 @@ static char *check_for_directory_rename(struct merge_options *opt,
|
||||||
struct strmap *collisions,
|
struct strmap *collisions,
|
||||||
int *clean_merge)
|
int *clean_merge)
|
||||||
{
|
{
|
||||||
die("Not yet implemented.");
|
char *new_path = NULL;
|
||||||
|
struct strmap_entry *rename_info;
|
||||||
|
struct strmap_entry *otherinfo = NULL;
|
||||||
|
const char *new_dir;
|
||||||
|
|
||||||
|
if (strmap_empty(dir_renames))
|
||||||
|
return new_path;
|
||||||
|
rename_info = check_dir_renamed(path, dir_renames);
|
||||||
|
if (!rename_info)
|
||||||
|
return new_path;
|
||||||
|
/* old_dir = rename_info->key; */
|
||||||
|
new_dir = rename_info->value;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This next part is a little weird. We do not want to do an
|
||||||
|
* implicit rename into a directory we renamed on our side, because
|
||||||
|
* that will result in a spurious rename/rename(1to2) conflict. An
|
||||||
|
* example:
|
||||||
|
* Base commit: dumbdir/afile, otherdir/bfile
|
||||||
|
* Side 1: smrtdir/afile, otherdir/bfile
|
||||||
|
* Side 2: dumbdir/afile, dumbdir/bfile
|
||||||
|
* Here, while working on Side 1, we could notice that otherdir was
|
||||||
|
* renamed/merged to dumbdir, and change the diff_filepair for
|
||||||
|
* otherdir/bfile into a rename into dumbdir/bfile. However, Side
|
||||||
|
* 2 will notice the rename from dumbdir to smrtdir, and do the
|
||||||
|
* transitive rename to move it from dumbdir/bfile to
|
||||||
|
* smrtdir/bfile. That gives us bfile in dumbdir vs being in
|
||||||
|
* smrtdir, a rename/rename(1to2) conflict. We really just want
|
||||||
|
* the file to end up in smrtdir. And the way to achieve that is
|
||||||
|
* to not let Side1 do the rename to dumbdir, since we know that is
|
||||||
|
* the source of one of our directory renames.
|
||||||
|
*
|
||||||
|
* That's why otherinfo and dir_rename_exclusions is here.
|
||||||
|
*
|
||||||
|
* As it turns out, this also prevents N-way transient rename
|
||||||
|
* confusion; See testcases 9c and 9d of t6043.
|
||||||
|
*/
|
||||||
|
otherinfo = strmap_get_entry(dir_rename_exclusions, new_dir);
|
||||||
|
if (otherinfo) {
|
||||||
|
path_msg(opt, rename_info->key, 1,
|
||||||
|
_("WARNING: Avoiding applying %s -> %s rename "
|
||||||
|
"to %s, because %s itself was renamed."),
|
||||||
|
rename_info->key, new_dir, path, new_dir);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_path = handle_path_level_conflicts(opt, path, side_index,
|
||||||
|
rename_info, collisions);
|
||||||
|
*clean_merge &= (new_path != NULL);
|
||||||
|
|
||||||
|
return new_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void apply_directory_rename_modifications(struct merge_options *opt,
|
static void apply_directory_rename_modifications(struct merge_options *opt,
|
||||||
|
|
Loading…
Reference in New Issue