Allows better help text to be defined than "be verbose". Also make use of the macro in places that already had a different description. No object code changes intended. Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
		
			
				
	
	
		
			131 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			131 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Builtin "git count-objects".
 | 
						|
 *
 | 
						|
 * Copyright (c) 2006 Junio C Hamano
 | 
						|
 */
 | 
						|
 | 
						|
#include "cache.h"
 | 
						|
#include "dir.h"
 | 
						|
#include "builtin.h"
 | 
						|
#include "parse-options.h"
 | 
						|
 | 
						|
static void count_objects(DIR *d, char *path, int len, int verbose,
 | 
						|
			  unsigned long *loose,
 | 
						|
			  off_t *loose_size,
 | 
						|
			  unsigned long *packed_loose,
 | 
						|
			  unsigned long *garbage)
 | 
						|
{
 | 
						|
	struct dirent *ent;
 | 
						|
	while ((ent = readdir(d)) != NULL) {
 | 
						|
		char hex[41];
 | 
						|
		unsigned char sha1[20];
 | 
						|
		const char *cp;
 | 
						|
		int bad = 0;
 | 
						|
 | 
						|
		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) += xsize_t(on_disk_bytes(st));
 | 
						|
		}
 | 
						|
		if (bad) {
 | 
						|
			if (verbose) {
 | 
						|
				error("garbage found: %.*s/%s",
 | 
						|
				      len + 2, path, ent->d_name);
 | 
						|
				(*garbage)++;
 | 
						|
			}
 | 
						|
			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 char const * const count_objects_usage[] = {
 | 
						|
	"git count-objects [-v]",
 | 
						|
	NULL
 | 
						|
};
 | 
						|
 | 
						|
int cmd_count_objects(int argc, const char **argv, const char *prefix)
 | 
						|
{
 | 
						|
	int i, verbose = 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, garbage = 0;
 | 
						|
	off_t loose_size = 0;
 | 
						|
	struct option opts[] = {
 | 
						|
		OPT__VERBOSE(&verbose, "be verbose"),
 | 
						|
		OPT_END(),
 | 
						|
	};
 | 
						|
 | 
						|
	argc = parse_options(argc, argv, prefix, opts, count_objects_usage, 0);
 | 
						|
	/* we do not take arguments other than flags for now */
 | 
						|
	if (argc)
 | 
						|
		usage_with_options(count_objects_usage, opts);
 | 
						|
	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, &garbage);
 | 
						|
		closedir(d);
 | 
						|
	}
 | 
						|
	if (verbose) {
 | 
						|
		struct packed_git *p;
 | 
						|
		unsigned long num_pack = 0;
 | 
						|
		off_t size_pack = 0;
 | 
						|
		if (!packed_git)
 | 
						|
			prepare_packed_git();
 | 
						|
		for (p = packed_git; p; p = p->next) {
 | 
						|
			if (!p->pack_local)
 | 
						|
				continue;
 | 
						|
			if (open_pack_index(p))
 | 
						|
				continue;
 | 
						|
			packed += p->num_objects;
 | 
						|
			size_pack += p->pack_size + p->index_size;
 | 
						|
			num_pack++;
 | 
						|
		}
 | 
						|
		printf("count: %lu\n", loose);
 | 
						|
		printf("size: %lu\n", (unsigned long) (loose_size / 1024));
 | 
						|
		printf("in-pack: %lu\n", packed);
 | 
						|
		printf("packs: %lu\n", num_pack);
 | 
						|
		printf("size-pack: %lu\n", (unsigned long) (size_pack / 1024));
 | 
						|
		printf("prune-packable: %lu\n", packed_loose);
 | 
						|
		printf("garbage: %lu\n", garbage);
 | 
						|
	}
 | 
						|
	else
 | 
						|
		printf("%lu objects, %lu kilobytes\n",
 | 
						|
		       loose, (unsigned long) (loose_size / 1024));
 | 
						|
	return 0;
 | 
						|
}
 |