@@ -343,6 +343,13 @@ static void path_msg(struct merge_options *opt,
343
343
strbuf_addch (sb , '\n' );
344
344
}
345
345
346
+ static char * unique_path (struct strmap * existing_paths ,
347
+ const char * path ,
348
+ const char * branch )
349
+ {
350
+ die ("Not yet implemented." );
351
+ }
352
+
346
353
/*** Function Grouping: functions related to collect_merge_info() ***/
347
354
348
355
static void setup_path_info (struct merge_options * opt ,
@@ -962,6 +969,8 @@ static void process_entry(struct merge_options *opt,
962
969
struct conflict_info * ci ,
963
970
struct directory_versions * dir_metadata )
964
971
{
972
+ int df_file_index = 0 ;
973
+
965
974
VERIFY_CI (ci );
966
975
assert (ci -> filemask >= 0 && ci -> filemask <= 7 );
967
976
/* ci->match_mask == 7 was handled in collect_merge_info_callback() */
@@ -998,13 +1007,86 @@ static void process_entry(struct merge_options *opt,
998
1007
oidcpy (& ci -> stages [i ].oid , & null_oid );
999
1008
}
1000
1009
} else if (ci -> df_conflict && ci -> merged .result .mode != 0 ) {
1001
- die ("Not yet implemented." );
1010
+ /*
1011
+ * This started out as a D/F conflict, and the entries in
1012
+ * the competing directory were not removed by the merge as
1013
+ * evidenced by write_completed_directory() writing a value
1014
+ * to ci->merged.result.mode.
1015
+ */
1016
+ struct conflict_info * new_ci ;
1017
+ const char * branch ;
1018
+ const char * old_path = path ;
1019
+ int i ;
1020
+
1021
+ assert (ci -> merged .result .mode == S_IFDIR );
1022
+
1023
+ /*
1024
+ * If filemask is 1, we can just ignore the file as having
1025
+ * been deleted on both sides. We do not want to overwrite
1026
+ * ci->merged.result, since it stores the tree for all the
1027
+ * files under it.
1028
+ */
1029
+ if (ci -> filemask == 1 ) {
1030
+ ci -> filemask = 0 ;
1031
+ return ;
1032
+ }
1033
+
1034
+ /*
1035
+ * This file still exists on at least one side, and we want
1036
+ * the directory to remain here, so we need to move this
1037
+ * path to some new location.
1038
+ */
1039
+ new_ci = xcalloc (1 , sizeof (* new_ci ));
1040
+ /* We don't really want new_ci->merged.result copied, but it'll
1041
+ * be overwritten below so it doesn't matter. We also don't
1042
+ * want any directory mode/oid values copied, but we'll zero
1043
+ * those out immediately. We do want the rest of ci copied.
1044
+ */
1045
+ memcpy (new_ci , ci , sizeof (* ci ));
1046
+ new_ci -> match_mask = (new_ci -> match_mask & ~new_ci -> dirmask );
1047
+ new_ci -> dirmask = 0 ;
1048
+ for (i = MERGE_BASE ; i <= MERGE_SIDE2 ; i ++ ) {
1049
+ if (new_ci -> filemask & (1 << i ))
1050
+ continue ;
1051
+ /* zero out any entries related to directories */
1052
+ new_ci -> stages [i ].mode = 0 ;
1053
+ oidcpy (& new_ci -> stages [i ].oid , & null_oid );
1054
+ }
1055
+
1056
+ /*
1057
+ * Find out which side this file came from; note that we
1058
+ * cannot just use ci->filemask, because renames could cause
1059
+ * the filemask to go back to 7. So we use dirmask, then
1060
+ * pick the opposite side's index.
1061
+ */
1062
+ df_file_index = (ci -> dirmask & (1 << 1 )) ? 2 : 1 ;
1063
+ branch = (df_file_index == 1 ) ? opt -> branch1 : opt -> branch2 ;
1064
+ path = unique_path (& opt -> priv -> paths , path , branch );
1065
+ strmap_put (& opt -> priv -> paths , path , new_ci );
1066
+
1067
+ path_msg (opt , path , 0 ,
1068
+ _ ("CONFLICT (file/directory): directory in the way "
1069
+ "of %s from %s; moving it to %s instead." ),
1070
+ old_path , branch , path );
1071
+
1072
+ /*
1073
+ * Zero out the filemask for the old ci. At this point, ci
1074
+ * was just an entry for a directory, so we don't need to
1075
+ * do anything more with it.
1076
+ */
1077
+ ci -> filemask = 0 ;
1078
+
1079
+ /*
1080
+ * Now note that we're working on the new entry (path was
1081
+ * updated above.
1082
+ */
1083
+ ci = new_ci ;
1002
1084
}
1003
1085
1004
1086
/*
1005
1087
* NOTE: Below there is a long switch-like if-elseif-elseif... block
1006
1088
* which the code goes through even for the df_conflict cases
1007
- * above. Well, it will once we don't die-not-implemented above.
1089
+ * above.
1008
1090
*/
1009
1091
if (ci -> match_mask ) {
1010
1092
ci -> merged .clean = 1 ;
0 commit comments