@@ -65,6 +65,7 @@ typedef struct {
65
65
bool reload_submodules ;
66
66
size_t total_steps ;
67
67
size_t completed_steps ;
68
+ git_checkout_perfdata perfdata ;
68
69
} checkout_data ;
69
70
70
71
typedef struct {
@@ -1218,50 +1219,86 @@ static int checkout_get_actions(
1218
1219
return error ;
1219
1220
}
1220
1221
1222
+ static int checkout_mkdir (
1223
+ checkout_data * data ,
1224
+ const char * path ,
1225
+ const char * base ,
1226
+ mode_t mode ,
1227
+ unsigned int flags )
1228
+ {
1229
+ struct git_futils_mkdir_perfdata mkdir_perfdata = {0 };
1230
+
1231
+ int error = git_futils_mkdir_withperf (
1232
+ path , base , mode , flags , & mkdir_perfdata );
1233
+
1234
+ data -> perfdata .mkdir_calls += mkdir_perfdata .mkdir_calls ;
1235
+ data -> perfdata .stat_calls += mkdir_perfdata .stat_calls ;
1236
+ data -> perfdata .chmod_calls += mkdir_perfdata .chmod_calls ;
1237
+
1238
+ return error ;
1239
+ }
1240
+
1241
+ static int mkpath2file (
1242
+ checkout_data * data , const char * path , unsigned int mode )
1243
+ {
1244
+ return checkout_mkdir (
1245
+ data , path , git_repository_workdir (data -> repo ), mode ,
1246
+ GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR );
1247
+ }
1248
+
1221
1249
static int buffer_to_file (
1250
+ checkout_data * data ,
1222
1251
struct stat * st ,
1223
1252
git_buf * buf ,
1224
1253
const char * path ,
1225
- mode_t dir_mode ,
1226
- int file_open_flags ,
1227
1254
mode_t file_mode )
1228
1255
{
1229
1256
int error ;
1230
1257
1231
- if ((error = git_futils_mkpath2file ( path , dir_mode )) < 0 )
1258
+ if ((error = mkpath2file ( data , path , data -> opts . dir_mode )) < 0 )
1232
1259
return error ;
1233
1260
1234
1261
if ((error = git_futils_writebuffer (
1235
- buf , path , file_open_flags , file_mode )) < 0 )
1262
+ buf , path , data -> opts . file_open_flags , file_mode )) < 0 )
1236
1263
return error ;
1237
1264
1238
- if (st != NULL && (error = p_stat (path , st )) < 0 )
1239
- giterr_set (GITERR_OS , "Error statting '%s'" , path );
1265
+ if (st ) {
1266
+ data -> perfdata .stat_calls ++ ;
1267
+
1268
+ if ((error = p_stat (path , st )) < 0 ) {
1269
+ giterr_set (GITERR_OS , "Error statting '%s'" , path );
1270
+ return error ;
1271
+ }
1272
+ }
1240
1273
1241
- else if (GIT_PERMS_IS_EXEC (file_mode ) &&
1242
- (error = p_chmod (path , file_mode )) < 0 )
1243
- giterr_set (GITERR_OS , "Failed to set permissions on '%s'" , path );
1274
+ if (GIT_PERMS_IS_EXEC (file_mode )) {
1275
+ data -> perfdata .chmod_calls ++ ;
1276
+
1277
+ if ((error = p_chmod (path , file_mode )) < 0 )
1278
+ giterr_set (GITERR_OS , "Failed to set permissions on '%s'" , path );
1279
+ }
1244
1280
1245
1281
return error ;
1246
1282
}
1247
1283
1248
1284
static int blob_content_to_file (
1285
+ checkout_data * data ,
1249
1286
struct stat * st ,
1250
1287
git_blob * blob ,
1251
1288
const char * path ,
1252
1289
const char * hint_path ,
1253
- mode_t entry_filemode ,
1254
- git_checkout_options * opts )
1290
+ mode_t entry_filemode )
1255
1291
{
1256
- int error = 0 ;
1257
- mode_t file_mode = opts -> file_mode ? opts -> file_mode : entry_filemode ;
1292
+ mode_t file_mode = data -> opts . file_mode ?
1293
+ data -> opts . file_mode : entry_filemode ;
1258
1294
git_buf out = GIT_BUF_INIT ;
1259
1295
git_filter_list * fl = NULL ;
1296
+ int error = 0 ;
1260
1297
1261
1298
if (hint_path == NULL )
1262
1299
hint_path = path ;
1263
1300
1264
- if (!opts -> disable_filters )
1301
+ if (!data -> opts . disable_filters )
1265
1302
error = git_filter_list_load (
1266
1303
& fl , git_blob_owner (blob ), blob , hint_path ,
1267
1304
GIT_FILTER_TO_WORKTREE , GIT_FILTER_OPT_DEFAULT );
@@ -1272,9 +1309,7 @@ static int blob_content_to_file(
1272
1309
git_filter_list_free (fl );
1273
1310
1274
1311
if (!error ) {
1275
- error = buffer_to_file (
1276
- st , & out , path , opts -> dir_mode , opts -> file_open_flags , file_mode );
1277
-
1312
+ error = buffer_to_file (data , st , & out , path , file_mode );
1278
1313
st -> st_mode = entry_filemode ;
1279
1314
1280
1315
git_buf_free (& out );
@@ -1284,29 +1319,30 @@ static int blob_content_to_file(
1284
1319
}
1285
1320
1286
1321
static int blob_content_to_link (
1322
+ checkout_data * data ,
1287
1323
struct stat * st ,
1288
1324
git_blob * blob ,
1289
- const char * path ,
1290
- mode_t dir_mode ,
1291
- int can_symlink )
1325
+ const char * path )
1292
1326
{
1293
1327
git_buf linktarget = GIT_BUF_INIT ;
1294
1328
int error ;
1295
1329
1296
- if ((error = git_futils_mkpath2file ( path , dir_mode )) < 0 )
1330
+ if ((error = mkpath2file ( data , path , data -> opts . dir_mode )) < 0 )
1297
1331
return error ;
1298
1332
1299
1333
if ((error = git_blob__getbuf (& linktarget , blob )) < 0 )
1300
1334
return error ;
1301
1335
1302
- if (can_symlink ) {
1336
+ if (data -> can_symlink ) {
1303
1337
if ((error = p_symlink (git_buf_cstr (& linktarget ), path )) < 0 )
1304
1338
giterr_set (GITERR_OS , "Could not create symlink %s\n" , path );
1305
1339
} else {
1306
1340
error = git_futils_fake_symlink (git_buf_cstr (& linktarget ), path );
1307
1341
}
1308
1342
1309
1343
if (!error ) {
1344
+ data -> perfdata .stat_calls ++ ;
1345
+
1310
1346
if ((error = p_lstat (path , st )) < 0 )
1311
1347
giterr_set (GITERR_CHECKOUT , "Could not stat symlink %s" , path );
1312
1348
@@ -1350,6 +1386,7 @@ static int checkout_submodule_update_index(
1350
1386
if (git_buf_puts (& data -> path , file -> path ) < 0 )
1351
1387
return -1 ;
1352
1388
1389
+ data -> perfdata .stat_calls ++ ;
1353
1390
if (p_stat (git_buf_cstr (& data -> path ), & st ) < 0 ) {
1354
1391
giterr_set (
1355
1392
GITERR_CHECKOUT , "Could not stat submodule %s\n" , file -> path );
@@ -1371,7 +1408,8 @@ static int checkout_submodule(
1371
1408
if ((data -> strategy & GIT_CHECKOUT_UPDATE_ONLY ) != 0 )
1372
1409
return 0 ;
1373
1410
1374
- if ((error = git_futils_mkdir (
1411
+ if ((error = checkout_mkdir (
1412
+ data ,
1375
1413
file -> path , data -> opts .target_directory ,
1376
1414
data -> opts .dir_mode , GIT_MKDIR_PATH )) < 0 )
1377
1415
return error ;
@@ -1410,10 +1448,13 @@ static void report_progress(
1410
1448
data -> opts .progress_payload );
1411
1449
}
1412
1450
1413
- static int checkout_safe_for_update_only (const char * path , mode_t expected_mode )
1451
+ static int checkout_safe_for_update_only (
1452
+ checkout_data * data , const char * path , mode_t expected_mode )
1414
1453
{
1415
1454
struct stat st ;
1416
1455
1456
+ data -> perfdata .stat_calls ++ ;
1457
+
1417
1458
if (p_lstat (path , & st ) < 0 ) {
1418
1459
/* if doesn't exist, then no error and no update */
1419
1460
if (errno == ENOENT || errno == ENOTDIR )
@@ -1446,11 +1487,9 @@ static int checkout_write_content(
1446
1487
return error ;
1447
1488
1448
1489
if (S_ISLNK (mode ))
1449
- error = blob_content_to_link (
1450
- st , blob , full_path , data -> opts .dir_mode , data -> can_symlink );
1490
+ error = blob_content_to_link (data , st , blob , full_path );
1451
1491
else
1452
- error = blob_content_to_file (
1453
- st , blob , full_path , hint_path , mode , & data -> opts );
1492
+ error = blob_content_to_file (data , st , blob , full_path , hint_path , mode );
1454
1493
1455
1494
git_blob_free (blob );
1456
1495
@@ -1481,7 +1520,7 @@ static int checkout_blob(
1481
1520
1482
1521
if ((data -> strategy & GIT_CHECKOUT_UPDATE_ONLY ) != 0 ) {
1483
1522
int rval = checkout_safe_for_update_only (
1484
- git_buf_cstr (& data -> path ), file -> mode );
1523
+ data , git_buf_cstr (& data -> path ), file -> mode );
1485
1524
if (rval <= 0 )
1486
1525
return rval ;
1487
1526
}
@@ -1736,7 +1775,7 @@ static int checkout_write_entry(
1736
1775
}
1737
1776
1738
1777
if ((data -> strategy & GIT_CHECKOUT_UPDATE_ONLY ) != 0 &&
1739
- (error = checkout_safe_for_update_only (git_buf_cstr (& data -> path ), side -> mode )) <= 0 )
1778
+ (error = checkout_safe_for_update_only (data , git_buf_cstr (& data -> path ), side -> mode )) <= 0 )
1740
1779
return error ;
1741
1780
1742
1781
return checkout_write_content (data ,
@@ -1835,7 +1874,7 @@ static int checkout_write_merge(
1835
1874
goto done ;
1836
1875
1837
1876
if ((data -> strategy & GIT_CHECKOUT_UPDATE_ONLY ) != 0 &&
1838
- (error = checkout_safe_for_update_only (git_buf_cstr (& path_workdir ), result .mode )) <= 0 )
1877
+ (error = checkout_safe_for_update_only (data , git_buf_cstr (& path_workdir ), result .mode )) <= 0 )
1839
1878
goto done ;
1840
1879
1841
1880
if (!data -> opts .disable_filters ) {
@@ -1851,7 +1890,7 @@ static int checkout_write_merge(
1851
1890
out_data .size = result .len ;
1852
1891
}
1853
1892
1854
- if ((error = git_futils_mkpath2file ( path_workdir .ptr , 0755 )) < 0 ||
1893
+ if ((error = mkpath2file ( data , path_workdir .ptr , data -> opts . dir_mode )) < 0 ||
1855
1894
(error = git_filebuf_open (& output , git_buf_cstr (& path_workdir ), GIT_FILEBUF_DO_NOT_BUFFER , result .mode )) < 0 ||
1856
1895
(error = git_filebuf_write (& output , out_data .ptr , out_data .size )) < 0 ||
1857
1896
(error = git_filebuf_commit (& output )) < 0 )
@@ -2056,8 +2095,9 @@ static int checkout_data_init(
2056
2095
if (!data -> opts .target_directory )
2057
2096
data -> opts .target_directory = git_repository_workdir (repo );
2058
2097
else if (!git_path_isdir (data -> opts .target_directory ) &&
2059
- (error = git_futils_mkdir (data -> opts .target_directory , NULL ,
2060
- GIT_DIR_MODE , GIT_MKDIR_VERIFY_DIR )) < 0 )
2098
+ (error = checkout_mkdir (data ,
2099
+ data -> opts .target_directory , NULL ,
2100
+ GIT_DIR_MODE , GIT_MKDIR_VERIFY_DIR )) < 0 )
2061
2101
goto cleanup ;
2062
2102
2063
2103
/* refresh config and index content unless NO_REFRESH is given */
0 commit comments