11
11
12
12
static unsigned long garbage ;
13
13
static off_t size_garbage ;
14
+ static int verbose ;
15
+ static unsigned long loose , packed , packed_loose ;
16
+ static off_t loose_size ;
14
17
15
18
static void real_report_garbage (const char * desc , const char * path )
16
19
{
@@ -21,61 +24,31 @@ static void real_report_garbage(const char *desc, const char *path)
21
24
garbage ++ ;
22
25
}
23
26
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 )
28
28
{
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
+ }
35
32
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 ++ ;
78
44
}
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 ;
79
52
}
80
53
81
54
static char const * const count_objects_usage [] = {
@@ -85,12 +58,7 @@ static char const * const count_objects_usage[] = {
85
58
86
59
int cmd_count_objects (int argc , const char * * argv , const char * prefix )
87
60
{
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 ;
94
62
struct option opts [] = {
95
63
OPT__VERBOSE (& verbose , N_ ("be verbose" )),
96
64
OPT_BOOL ('H' , "human-readable" , & human_readable ,
@@ -104,19 +72,10 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
104
72
usage_with_options (count_objects_usage , opts );
105
73
if (verbose )
106
74
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
+
120
79
if (verbose ) {
121
80
struct packed_git * p ;
122
81
unsigned long num_pack = 0 ;
0 commit comments