1111#include "dir.h"
1212#include "packfile.h"
1313#include "help.h"
14- #include "archive.h"
15- #include "object-store.h"
16- #include "compat/disk.h"
14+ #include "diagnose.h"
1715
1816/*
1917 * Remove the deepest subdirectory in the provided path string. Path must not
@@ -263,53 +261,6 @@ static int unregister_dir(void)
263261 return res ;
264262}
265263
266- static int add_directory_to_archiver (struct strvec * archiver_args ,
267- const char * path , int recurse )
268- {
269- int at_root = !* path ;
270- DIR * dir ;
271- struct dirent * e ;
272- struct strbuf buf = STRBUF_INIT ;
273- size_t len ;
274- int res = 0 ;
275-
276- dir = opendir (at_root ? "." : path );
277- if (!dir ) {
278- if (errno == ENOENT ) {
279- warning (_ ("could not archive missing directory '%s'" ), path );
280- return 0 ;
281- }
282- return error_errno (_ ("could not open directory '%s'" ), path );
283- }
284-
285- if (!at_root )
286- strbuf_addf (& buf , "%s/" , path );
287- len = buf .len ;
288- strvec_pushf (archiver_args , "--prefix=%s" , buf .buf );
289-
290- while (!res && (e = readdir (dir ))) {
291- if (!strcmp ("." , e -> d_name ) || !strcmp (".." , e -> d_name ))
292- continue ;
293-
294- strbuf_setlen (& buf , len );
295- strbuf_addstr (& buf , e -> d_name );
296-
297- if (e -> d_type == DT_REG )
298- strvec_pushf (archiver_args , "--add-file=%s" , buf .buf );
299- else if (e -> d_type != DT_DIR )
300- warning (_ ("skipping '%s', which is neither file nor "
301- "directory" ), buf .buf );
302- else if (recurse &&
303- add_directory_to_archiver (archiver_args ,
304- buf .buf , recurse ) < 0 )
305- res = -1 ;
306- }
307-
308- closedir (dir );
309- strbuf_release (& buf );
310- return res ;
311- }
312-
313264/* printf-style interface, expects `<key>=<value>` argument */
314265static int set_config (const char * fmt , ...)
315266{
@@ -550,83 +501,6 @@ static int cmd_clone(int argc, const char **argv)
550501 return res ;
551502}
552503
553- static void dir_file_stats_objects (const char * full_path , size_t full_path_len ,
554- const char * file_name , void * data )
555- {
556- struct strbuf * buf = data ;
557- struct stat st ;
558-
559- if (!stat (full_path , & st ))
560- strbuf_addf (buf , "%-70s %16" PRIuMAX "\n" , file_name ,
561- (uintmax_t )st .st_size );
562- }
563-
564- static int dir_file_stats (struct object_directory * object_dir , void * data )
565- {
566- struct strbuf * buf = data ;
567-
568- strbuf_addf (buf , "Contents of %s:\n" , object_dir -> path );
569-
570- for_each_file_in_pack_dir (object_dir -> path , dir_file_stats_objects ,
571- data );
572-
573- return 0 ;
574- }
575-
576- static int count_files (char * path )
577- {
578- DIR * dir = opendir (path );
579- struct dirent * e ;
580- int count = 0 ;
581-
582- if (!dir )
583- return 0 ;
584-
585- while ((e = readdir (dir )) != NULL )
586- if (!is_dot_or_dotdot (e -> d_name ) && e -> d_type == DT_REG )
587- count ++ ;
588-
589- closedir (dir );
590- return count ;
591- }
592-
593- static void loose_objs_stats (struct strbuf * buf , const char * path )
594- {
595- DIR * dir = opendir (path );
596- struct dirent * e ;
597- int count ;
598- int total = 0 ;
599- unsigned char c ;
600- struct strbuf count_path = STRBUF_INIT ;
601- size_t base_path_len ;
602-
603- if (!dir )
604- return ;
605-
606- strbuf_addstr (buf , "Object directory stats for " );
607- strbuf_add_absolute_path (buf , path );
608- strbuf_addstr (buf , ":\n" );
609-
610- strbuf_add_absolute_path (& count_path , path );
611- strbuf_addch (& count_path , '/' );
612- base_path_len = count_path .len ;
613-
614- while ((e = readdir (dir )) != NULL )
615- if (!is_dot_or_dotdot (e -> d_name ) &&
616- e -> d_type == DT_DIR && strlen (e -> d_name ) == 2 &&
617- !hex_to_bytes (& c , e -> d_name , 1 )) {
618- strbuf_setlen (& count_path , base_path_len );
619- strbuf_addstr (& count_path , e -> d_name );
620- total += (count = count_files (count_path .buf ));
621- strbuf_addf (buf , "%s : %7d files\n" , e -> d_name , count );
622- }
623-
624- strbuf_addf (buf , "Total: %d loose objects" , total );
625-
626- strbuf_release (& count_path );
627- closedir (dir );
628- }
629-
630504static int cmd_diagnose (int argc , const char * * argv )
631505{
632506 struct option options [] = {
@@ -637,12 +511,8 @@ static int cmd_diagnose(int argc, const char **argv)
637511 NULL
638512 };
639513 struct strbuf zip_path = STRBUF_INIT ;
640- struct strvec archiver_args = STRVEC_INIT ;
641- char * * argv_copy = NULL ;
642- int stdout_fd = -1 , archiver_fd = -1 ;
643514 time_t now = time (NULL );
644515 struct tm tm ;
645- struct strbuf buf = STRBUF_INIT ;
646516 int res = 0 ;
647517
648518 argc = parse_options (argc , argv , NULL , options ,
@@ -663,79 +533,11 @@ static int cmd_diagnose(int argc, const char **argv)
663533 zip_path .buf );
664534 goto diagnose_cleanup ;
665535 }
666- stdout_fd = dup (1 );
667- if (stdout_fd < 0 ) {
668- res = error_errno (_ ("could not duplicate stdout" ));
669- goto diagnose_cleanup ;
670- }
671-
672- archiver_fd = xopen (zip_path .buf , O_CREAT | O_WRONLY | O_TRUNC , 0666 );
673- if (archiver_fd < 0 || dup2 (archiver_fd , 1 ) < 0 ) {
674- res = error_errno (_ ("could not redirect output" ));
675- goto diagnose_cleanup ;
676- }
677-
678- init_zip_archiver ();
679- strvec_pushl (& archiver_args , "scalar-diagnose" , "--format=zip" , NULL );
680-
681- strbuf_reset (& buf );
682- strbuf_addstr (& buf , "Collecting diagnostic info\n\n" );
683- get_version_info (& buf , 1 );
684-
685- strbuf_addf (& buf , "Enlistment root: %s\n" , the_repository -> worktree );
686- get_disk_info (& buf );
687- write_or_die (stdout_fd , buf .buf , buf .len );
688- strvec_pushf (& archiver_args ,
689- "--add-virtual-file=diagnostics.log:%.*s" ,
690- (int )buf .len , buf .buf );
691-
692- strbuf_reset (& buf );
693- strbuf_addstr (& buf , "--add-virtual-file=packs-local.txt:" );
694- dir_file_stats (the_repository -> objects -> odb , & buf );
695- foreach_alt_odb (dir_file_stats , & buf );
696- strvec_push (& archiver_args , buf .buf );
697-
698- strbuf_reset (& buf );
699- strbuf_addstr (& buf , "--add-virtual-file=objects-local.txt:" );
700- loose_objs_stats (& buf , ".git/objects" );
701- strvec_push (& archiver_args , buf .buf );
702-
703- if ((res = add_directory_to_archiver (& archiver_args , ".git" , 0 )) ||
704- (res = add_directory_to_archiver (& archiver_args , ".git/hooks" , 0 )) ||
705- (res = add_directory_to_archiver (& archiver_args , ".git/info" , 0 )) ||
706- (res = add_directory_to_archiver (& archiver_args , ".git/logs" , 1 )) ||
707- (res = add_directory_to_archiver (& archiver_args , ".git/objects/info" , 0 )))
708- goto diagnose_cleanup ;
709-
710- strvec_pushl (& archiver_args , "--prefix=" ,
711- oid_to_hex (the_hash_algo -> empty_tree ), "--" , NULL );
712-
713- /* `write_archive()` modifies the `argv` passed to it. Let it. */
714- argv_copy = xmemdupz (archiver_args .v ,
715- sizeof (char * ) * archiver_args .nr );
716- res = write_archive (archiver_args .nr , (const char * * )argv_copy , NULL ,
717- the_repository , NULL , 0 );
718- if (res ) {
719- error (_ ("failed to write archive" ));
720- goto diagnose_cleanup ;
721- }
722536
723- if (!res )
724- fprintf (stderr , "\n"
725- "Diagnostics complete.\n"
726- "All of the gathered info is captured in '%s'\n" ,
727- zip_path .buf );
537+ res = create_diagnostics_archive (& zip_path );
728538
729539diagnose_cleanup :
730- if (archiver_fd >= 0 ) {
731- close (1 );
732- dup2 (stdout_fd , 1 );
733- }
734- free (argv_copy );
735- strvec_clear (& archiver_args );
736540 strbuf_release (& zip_path );
737- strbuf_release (& buf );
738-
739541 return res ;
740542}
741543
0 commit comments