зеркало из https://github.com/microsoft/git.git
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:
Родитель
cac05d4dfd
Коммит
4a1e693a30
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче