11
11
#include "dir.h"
12
12
#include "packfile.h"
13
13
#include "help.h"
14
- #include "archive.h"
15
- #include "object-store.h"
16
- #include "compat/disk.h"
14
+ #include "diagnose.h"
17
15
18
16
/*
19
17
* Remove the deepest subdirectory in the provided path string. Path must not
@@ -263,53 +261,6 @@ static int unregister_dir(void)
263
261
return res ;
264
262
}
265
263
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
-
313
264
/* printf-style interface, expects `<key>=<value>` argument */
314
265
static int set_config (const char * fmt , ...)
315
266
{
@@ -550,83 +501,6 @@ static int cmd_clone(int argc, const char **argv)
550
501
return res ;
551
502
}
552
503
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
-
630
504
static int cmd_diagnose (int argc , const char * * argv )
631
505
{
632
506
struct option options [] = {
@@ -637,12 +511,8 @@ static int cmd_diagnose(int argc, const char **argv)
637
511
NULL
638
512
};
639
513
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 ;
643
514
time_t now = time (NULL );
644
515
struct tm tm ;
645
- struct strbuf buf = STRBUF_INIT ;
646
516
int res = 0 ;
647
517
648
518
argc = parse_options (argc , argv , NULL , options ,
@@ -663,79 +533,11 @@ static int cmd_diagnose(int argc, const char **argv)
663
533
zip_path .buf );
664
534
goto diagnose_cleanup ;
665
535
}
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
- }
722
536
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 );
728
538
729
539
diagnose_cleanup :
730
- if (archiver_fd >= 0 ) {
731
- close (1 );
732
- dup2 (stdout_fd , 1 );
733
- }
734
- free (argv_copy );
735
- strvec_clear (& archiver_args );
736
540
strbuf_release (& zip_path );
737
- strbuf_release (& buf );
738
-
739
541
return res ;
740
542
}
741
543
0 commit comments