count-objects: use for_each_loose_file_in_objdir
This drops our line count considerably, and should make things more readable by keeping the counting logic separate from the traversal. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Oct 15, 2014 at 18:41 UTC
4a1e693a30c816fa5293c5f9e83e1e98ee87584e
1 file changed
+30
-71
builtin/count-objects.c
+30
-71
@@ -11,6 +11,9 @@
11
12
static unsigned long garbage;
13
static off_t size_garbage;
14
+static int verbose;
15
+static unsigned long loose, packed, packed_loose;
16
+static off_t loose_size;
17
18
static void real_report_garbage(const char *desc, const char *path)
19
{
@@ -21,61 +24,31 @@ static void real_report_garbage(const char *desc, const char *path)
24
garbage++;
25
}
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
{
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
+}
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++;
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;
52
}
53
54
static char const * const count_objects_usage[] = {
@@ -85,12 +58,7 @@ static char const * const count_objects_usage[] = {
58
59
int cmd_count_objects(int argc, const char **argv, const char *prefix)
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;
62
struct option opts[] = {
63
OPT__VERBOSE(&verbose, N_("be verbose")),
64
OPT_BOOL('H', "human-readable", &human_readable,
@@ -104,19 +72,10 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
72
usage_with_options(count_objects_usage, opts);
73
if (verbose)
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
+
79
if (verbose) {
80
struct packed_git *p;
81
unsigned long num_pack = 0;