31
return 0;
32
}
33
34
-static int prune_object(const char *fullpath, const unsigned char *sha1)
34
+static int prune_object(const unsigned char *sha1, const char *fullpath,
35
+ void *data)
36
{
37
struct stat st;
37
- if (lstat(fullpath, &st))
38
- return error("Could not stat '%s'", fullpath);
38
+
39
+ /*
40
+ * Do we know about this object?
41
+ * It must have been reachable
42
+ */
43
+ if (lookup_object(sha1))
44
+ return 0;
45
+
46
+ if (lstat(fullpath, &st)) {
47
+ /* report errors, but do not stop pruning */
48
+ error("Could not stat '%s'", fullpath);
49
+ return 0;
50
+ }
51
if (st.st_mtime > expire)
52
return 0;
53
if (show_only || verbose) {
60
return 0;
61
}
62
51
-static int prune_dir(int i, struct strbuf *path)
63
+static int prune_cruft(const char *basename, const char *path, void *data)
64
{
53
- size_t baselen = path->len;
54
- DIR *dir = opendir(path->buf);
55
- struct dirent *de;
56
-
57
- if (!dir)
58
- return 0;
59
-
60
- while ((de = readdir(dir)) != NULL) {
61
- char name[100];
62
- unsigned char sha1[20];
63
-
64
- if (is_dot_or_dotdot(de->d_name))
65
- continue;
66
- if (strlen(de->d_name) == 38) {
67
- sprintf(name, "%02x", i);
68
- memcpy(name+2, de->d_name, 39);
69
- if (get_sha1_hex(name, sha1) < 0)
70
- break;
71
-
72
- /*
73
- * Do we know about this object?
74
- * It must have been reachable
75
- */
76
- if (lookup_object(sha1))
77
- continue;
78
-
79
- strbuf_addf(path, "/%s", de->d_name);
80
- prune_object(path->buf, sha1);
81
- strbuf_setlen(path, baselen);
82
- continue;
83
- }
84
- if (starts_with(de->d_name, "tmp_obj_")) {
85
- strbuf_addf(path, "/%s", de->d_name);
86
- prune_tmp_file(path->buf);
87
- strbuf_setlen(path, baselen);
88
- continue;
89
- }
90
- fprintf(stderr, "bad sha1 file: %s/%s\n", path->buf, de->d_name);
91
- }
92
- closedir(dir);
93
- if (!show_only)
94
- rmdir(path->buf);
65
+ if (starts_with(basename, "tmp_obj_"))
66
+ prune_tmp_file(path);
67
+ else
68
+ fprintf(stderr, "bad sha1 file: %s\n", path);
69
return 0;
70
}
71
98
-static void prune_object_dir(const char *path)
72
+static int prune_subdir(int nr, const char *path, void *data)
73
{
100
- struct strbuf buf = STRBUF_INIT;
101
- size_t baselen;
102
- int i;
103
-
104
- strbuf_addstr(&buf, path);
105
- strbuf_addch(&buf, '/');
106
- baselen = buf.len;
107
-
108
- for (i = 0; i < 256; i++) {
109
- strbuf_addf(&buf, "%02x", i);
110
- prune_dir(i, &buf);
111
- strbuf_setlen(&buf, baselen);
112
- }
74
+ if (!show_only)
75
+ rmdir(path);
76
+ return 0;
77
}
78
79
/*
137
138
mark_reachable_objects(&revs, 1, progress);
139
stop_progress(&progress);
176
- prune_object_dir(get_object_directory());
140
+ for_each_loose_file_in_objdir(get_object_directory(), prune_object,
141
+ prune_cruft, prune_subdir, NULL);
142
143
prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0);
144
remove_temporary_files(get_object_directory());