Пример #1
0
static struct pack_list * add_pack(struct packed_git *p)
{
	struct pack_list l;
	unsigned long off = 0, step;
	const unsigned char *base;

	if (!p->pack_local && !(alt_odb || verbose))
		return NULL;

	l.pack = p;
	llist_init(&l.all_objects);

	if (open_pack_index(p))
		return NULL;

	base = p->index_data;
	base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
	step = the_hash_algo->rawsz + ((p->index_version < 2) ? 4 : 0);
	while (off < p->num_objects * step) {
		llist_insert_back(l.all_objects, (const struct object_id *)(base + off));
		off += step;
	}
	/* this list will be pruned in cmp_two_packs later */
	l.unique_objects = llist_copy(l.all_objects);
	if (p->pack_local)
		return pack_list_insert(&local_packs, &l);
	else
		return pack_list_insert(&altodb_packs, &l);
}
Пример #2
0
static int verify_one_pack(const char *path, unsigned int flags)
{
	char arg[PATH_MAX];
	int len;
	int verbose = flags & VERIFY_PACK_VERBOSE;
	int stat_only = flags & VERIFY_PACK_STAT_ONLY;
	struct packed_git *pack;
	int err;

	len = strlcpy(arg, path, PATH_MAX);
	if (len >= PATH_MAX)
		return error("name too long: %s", path);

	/*
	 * In addition to "foo.idx" we accept "foo.pack" and "foo";
	 * normalize these forms to "foo.idx" for add_packed_git().
	 */
	if (has_extension(arg, ".pack")) {
		strcpy(arg + len - 5, ".idx");
		len--;
	} else if (!has_extension(arg, ".idx")) {
		if (len + 4 >= PATH_MAX)
			return error("name too long: %s.idx", arg);
		strcpy(arg + len, ".idx");
		len += 4;
	}

	/*
	 * add_packed_git() uses our buffer (containing "foo.idx") to
	 * build the pack filename ("foo.pack").  Make sure it fits.
	 */
	if (len + 1 >= PATH_MAX) {
		arg[len - 4] = '\0';
		return error("name too long: %s.pack", arg);
	}

	pack = add_packed_git(arg, len, 1);
	if (!pack)
		return error("packfile %s not found.", arg);

	install_packed_git(pack);

	if (!stat_only)
		err = verify_pack(pack);
	else
		err = open_pack_index(pack);

	if (verbose || stat_only) {
		if (err)
			printf("%s: bad\n", pack->pack_name);
		else {
			show_pack_info(pack, flags);
			if (!stat_only)
				printf("%s: ok\n", pack->pack_name);
		}
	}

	return err;
}
Пример #3
0
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;
	unsigned long loose_size = 0;
	struct option opts[] = {
		OPT__VERBOSE(&verbose),
		OPT_END(),
	};

	argc = parse_options(argc, argv, 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;
		unsigned long 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", loose_size / 1024);
		printf("in-pack: %lu\n", packed);
		printf("packs: %lu\n", num_pack);
		printf("size-pack: %lu\n", size_pack / 1024);
		printf("prune-packable: %lu\n", packed_loose);
		printf("garbage: %lu\n", garbage);
	}
	else
		printf("%lu objects, %lu kilobytes\n",
		       loose, loose_size / 1024);
	return 0;
}
Пример #4
0
int cmd_fsck(int argc, const char **argv, const char *prefix)
{
	int i;
	struct alternate_object_database *alt;

	/* fsck knows how to handle missing promisor objects */
	fetch_if_missing = 0;

	errors_found = 0;
	check_replace_refs = 0;

	argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);

	fsck_walk_options.walk = mark_object;
	fsck_obj_options.walk = mark_used;
	fsck_obj_options.error_func = fsck_error_func;
	if (check_strict)
		fsck_obj_options.strict = 1;

	if (show_progress == -1)
		show_progress = isatty(2);
	if (verbose)
		show_progress = 0;

	if (write_lost_and_found) {
		check_full = 1;
		include_reflogs = 0;
	}

	if (name_objects)
		fsck_walk_options.object_names =
			xcalloc(1, sizeof(struct decoration));

	git_config(fsck_config, NULL);

	fsck_head_link();
	if (connectivity_only) {
		for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
		for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
	} else {
		struct alternate_object_database *alt_odb_list;

		fsck_object_dir(get_object_directory());

		prepare_alt_odb(the_repository);
		alt_odb_list = the_repository->objects->alt_odb_list;
		for (alt = alt_odb_list; alt; alt = alt->next)
			fsck_object_dir(alt->path);

		if (check_full) {
			struct packed_git *p;
			uint32_t total = 0, count = 0;
			struct progress *progress = NULL;

			if (show_progress) {
				for (p = get_packed_git(the_repository); p;
				     p = p->next) {
					if (open_pack_index(p))
						continue;
					total += p->num_objects;
				}

				progress = start_progress(_("Checking objects"), total);
			}
			for (p = get_packed_git(the_repository); p;
			     p = p->next) {
				/* verify gives error messages itself */
				if (verify_pack(p, fsck_obj_buffer,
						progress, count))
					errors_found |= ERROR_PACK;
				count += p->num_objects;
			}
			stop_progress(&progress);
		}
	}

	for (i = 0; i < argc; i++) {
		const char *arg = argv[i];
		struct object_id oid;
		if (!get_oid(arg, &oid)) {
			struct object *obj = lookup_object(oid.hash);

			if (!obj || !(obj->flags & HAS_OBJ)) {
				if (is_promisor_object(&oid))
					continue;
				error("%s: object missing", oid_to_hex(&oid));
				errors_found |= ERROR_OBJECT;
				continue;
			}

			obj->flags |= USED;
			if (name_objects)
				add_decoration(fsck_walk_options.object_names,
					obj, xstrdup(arg));
			mark_object_reachable(obj);
			continue;
		}
		error("invalid parameter: expected sha1, got '%s'", arg);
		errors_found |= ERROR_OBJECT;
	}

	/*
	 * If we've not been given any explicit head information, do the
	 * default ones from .git/refs. We also consider the index file
	 * in this case (ie this implies --cache).
	 */
	if (!argc) {
		get_default_heads();
		keep_cache_objects = 1;
	}

	if (keep_cache_objects) {
		verify_index_checksum = 1;
		verify_ce_order = 1;
		read_cache();
		for (i = 0; i < active_nr; i++) {
			unsigned int mode;
			struct blob *blob;
			struct object *obj;

			mode = active_cache[i]->ce_mode;
			if (S_ISGITLINK(mode))
				continue;
			blob = lookup_blob(&active_cache[i]->oid);
			if (!blob)
				continue;
			obj = &blob->object;
			obj->flags |= USED;
			if (name_objects)
				add_decoration(fsck_walk_options.object_names,
					obj,
					xstrfmt(":%s", active_cache[i]->name));
			mark_object_reachable(obj);
		}
		if (active_cache_tree)
			fsck_cache_tree(active_cache_tree);
	}

	check_connectivity();
	return errors_found;
}
Пример #5
0
int cmd_count_objects(int argc, const char **argv, const char *prefix)
{
    int human_readable = 0;
    struct option opts[] = {
        OPT__VERBOSE(&verbose, N_("be verbose")),
        OPT_BOOL('H', "human-readable", &human_readable,
        N_("print sizes in human readable format")),
        OPT_END(),
    };

    git_config(git_default_config, NULL);

    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);
    if (verbose) {
        report_garbage = real_report_garbage;
        report_linked_checkout_garbage();
    }

    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;
        off_t size_pack = 0;
        struct strbuf loose_buf = STRBUF_INIT;
        struct strbuf pack_buf = STRBUF_INIT;
        struct strbuf garbage_buf = STRBUF_INIT;
        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++;
        }

        if (human_readable) {
            strbuf_humanise_bytes(&loose_buf, loose_size);
            strbuf_humanise_bytes(&pack_buf, size_pack);
            strbuf_humanise_bytes(&garbage_buf, size_garbage);
        } else {
            strbuf_addf(&loose_buf, "%lu",
                        (unsigned long)(loose_size / 1024));
            strbuf_addf(&pack_buf, "%lu",
                        (unsigned long)(size_pack / 1024));
            strbuf_addf(&garbage_buf, "%lu",
                        (unsigned long)(size_garbage / 1024));
        }

        printf("count: %lu\n", loose);
        printf("size: %s\n", loose_buf.buf);
        printf("in-pack: %lu\n", packed);
        printf("packs: %lu\n", num_pack);
        printf("size-pack: %s\n", pack_buf.buf);
        printf("prune-packable: %lu\n", packed_loose);
        printf("garbage: %lu\n", garbage);
        printf("size-garbage: %s\n", garbage_buf.buf);
        foreach_alt_odb(print_alternate, NULL);
        strbuf_release(&loose_buf);
        strbuf_release(&pack_buf);
        strbuf_release(&garbage_buf);
    } else {
        struct strbuf buf = STRBUF_INIT;
        if (human_readable)
            strbuf_humanise_bytes(&buf, loose_size);
        else
            strbuf_addf(&buf, "%lu kilobytes",
                        (unsigned long)(loose_size / 1024));
        printf("%lu objects, %s\n", loose, buf.buf);
        strbuf_release(&buf);
    }
    return 0;
}