@@ -2176,9 +2176,15 @@ static int icase_exists(struct unpack_trees_options *o, const char *name, int le
21762176 return src && !ie_match_stat (o -> src_index , src , st , CE_MATCH_IGNORE_VALID |CE_MATCH_IGNORE_SKIP_WORKTREE );
21772177}
21782178
2179+ enum absent_checking_type {
2180+ COMPLETELY_ABSENT ,
2181+ ABSENT_ANY_DIRECTORY
2182+ };
2183+
21792184static int check_ok_to_remove (const char * name , int len , int dtype ,
21802185 const struct cache_entry * ce , struct stat * st ,
21812186 enum unpack_trees_error_types error_type ,
2187+ enum absent_checking_type absent_type ,
21822188 struct unpack_trees_options * o )
21832189{
21842190 const struct cache_entry * result ;
@@ -2213,6 +2219,10 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
22132219 return 0 ;
22142220 }
22152221
2222+ /* If we only care about directories, then we can remove */
2223+ if (absent_type == ABSENT_ANY_DIRECTORY )
2224+ return 0 ;
2225+
22162226 /*
22172227 * The previous round may already have decided to
22182228 * delete this path, which is in a subdirectory that
@@ -2233,6 +2243,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
22332243 */
22342244static int verify_absent_1 (const struct cache_entry * ce ,
22352245 enum unpack_trees_error_types error_type ,
2246+ enum absent_checking_type absent_type ,
22362247 struct unpack_trees_options * o )
22372248{
22382249 int len ;
@@ -2259,7 +2270,8 @@ static int verify_absent_1(const struct cache_entry *ce,
22592270 NULL , o );
22602271 else
22612272 ret = check_ok_to_remove (path , len , DT_UNKNOWN , NULL ,
2262- & st , error_type , o );
2273+ & st , error_type ,
2274+ absent_type , o );
22632275 }
22642276 free (path );
22652277 return ret ;
@@ -2274,7 +2286,7 @@ static int verify_absent_1(const struct cache_entry *ce,
22742286
22752287 return check_ok_to_remove (ce -> name , ce_namelen (ce ),
22762288 ce_to_dtype (ce ), ce , & st ,
2277- error_type , o );
2289+ error_type , absent_type , o );
22782290 }
22792291}
22802292
@@ -2284,14 +2296,23 @@ static int verify_absent(const struct cache_entry *ce,
22842296{
22852297 if (!o -> skip_sparse_checkout && (ce -> ce_flags & CE_NEW_SKIP_WORKTREE ))
22862298 return 0 ;
2287- return verify_absent_1 (ce , error_type , o );
2299+ return verify_absent_1 (ce , error_type , COMPLETELY_ABSENT , o );
2300+ }
2301+
2302+ static int verify_absent_if_directory (const struct cache_entry * ce ,
2303+ enum unpack_trees_error_types error_type ,
2304+ struct unpack_trees_options * o )
2305+ {
2306+ if (!o -> skip_sparse_checkout && (ce -> ce_flags & CE_NEW_SKIP_WORKTREE ))
2307+ return 0 ;
2308+ return verify_absent_1 (ce , error_type , ABSENT_ANY_DIRECTORY , o );
22882309}
22892310
22902311static int verify_absent_sparse (const struct cache_entry * ce ,
22912312 enum unpack_trees_error_types error_type ,
22922313 struct unpack_trees_options * o )
22932314{
2294- return verify_absent_1 (ce , error_type , o );
2315+ return verify_absent_1 (ce , error_type , COMPLETELY_ABSENT , o );
22952316}
22962317
22972318static int merged_entry (const struct cache_entry * ce ,
@@ -2365,6 +2386,12 @@ static int merged_entry(const struct cache_entry *ce,
23652386 * Previously unmerged entry left as an existence
23662387 * marker by read_index_unmerged();
23672388 */
2389+ if (verify_absent_if_directory (merge ,
2390+ ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN , o )) {
2391+ discard_cache_entry (merge );
2392+ return -1 ;
2393+ }
2394+
23682395 invalidate_ce_path (old , o );
23692396 }
23702397
0 commit comments