@@ -2176,9 +2176,15 @@ static int icase_exists(struct unpack_trees_options *o, const char *name, int le
2176
2176
return src && !ie_match_stat (o -> src_index , src , st , CE_MATCH_IGNORE_VALID |CE_MATCH_IGNORE_SKIP_WORKTREE );
2177
2177
}
2178
2178
2179
+ enum absent_checking_type {
2180
+ COMPLETELY_ABSENT ,
2181
+ ABSENT_ANY_DIRECTORY
2182
+ };
2183
+
2179
2184
static int check_ok_to_remove (const char * name , int len , int dtype ,
2180
2185
const struct cache_entry * ce , struct stat * st ,
2181
2186
enum unpack_trees_error_types error_type ,
2187
+ enum absent_checking_type absent_type ,
2182
2188
struct unpack_trees_options * o )
2183
2189
{
2184
2190
const struct cache_entry * result ;
@@ -2213,6 +2219,10 @@ static int check_ok_to_remove(const char *name, int len, int dtype,
2213
2219
return 0 ;
2214
2220
}
2215
2221
2222
+ /* If we only care about directories, then we can remove */
2223
+ if (absent_type == ABSENT_ANY_DIRECTORY )
2224
+ return 0 ;
2225
+
2216
2226
/*
2217
2227
* The previous round may already have decided to
2218
2228
* 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,
2233
2243
*/
2234
2244
static int verify_absent_1 (const struct cache_entry * ce ,
2235
2245
enum unpack_trees_error_types error_type ,
2246
+ enum absent_checking_type absent_type ,
2236
2247
struct unpack_trees_options * o )
2237
2248
{
2238
2249
int len ;
@@ -2259,7 +2270,8 @@ static int verify_absent_1(const struct cache_entry *ce,
2259
2270
NULL , o );
2260
2271
else
2261
2272
ret = check_ok_to_remove (path , len , DT_UNKNOWN , NULL ,
2262
- & st , error_type , o );
2273
+ & st , error_type ,
2274
+ absent_type , o );
2263
2275
}
2264
2276
free (path );
2265
2277
return ret ;
@@ -2274,7 +2286,7 @@ static int verify_absent_1(const struct cache_entry *ce,
2274
2286
2275
2287
return check_ok_to_remove (ce -> name , ce_namelen (ce ),
2276
2288
ce_to_dtype (ce ), ce , & st ,
2277
- error_type , o );
2289
+ error_type , absent_type , o );
2278
2290
}
2279
2291
}
2280
2292
@@ -2284,14 +2296,23 @@ static int verify_absent(const struct cache_entry *ce,
2284
2296
{
2285
2297
if (!o -> skip_sparse_checkout && (ce -> ce_flags & CE_NEW_SKIP_WORKTREE ))
2286
2298
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 );
2288
2309
}
2289
2310
2290
2311
static int verify_absent_sparse (const struct cache_entry * ce ,
2291
2312
enum unpack_trees_error_types error_type ,
2292
2313
struct unpack_trees_options * o )
2293
2314
{
2294
- return verify_absent_1 (ce , error_type , o );
2315
+ return verify_absent_1 (ce , error_type , COMPLETELY_ABSENT , o );
2295
2316
}
2296
2317
2297
2318
static int merged_entry (const struct cache_entry * ce ,
@@ -2365,6 +2386,12 @@ static int merged_entry(const struct cache_entry *ce,
2365
2386
* Previously unmerged entry left as an existence
2366
2387
* marker by read_index_unmerged();
2367
2388
*/
2389
+ if (verify_absent_if_directory (merge ,
2390
+ ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN , o )) {
2391
+ discard_cache_entry (merge );
2392
+ return -1 ;
2393
+ }
2394
+
2368
2395
invalidate_ce_path (old , o );
2369
2396
}
2370
2397
0 commit comments