@@ -72,6 +72,39 @@ static int dir_file_stats(struct odb_source *source, void *data)
7272 return 0 ;
7373}
7474
75+ static void dir_stats (struct strbuf * buf , const char * path )
76+ {
77+ DIR * dir = opendir (path );
78+ struct dirent * e ;
79+ struct stat e_stat ;
80+ struct strbuf file_path = STRBUF_INIT ;
81+ size_t base_path_len ;
82+
83+ if (!dir )
84+ return ;
85+
86+ strbuf_addstr (buf , "Contents of " );
87+ strbuf_add_absolute_path (buf , path );
88+ strbuf_addstr (buf , ":\n" );
89+
90+ strbuf_add_absolute_path (& file_path , path );
91+ strbuf_addch (& file_path , '/' );
92+ base_path_len = file_path .len ;
93+
94+ while ((e = readdir (dir )) != NULL )
95+ if (!is_dot_or_dotdot (e -> d_name ) && e -> d_type == DT_REG ) {
96+ strbuf_setlen (& file_path , base_path_len );
97+ strbuf_addstr (& file_path , e -> d_name );
98+ if (!stat (file_path .buf , & e_stat ))
99+ strbuf_addf (buf , "%-70s %16" PRIuMAX "\n" ,
100+ e -> d_name ,
101+ (uintmax_t )e_stat .st_size );
102+ }
103+
104+ strbuf_release (& file_path );
105+ closedir (dir );
106+ }
107+
75108static int count_files (struct strbuf * path )
76109{
77110 DIR * dir = opendir (path -> buf );
@@ -187,7 +220,7 @@ int create_diagnostics_archive(struct repository *r,
187220 char * * argv_copy = NULL ;
188221 int stdout_fd = -1 , archiver_fd = -1 ;
189222 char * cache_server_url = NULL , * shared_cache = NULL ;
190- struct strbuf buf = STRBUF_INIT ;
223+ struct strbuf buf = STRBUF_INIT , path = STRBUF_INIT ;
191224 int res ;
192225 struct archive_dir archive_dirs [] = {
193226 { ".git" , 0 },
@@ -259,6 +292,52 @@ int create_diagnostics_archive(struct repository *r,
259292 }
260293 }
261294
295+ if (shared_cache ) {
296+ size_t path_len ;
297+
298+ strbuf_reset (& buf );
299+ strbuf_addf (& path , "%s/pack" , shared_cache );
300+ strbuf_reset (& buf );
301+ strbuf_addstr (& buf , "--add-virtual-file=packs-cached.txt:" );
302+ dir_stats (& buf , path .buf );
303+ strvec_push (& archiver_args , buf .buf );
304+
305+ strbuf_reset (& buf );
306+ strbuf_addstr (& buf , "--add-virtual-file=objects-cached.txt:" );
307+ loose_objs_stats (& buf , shared_cache );
308+ strvec_push (& archiver_args , buf .buf );
309+
310+ strbuf_reset (& path );
311+ strbuf_addf (& path , "%s/info" , shared_cache );
312+ path_len = path .len ;
313+
314+ if (is_directory (path .buf )) {
315+ DIR * dir = opendir (path .buf );
316+ struct dirent * e ;
317+
318+ while ((e = readdir (dir ))) {
319+ if (!strcmp ("." , e -> d_name ) || !strcmp (".." , e -> d_name ))
320+ continue ;
321+ if (e -> d_type == DT_DIR )
322+ continue ;
323+
324+ strbuf_reset (& buf );
325+ strbuf_addf (& buf , "--add-virtual-file=info/%s:" , e -> d_name );
326+
327+ strbuf_setlen (& path , path_len );
328+ strbuf_addch (& path , '/' );
329+ strbuf_addstr (& path , e -> d_name );
330+
331+ if (strbuf_read_file (& buf , path .buf , 0 ) < 0 ) {
332+ res = error_errno (_ ("could not read '%s'" ), path .buf );
333+ goto diagnose_cleanup ;
334+ }
335+ strvec_push (& archiver_args , buf .buf ); // CodeQL [SM01932] justification: CodeQL is wrong here because the value is read from a file via strbuf_read() which does NUL-terminate the string, something CodeQL fails to understand
336+ }
337+ closedir (dir );
338+ }
339+ }
340+
262341 strvec_pushl (& archiver_args , "--prefix=" ,
263342 oid_to_hex (r -> hash_algo -> empty_tree ), "--" , NULL );
264343
0 commit comments