@@ -360,20 +360,24 @@ static int string_list_df_name_compare(const void *a, const void *b)
360360 return onelen - twolen ;
361361}
362362
363-
364-
365- static void make_room_for_directories_of_df_conflicts (struct merge_options * o ,
366- struct string_list * entries )
363+ static void record_df_conflict_files (struct merge_options * o ,
364+ struct string_list * entries )
367365{
368- /* If there are D/F conflicts, and the paths currently exist
369- * in the working copy as a file, we want to remove them to
370- * make room for the corresponding directory. Such paths will
371- * later be processed in process_df_entry() at the end. If
372- * the corresponding directory ends up being removed by the
373- * merge, then the file will be reinstated at that time;
374- * otherwise, if the file is not supposed to be removed by the
375- * merge, the contents of the file will be placed in another
376- * unique filename.
366+ /* If there is a D/F conflict and the file for such a conflict
367+ * currently exist in the working copy, we want to allow it to
368+ * be removed to make room for the corresponding directory if
369+ * needed. The files underneath the directories of such D/F
370+ * conflicts will be handled in process_entry(), while the
371+ * files of such D/F conflicts will be processed later in
372+ * process_df_entry(). If the corresponding directory ends up
373+ * being removed by the merge, then no additional work needs
374+ * to be done by process_df_entry() for the conflicting file.
375+ * If the directory needs to be written to the working copy,
376+ * then the conflicting file will simply be removed (e.g. in
377+ * make_room_for_path). If the directory is written to the
378+ * working copy but the file also has a conflict that needs to
379+ * be resolved, then process_df_entry() will reinstate the
380+ * file with a new unique name.
377381 */
378382 const char * last_file = NULL ;
379383 int last_len = 0 ;
@@ -390,6 +394,7 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
390394 qsort (entries -> items , entries -> nr , sizeof (* entries -> items ),
391395 string_list_df_name_compare );
392396
397+ string_list_clear (& o -> df_conflict_file_set , 1 );
393398 for (i = 0 ; i < entries -> nr ; i ++ ) {
394399 const char * path = entries -> items [i ].string ;
395400 int len = strlen (path );
@@ -398,14 +403,15 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
398403 /*
399404 * Check if last_file & path correspond to a D/F conflict;
400405 * i.e. whether path is last_file+'/'+<something>.
401- * If so, remove last_file to make room for path and friends.
406+ * If so, record that it's okay to remove last_file to make
407+ * room for path and friends if needed.
402408 */
403409 if (last_file &&
404410 len > last_len &&
405411 memcmp (path , last_file , last_len ) == 0 &&
406412 path [last_len ] == '/' ) {
407413 output (o , 3 , "Removing %s to make room for subdirectory; may re-add later." , last_file );
408- unlink ( last_file );
414+ string_list_insert ( & o -> df_conflict_file_set , last_file );
409415 }
410416
411417 /*
@@ -1569,7 +1575,7 @@ int merge_trees(struct merge_options *o,
15691575 get_files_dirs (o , merge );
15701576
15711577 entries = get_unmerged ();
1572- make_room_for_directories_of_df_conflicts (o , entries );
1578+ record_df_conflict_files (o , entries );
15731579 re_head = get_renames (o , head , common , head , merge , entries );
15741580 re_merge = get_renames (o , merge , common , head , merge , entries );
15751581 clean = process_renames (o , re_head , re_merge );
@@ -1795,6 +1801,8 @@ void init_merge_options(struct merge_options *o)
17951801 o -> current_file_set .strdup_strings = 1 ;
17961802 memset (& o -> current_directory_set , 0 , sizeof (struct string_list ));
17971803 o -> current_directory_set .strdup_strings = 1 ;
1804+ memset (& o -> df_conflict_file_set , 0 , sizeof (struct string_list ));
1805+ o -> df_conflict_file_set .strdup_strings = 1 ;
17981806}
17991807
18001808int parse_merge_opt (struct merge_options * o , const char * s )
0 commit comments