@@ -591,6 +591,30 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
591591 }
592592}
593593
594+ static int dir_in_way (const char * path , int check_working_copy )
595+ {
596+ int pos , pathlen = strlen (path );
597+ char * dirpath = xmalloc (pathlen + 2 );
598+ struct stat st ;
599+
600+ strcpy (dirpath , path );
601+ dirpath [pathlen ] = '/' ;
602+ dirpath [pathlen + 1 ] = '\0' ;
603+
604+ pos = cache_name_pos (dirpath , pathlen + 1 );
605+
606+ if (pos < 0 )
607+ pos = -1 - pos ;
608+ if (pos < active_nr &&
609+ !strncmp (dirpath , active_cache [pos ]-> name , pathlen + 1 )) {
610+ free (dirpath );
611+ return 1 ;
612+ }
613+
614+ free (dirpath );
615+ return check_working_copy && !lstat (path , & st ) && S_ISDIR (st .st_mode );
616+ }
617+
594618static int would_lose_untracked (const char * path )
595619{
596620 int pos = cache_name_pos (path , strlen (path ));
@@ -880,7 +904,6 @@ static void conflict_rename_delete(struct merge_options *o,
880904{
881905 char * dest_name = pair -> two -> path ;
882906 int df_conflict = 0 ;
883- struct stat st ;
884907
885908 output (o , 1 , "CONFLICT (rename/delete): Rename %s->%s in %s "
886909 "and deleted in %s" ,
@@ -890,7 +913,7 @@ static void conflict_rename_delete(struct merge_options *o,
890913 update_stages (dest_name , NULL ,
891914 rename_branch == o -> branch1 ? pair -> two : NULL ,
892915 rename_branch == o -> branch1 ? NULL : pair -> two );
893- if (lstat (dest_name , & st ) == 0 && S_ISDIR ( st . st_mode )) {
916+ if (dir_in_way (dest_name , ! o -> call_depth )) {
894917 dest_name = unique_path (o , dest_name , rename_branch );
895918 df_conflict = 1 ;
896919 }
@@ -912,13 +935,12 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
912935 const char * ren2_dst = pair2 -> two -> path ;
913936 const char * dst_name1 = ren1_dst ;
914937 const char * dst_name2 = ren2_dst ;
915- struct stat st ;
916- if (lstat (ren1_dst , & st ) == 0 && S_ISDIR (st .st_mode )) {
938+ if (dir_in_way (ren1_dst , !o -> call_depth )) {
917939 dst_name1 = del [delp ++ ] = unique_path (o , ren1_dst , branch1 );
918940 output (o , 1 , "%s is a directory in %s adding as %s instead" ,
919941 ren1_dst , branch2 , dst_name1 );
920942 }
921- if (lstat (ren2_dst , & st ) == 0 && S_ISDIR ( st . st_mode )) {
943+ if (dir_in_way (ren2_dst , ! o -> call_depth )) {
922944 dst_name2 = del [delp ++ ] = unique_path (o , ren2_dst , branch2 );
923945 output (o , 1 , "%s is a directory in %s adding as %s instead" ,
924946 ren2_dst , branch1 , dst_name2 );
@@ -1078,7 +1100,7 @@ static int process_renames(struct merge_options *o,
10781100 try_merge = 0 ;
10791101
10801102 if (sha_eq (src_other .sha1 , null_sha1 )) {
1081- if (string_list_has_string ( & o -> current_directory_set , ren1_dst )) {
1103+ if (dir_in_way ( ren1_dst , 0 /*check_wc*/ )) {
10821104 ren1 -> dst_entry -> processed = 0 ;
10831105 setup_rename_df_conflict_info (RENAME_DELETE ,
10841106 ren1 -> pair ,
@@ -1157,7 +1179,7 @@ static int process_renames(struct merge_options *o,
11571179 a = & src_other ;
11581180 }
11591181 update_stages_and_entry (ren1_dst , ren1 -> dst_entry , one , a , b , 1 );
1160- if (string_list_has_string ( & o -> current_directory_set , ren1_dst )) {
1182+ if (dir_in_way ( ren1_dst , 0 /*check_wc*/ )) {
11611183 setup_rename_df_conflict_info (RENAME_NORMAL ,
11621184 ren1 -> pair ,
11631185 NULL ,
@@ -1262,7 +1284,6 @@ static int merge_content(struct merge_options *o,
12621284 const char * reason = "content" ;
12631285 struct merge_file_info mfi ;
12641286 struct diff_filespec one , a , b ;
1265- struct stat st ;
12661287 unsigned df_conflict_remains = 0 ;
12671288
12681289 if (!o_sha ) {
@@ -1279,7 +1300,7 @@ static int merge_content(struct merge_options *o,
12791300
12801301 mfi = merge_file (o , & one , & a , & b , o -> branch1 , o -> branch2 );
12811302 if (df_rename_conflict_branch &&
1282- lstat (path , & st ) == 0 && S_ISDIR ( st . st_mode )) {
1303+ dir_in_way (path , ! o -> call_depth )) {
12831304 df_conflict_remains = 1 ;
12841305 }
12851306
@@ -1344,8 +1365,7 @@ static int process_entry(struct merge_options *o,
13441365 output (o , 2 , "Removing %s" , path );
13451366 /* do not touch working file if it did not exist */
13461367 remove_file (o , 1 , path , !a_sha );
1347- } else if (string_list_has_string (& o -> current_directory_set ,
1348- path )) {
1368+ } else if (dir_in_way (path , 0 /*check_wc*/ )) {
13491369 entry -> processed = 0 ;
13501370 return 1 ; /* Assume clean until processed */
13511371 } else {
@@ -1368,7 +1388,7 @@ static int process_entry(struct merge_options *o,
13681388 mode = b_mode ;
13691389 sha = b_sha ;
13701390 }
1371- if (string_list_has_string ( & o -> current_directory_set , path )) {
1391+ if (dir_in_way ( path , 0 /*check_wc*/ )) {
13721392 /* Handle D->F conflicts after all subfiles */
13731393 entry -> processed = 0 ;
13741394 return 1 ; /* Assume clean until processed */
@@ -1416,7 +1436,6 @@ static int process_df_entry(struct merge_options *o,
14161436 unsigned char * o_sha = stage_sha (entry -> stages [1 ].sha , o_mode );
14171437 unsigned char * a_sha = stage_sha (entry -> stages [2 ].sha , a_mode );
14181438 unsigned char * b_sha = stage_sha (entry -> stages [3 ].sha , b_mode );
1419- struct stat st ;
14201439
14211440 entry -> processed = 1 ;
14221441 if (entry -> rename_df_conflict_info ) {
@@ -1461,7 +1480,7 @@ static int process_df_entry(struct merge_options *o,
14611480 } else if (o_sha && (!a_sha || !b_sha )) {
14621481 /* Modify/delete; deleted side may have put a directory in the way */
14631482 char * renamed = NULL ;
1464- if (lstat (path , & st ) == 0 && S_ISDIR ( st . st_mode )) {
1483+ if (dir_in_way (path , ! o -> call_depth )) {
14651484 renamed = unique_path (o , path , a_sha ? o -> branch1 : o -> branch2 );
14661485 }
14671486 clean_merge = 0 ;
@@ -1489,7 +1508,7 @@ static int process_df_entry(struct merge_options *o,
14891508 sha = b_sha ;
14901509 conf = "directory/file" ;
14911510 }
1492- if (lstat (path , & st ) == 0 && S_ISDIR ( st . st_mode )) {
1511+ if (dir_in_way (path , ! o -> call_depth )) {
14931512 char * new_path = unique_path (o , path , add_branch );
14941513 clean_merge = 0 ;
14951514 output (o , 1 , "CONFLICT (%s): There is a directory with name %s in %s. "
0 commit comments