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>
This commit is contained in:
Jeff King 2014-10-15 18:41:11 -04:00 коммит произвёл Junio C Hamano
Родитель cac05d4dfd
Коммит 4a1e693a30
1 изменённых файлов: 30 добавлений и 71 удалений

Просмотреть файл

@ -11,6 +11,9 @@
static unsigned long garbage;
static off_t size_garbage;
static int verbose;
static unsigned long loose, packed, packed_loose;
static off_t loose_size;
static void real_report_garbage(const char *desc, const char *path)
{
@ -21,61 +24,31 @@ static void real_report_garbage(const char *desc, const char *path)
garbage++;
}
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
off_t *loose_size,
unsigned long *packed_loose)
static void loose_garbage(const char *path)
{
struct dirent *ent;
while ((ent = readdir(d)) != NULL) {
char hex[41];
unsigned char sha1[20];
const char *cp;
int bad = 0;
if (verbose)
report_garbage("garbage found", path);
}
if (is_dot_or_dotdot(ent->d_name))
continue;
for (cp = ent->d_name; *cp; cp++) {
int ch = *cp;
if (('0' <= ch && ch <= '9') ||
('a' <= ch && ch <= 'f'))
continue;
bad = 1;
break;
}
if (cp - ent->d_name != 38)
bad = 1;
else {
struct stat st;
memcpy(path + len + 3, ent->d_name, 38);
path[len + 2] = '/';
path[len + 41] = 0;
if (lstat(path, &st) || !S_ISREG(st.st_mode))
bad = 1;
else
(*loose_size) += on_disk_bytes(st);
}
if (bad) {
if (verbose) {
struct strbuf sb = STRBUF_INIT;
strbuf_addf(&sb, "%.*s/%s",
len + 2, path, ent->d_name);
report_garbage("garbage found", sb.buf);
strbuf_release(&sb);
}
continue;
}
(*loose)++;
if (!verbose)
continue;
memcpy(hex, path+len, 2);
memcpy(hex+2, ent->d_name, 38);
hex[40] = 0;
if (get_sha1_hex(hex, sha1))
die("internal error");
if (has_sha1_pack(sha1))
(*packed_loose)++;
static int count_loose(const unsigned char *sha1, const char *path, void *data)
{
struct stat st;
if (lstat(path, &st) || !S_ISREG(st.st_mode))
loose_garbage(path);
else {
loose_size += on_disk_bytes(st);
loose++;
if (verbose && has_sha1_pack(sha1))
packed_loose++;
}
return 0;
}
static int count_cruft(const char *basename, const char *path, void *data)
{
loose_garbage(path);
return 0;
}
static char const * const count_objects_usage[] = {
@ -85,12 +58,7 @@ static char const * const count_objects_usage[] = {
int cmd_count_objects(int argc, const char **argv, const char *prefix)
{
int i, verbose = 0, human_readable = 0;
const char *objdir = get_object_directory();
int len = strlen(objdir);
char *path = xmalloc(len + 50);
unsigned long loose = 0, packed = 0, packed_loose = 0;
off_t loose_size = 0;
int human_readable = 0;
struct option opts[] = {
OPT__VERBOSE(&verbose, N_("be verbose")),
OPT_BOOL('H', "human-readable", &human_readable,
@ -104,19 +72,10 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
usage_with_options(count_objects_usage, opts);
if (verbose)
report_garbage = real_report_garbage;
memcpy(path, objdir, len);
if (len && objdir[len-1] != '/')
path[len++] = '/';
for (i = 0; i < 256; i++) {
DIR *d;
sprintf(path + len, "%02x", i);
d = opendir(path);
if (!d)
continue;
count_objects(d, path, len, verbose,
&loose, &loose_size, &packed_loose);
closedir(d);
}
for_each_loose_file_in_objdir(get_object_directory(),
count_loose, count_cruft, NULL, NULL);
if (verbose) {
struct packed_git *p;
unsigned long num_pack = 0;