@@ -1239,25 +1239,64 @@ static int checkout_mkdir(
12391239 return error ;
12401240}
12411241
1242+ static bool should_remove_existing (checkout_data * data )
1243+ {
1244+ int ignorecase = 0 ;
1245+
1246+ git_repository__cvar (& ignorecase , data -> repo , GIT_CVAR_IGNORECASE );
1247+
1248+ return (ignorecase &&
1249+ (data -> strategy & GIT_CHECKOUT_DONT_REMOVE_EXISTING ) == 0 );
1250+ }
1251+
1252+ #define MKDIR_NORMAL \
1253+ GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR
1254+ #define MKDIR_REMOVE_EXISTING \
1255+ MKDIR_NORMAL | GIT_MKDIR_REMOVE_FILES | GIT_MKDIR_REMOVE_SYMLINKS
1256+
12421257static int mkpath2file (
12431258 checkout_data * data , const char * path , unsigned int mode )
12441259{
12451260 git_buf * mkdir_path = & data -> tmp ;
1261+ struct stat st ;
1262+ bool remove_existing = should_remove_existing (data );
12461263 int error ;
12471264
12481265 if ((error = git_buf_sets (mkdir_path , path )) < 0 )
12491266 return error ;
12501267
12511268 git_buf_rtruncate_at_char (mkdir_path , '/' );
12521269
1253- if (data -> last_mkdir .size && mkdir_path -> size == data -> last_mkdir .size &&
1254- memcmp (mkdir_path -> ptr , data -> last_mkdir .ptr , mkdir_path -> size ) == 0 )
1255- return 0 ;
1270+ if (!data -> last_mkdir .size ||
1271+ data -> last_mkdir .size != mkdir_path -> size ||
1272+ memcmp (mkdir_path -> ptr , data -> last_mkdir .ptr , mkdir_path -> size ) != 0 ) {
1273+
1274+ if ((error = checkout_mkdir (
1275+ data , mkdir_path -> ptr , data -> opts .target_directory , mode ,
1276+ remove_existing ? MKDIR_REMOVE_EXISTING : MKDIR_NORMAL )) < 0 )
1277+ return error ;
12561278
1257- if ((error = checkout_mkdir (
1258- data , mkdir_path -> ptr , data -> opts .target_directory , mode ,
1259- GIT_MKDIR_PATH | GIT_MKDIR_VERIFY_DIR )) == 0 )
12601279 git_buf_swap (& data -> last_mkdir , mkdir_path );
1280+ }
1281+
1282+ if (remove_existing ) {
1283+ data -> perfdata .stat_calls ++ ;
1284+
1285+ if (p_lstat (path , & st ) == 0 ) {
1286+
1287+ /* Some file, symlink or folder already exists at this name.
1288+ * We would have removed it in remove_the_old unless we're on
1289+ * a case inensitive filesystem (or the user has asked us not
1290+ * to). Remove the similarly named file to write the new.
1291+ */
1292+ error = git_futils_rmdir_r (path , NULL , GIT_RMDIR_REMOVE_FILES );
1293+ } else if (errno != ENOENT ) {
1294+ giterr_set (GITERR_OS , "Failed to stat file '%s'" , path );
1295+ return GIT_EEXISTS ;
1296+ } else {
1297+ giterr_clear ();
1298+ }
1299+ }
12611300
12621301 return error ;
12631302}
@@ -1418,6 +1457,7 @@ static int checkout_submodule(
14181457 checkout_data * data ,
14191458 const git_diff_file * file )
14201459{
1460+ bool remove_existing = should_remove_existing (data );
14211461 int error = 0 ;
14221462
14231463 /* Until submodules are supported, UPDATE_ONLY means do nothing here */
@@ -1426,8 +1466,8 @@ static int checkout_submodule(
14261466
14271467 if ((error = checkout_mkdir (
14281468 data ,
1429- file -> path , data -> opts .target_directory ,
1430- data -> opts . dir_mode , GIT_MKDIR_PATH )) < 0 )
1469+ file -> path , data -> opts .target_directory , data -> opts . dir_mode ,
1470+ remove_existing ? MKDIR_REMOVE_EXISTING : MKDIR_NORMAL )) < 0 )
14311471 return error ;
14321472
14331473 if ((error = git_submodule_lookup (NULL , data -> repo , file -> path )) < 0 ) {
0 commit comments