1111
1212static unsigned long garbage ;
1313static off_t size_garbage ;
14+ static int verbose ;
15+ static unsigned long loose , packed , packed_loose ;
16+ static off_t loose_size ;
1417
1518static void real_report_garbage (const char * desc , const char * path )
1619{
@@ -21,61 +24,31 @@ static void real_report_garbage(const char *desc, const char *path)
2124 garbage ++ ;
2225}
2326
24- static void count_objects (DIR * d , char * path , int len , int verbose ,
25- unsigned long * loose ,
26- off_t * loose_size ,
27- unsigned long * packed_loose )
27+ static void loose_garbage (const char * path )
2828{
29- struct dirent * ent ;
30- while ((ent = readdir (d )) != NULL ) {
31- char hex [41 ];
32- unsigned char sha1 [20 ];
33- const char * cp ;
34- int bad = 0 ;
29+ if (verbose )
30+ report_garbage ("garbage found" , path );
31+ }
3532
36- if (is_dot_or_dotdot (ent -> d_name ))
37- continue ;
38- for (cp = ent -> d_name ; * cp ; cp ++ ) {
39- int ch = * cp ;
40- if (('0' <= ch && ch <= '9' ) ||
41- ('a' <= ch && ch <= 'f' ))
42- continue ;
43- bad = 1 ;
44- break ;
45- }
46- if (cp - ent -> d_name != 38 )
47- bad = 1 ;
48- else {
49- struct stat st ;
50- memcpy (path + len + 3 , ent -> d_name , 38 );
51- path [len + 2 ] = '/' ;
52- path [len + 41 ] = 0 ;
53- if (lstat (path , & st ) || !S_ISREG (st .st_mode ))
54- bad = 1 ;
55- else
56- (* loose_size ) += on_disk_bytes (st );
57- }
58- if (bad ) {
59- if (verbose ) {
60- struct strbuf sb = STRBUF_INIT ;
61- strbuf_addf (& sb , "%.*s/%s" ,
62- len + 2 , path , ent -> d_name );
63- report_garbage ("garbage found" , sb .buf );
64- strbuf_release (& sb );
65- }
66- continue ;
67- }
68- (* loose )++ ;
69- if (!verbose )
70- continue ;
71- memcpy (hex , path + len , 2 );
72- memcpy (hex + 2 , ent -> d_name , 38 );
73- hex [40 ] = 0 ;
74- if (get_sha1_hex (hex , sha1 ))
75- die ("internal error" );
76- if (has_sha1_pack (sha1 ))
77- (* packed_loose )++ ;
33+ static int count_loose (const unsigned char * sha1 , const char * path , void * data )
34+ {
35+ struct stat st ;
36+
37+ if (lstat (path , & st ) || !S_ISREG (st .st_mode ))
38+ loose_garbage (path );
39+ else {
40+ loose_size += on_disk_bytes (st );
41+ loose ++ ;
42+ if (verbose && has_sha1_pack (sha1 ))
43+ packed_loose ++ ;
7844 }
45+ return 0 ;
46+ }
47+
48+ static int count_cruft (const char * basename , const char * path , void * data )
49+ {
50+ loose_garbage (path );
51+ return 0 ;
7952}
8053
8154static char const * const count_objects_usage [] = {
@@ -85,12 +58,7 @@ static char const * const count_objects_usage[] = {
8558
8659int cmd_count_objects (int argc , const char * * argv , const char * prefix )
8760{
88- int i , verbose = 0 , human_readable = 0 ;
89- const char * objdir = get_object_directory ();
90- int len = strlen (objdir );
91- char * path = xmalloc (len + 50 );
92- unsigned long loose = 0 , packed = 0 , packed_loose = 0 ;
93- off_t loose_size = 0 ;
61+ int human_readable = 0 ;
9462 struct option opts [] = {
9563 OPT__VERBOSE (& verbose , N_ ("be verbose" )),
9664 OPT_BOOL ('H' , "human-readable" , & human_readable ,
@@ -104,19 +72,10 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
10472 usage_with_options (count_objects_usage , opts );
10573 if (verbose )
10674 report_garbage = real_report_garbage ;
107- memcpy (path , objdir , len );
108- if (len && objdir [len - 1 ] != '/' )
109- path [len ++ ] = '/' ;
110- for (i = 0 ; i < 256 ; i ++ ) {
111- DIR * d ;
112- sprintf (path + len , "%02x" , i );
113- d = opendir (path );
114- if (!d )
115- continue ;
116- count_objects (d , path , len , verbose ,
117- & loose , & loose_size , & packed_loose );
118- closedir (d );
119- }
75+
76+ for_each_loose_file_in_objdir (get_object_directory (),
77+ count_loose , count_cruft , NULL , NULL );
78+
12079 if (verbose ) {
12180 struct packed_git * p ;
12281 unsigned long num_pack = 0 ;
0 commit comments