@@ -47,6 +47,12 @@ enum {
4747 (CHECKOUT_ACTION__UPDATE_BLOB | CHECKOUT_ACTION__REMOVE ),
4848};
4949
50+ typedef struct {
51+ git_buf target_path ;
52+ size_t target_len ;
53+ git_buf tmp ;
54+ } checkout_buffers ;
55+
5056typedef struct {
5157 git_repository * repo ;
5258 git_iterator * target ;
@@ -61,9 +67,7 @@ typedef struct {
6167 git_vector update_conflicts ;
6268 git_vector * update_reuc ;
6369 git_vector * update_names ;
64- git_buf target_path ;
65- size_t target_len ;
66- git_buf tmp ;
70+ git_tlsdata_key buffers ;
6771 unsigned int strategy ;
6872 int can_symlink ;
6973 int respect_filemode ;
@@ -323,15 +327,16 @@ static int checkout_action_no_wd(
323327static int checkout_target_fullpath (
324328 git_buf * * out , checkout_data * data , const char * path )
325329{
326- git_buf_truncate (& data -> target_path , data -> target_len );
330+ checkout_buffers * buffers = git_tlsdata_get (data -> buffers );
331+ git_buf_truncate (& buffers -> target_path , buffers -> target_len );
327332
328- if (path && git_buf_puts (& data -> target_path , path ) < 0 )
333+ if (path && git_buf_puts (& buffers -> target_path , path ) < 0 )
329334 return -1 ;
330335
331- if (git_path_validate_workdir_buf (data -> repo , & data -> target_path ) < 0 )
336+ if (git_path_validate_workdir_buf (data -> repo , & buffers -> target_path ) < 0 )
332337 return -1 ;
333338
334- * out = & data -> target_path ;
339+ * out = & buffers -> target_path ;
335340
336341 return 0 ;
337342}
@@ -368,6 +373,7 @@ static int checkout_action_wd_only(
368373 bool remove = false;
369374 git_checkout_notify_t notify = GIT_CHECKOUT_NOTIFY_NONE ;
370375 const git_index_entry * wd = * wditem ;
376+ checkout_buffers * buffers = git_tlsdata_get (data -> buffers );
371377
372378 if (!git_pathspec__match (
373379 pathspec , wd -> path ,
@@ -423,8 +429,8 @@ static int checkout_action_wd_only(
423429
424430 /* copy the entry for issuing notification callback later */
425431 git_index_entry saved_wd = * wd ;
426- git_buf_sets (& data -> tmp , wd -> path );
427- saved_wd .path = data -> tmp .ptr ;
432+ git_buf_sets (& buffers -> tmp , wd -> path );
433+ saved_wd .path = buffers -> tmp .ptr ;
428434
429435 error = git_iterator_advance_over (
430436 wditem , & untracked_state , workdir );
@@ -1519,6 +1525,7 @@ static int blob_content_to_file(
15191525 git_filter_list * fl = NULL ;
15201526 int fd ;
15211527 int error = 0 ;
1528+ checkout_buffers * buffers = git_tlsdata_get (data -> buffers );
15221529
15231530 GIT_ASSERT (hint_path != NULL );
15241531
@@ -1536,7 +1543,7 @@ static int blob_content_to_file(
15361543 }
15371544
15381545 filter_session .attr_session = & data -> attr_session ;
1539- filter_session .temp_buf = & data -> tmp ;
1546+ filter_session .temp_buf = & buffers -> tmp ;
15401547
15411548 if (!data -> opts .disable_filters &&
15421549 (error = git_filter_list__load (
@@ -2088,6 +2095,7 @@ static int checkout_write_merge(
20882095 git_filter_list * fl = NULL ;
20892096 git_filter_session filter_session = GIT_FILTER_SESSION_INIT ;
20902097 int error = 0 ;
2098+ checkout_buffers * buffers = git_tlsdata_get (data -> buffers );
20912099
20922100 if (data -> opts .checkout_strategy & GIT_CHECKOUT_CONFLICT_STYLE_DIFF3 )
20932101 opts .flags |= GIT_MERGE_FILE_STYLE_DIFF3 ;
@@ -2137,7 +2145,7 @@ static int checkout_write_merge(
21372145 in_data .size = result .len ;
21382146
21392147 filter_session .attr_session = & data -> attr_session ;
2140- filter_session .temp_buf = & data -> tmp ;
2148+ filter_session .temp_buf = & buffers -> tmp ;
21412149
21422150 if ((error = git_filter_list__load (
21432151 & fl , data -> repo , NULL , result .path ,
@@ -2328,6 +2336,16 @@ static int checkout_extensions_update_index(checkout_data *data)
23282336 return error ;
23292337}
23302338
2339+ static void GIT_SYSTEM_CALL dispose_checkout_buffers (void * _buffers ) {
2340+ checkout_buffers * buffers = _buffers ;
2341+ if (buffers == NULL )
2342+ return ;
2343+
2344+ git_buf_dispose (& buffers -> target_path );
2345+ git_buf_dispose (& buffers -> tmp );
2346+ git__free (buffers );
2347+ }
2348+
23312349static void checkout_data_clear (checkout_data * data )
23322350{
23332351 if (data -> opts_free_baseline ) {
@@ -2344,8 +2362,11 @@ static void checkout_data_clear(checkout_data *data)
23442362 git__free (data -> pfx );
23452363 data -> pfx = NULL ;
23462364
2347- git_buf_dispose (& data -> target_path );
2348- git_buf_dispose (& data -> tmp );
2365+ if (data -> buffers ) {
2366+ dispose_checkout_buffers (git_tlsdata_get (data -> buffers ));
2367+ git_tlsdata_set (data -> buffers , NULL );
2368+ git_tlsdata_dispose (data -> buffers );
2369+ }
23492370
23502371 git_index_free (data -> index );
23512372 data -> index = NULL ;
@@ -2377,6 +2398,7 @@ static int checkout_data_init(
23772398 git_iterator * target ,
23782399 const git_checkout_options * proposed )
23792400{
2401+ checkout_buffers * buffers = NULL ;
23802402 int error = 0 ;
23812403 git_repository * repo = git_iterator_owner (target );
23822404
@@ -2525,22 +2547,37 @@ static int checkout_data_init(
25252547 git_config_entry_free (conflict_style );
25262548 }
25272549
2550+ if ((error = git_tlsdata_init (& data -> buffers , dispose_checkout_buffers )) < 0 )
2551+ goto cleanup ;
2552+
2553+ if ((buffers = git__malloc (sizeof (checkout_buffers ))) == NULL ) {
2554+ error = -1 ;
2555+ goto cleanup ;
2556+ }
2557+
25282558 if ((error = git_pool_init (& data -> pool , 1 )) < 0 ||
25292559 (error = git_vector_init (& data -> removes , 0 , git__strcmp_cb )) < 0 ||
25302560 (error = git_vector_init (& data -> remove_conflicts , 0 , NULL )) < 0 ||
25312561 (error = git_vector_init (& data -> update_conflicts , 0 , NULL )) < 0 ||
2532- (error = git_buf_puts (& data -> target_path , data -> opts .target_directory )) < 0 ||
2533- (error = git_path_to_dir (& data -> target_path )) < 0 ||
2562+ (error = git_buf_init (& buffers -> target_path , 0 )) < 0 ||
2563+ (error = git_buf_init (& buffers -> tmp , 0 )) < 0 ||
2564+ (error = git_tlsdata_set (data -> buffers , buffers )) < 0 ||
2565+ (error = git_buf_puts (& buffers -> target_path , data -> opts .target_directory )) < 0 ||
2566+ (error = git_path_to_dir (& buffers -> target_path )) < 0 ||
25342567 (error = git_strmap_new (& data -> mkdir_map )) < 0 )
25352568 goto cleanup ;
25362569
2537- data -> target_len = git_buf_len (& data -> target_path );
2570+ buffers -> target_len = git_buf_len (& buffers -> target_path );
25382571
25392572 git_attr_session__init (& data -> attr_session , data -> repo );
25402573
25412574cleanup :
2542- if (error < 0 )
2575+ if (error < 0 ) {
2576+ if (data -> buffers && buffers && git_tlsdata_get (data -> buffers ) == NULL )
2577+ dispose_checkout_buffers (buffers );
2578+
25432579 checkout_data_clear (data );
2580+ }
25442581
25452582 return error ;
25462583}
0 commit comments