Skip to content

Commit

Permalink
count-objects: use for_each_loose_file_in_objdir
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Oct 16, 2014
1 parent cac05d4 commit 4a1e693
Showing 1 changed file with 30 additions and 71 deletions.
101 changes: 30 additions & 71 deletions builtin/count-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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[] = {
Expand All @@ -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,
Expand All @@ -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;
Expand Down

0 comments on commit 4a1e693

Please sign in to comment.