* jc/count:
  builtin-count-objects: open packs when running -v
  builtin-count-objects: make it official.
  built-in count-objects.
This commit is contained in:
Junio C Hamano 2006-05-03 23:40:39 -07:00
Родитель 5dfde87156 80fe7d2b54
Коммит d820f91871
6 изменённых файлов: 141 добавлений и 35 удалений

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

@ -7,13 +7,23 @@ git-count-objects - Reports on unpacked objects
SYNOPSIS SYNOPSIS
-------- --------
'git-count-objects' 'git-count-objects' [-v]
DESCRIPTION DESCRIPTION
----------- -----------
This counts the number of unpacked object files and disk space consumed by This counts the number of unpacked object files and disk space consumed by
them, to help you decide when it is a good time to repack. them, to help you decide when it is a good time to repack.
OPTIONS
-------
-v::
In addition to the number of loose objects and disk
space consumed, it reports the number of in-pack
objects, and number of objects that can be removed by
running `git-prune-packed`.
Author Author
------ ------
Written by Junio C Hamano <junkio@cox.net> Written by Junio C Hamano <junkio@cox.net>

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

@ -115,7 +115,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
SCRIPT_SH = \ SCRIPT_SH = \
git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \ git-add.sh git-bisect.sh git-branch.sh git-checkout.sh \
git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \ git-cherry.sh git-clean.sh git-clone.sh git-commit.sh \
git-count-objects.sh git-diff.sh git-fetch.sh \ git-diff.sh git-fetch.sh \
git-format-patch.sh git-ls-remote.sh \ git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \ git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-rebase.sh \ git-prune.sh git-pull.sh git-rebase.sh \
@ -168,7 +168,7 @@ PROGRAMS = \
git-describe$X git-merge-tree$X git-blame$X git-imap-send$X git-describe$X git-merge-tree$X git-blame$X git-imap-send$X
BUILT_INS = git-log$X \ BUILT_INS = git-log$X \
git-push$X git-count-objects$X git-push$X
# what 'all' will build and 'install' will install, in gitexecdir # what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS) ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@ -215,7 +215,7 @@ LIB_OBJS = \
$(DIFF_OBJS) $(DIFF_OBJS)
BUILTIN_OBJS = \ BUILTIN_OBJS = \
builtin-log.o builtin-help.o builtin-push.o builtin-log.o builtin-help.o builtin-count.o builtin-push.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB) GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz LIBS = $(GITLIBS) -lz

125
builtin-count.c Normal file
Просмотреть файл

@ -0,0 +1,125 @@
/*
* Builtin "git count-objects".
*
* Copyright (c) 2006 Junio C Hamano
*/
#include "cache.h"
#include "builtin.h"
static const char count_objects_usage[] = "git-count-objects [-v]";
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
unsigned long *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 ((ent->d_name[0] == '.') &&
(ent->d_name[1] == 0 ||
((ent->d_name[1] == '.') && (ent->d_name[2] == 0))))
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) += st.st_blocks;
}
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)++;
}
}
int cmd_count_objects(int ac, const char **av, char **ep)
{
int i;
int 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;
for (i = 1; i < ac; i++) {
const char *arg = av[i];
if (*arg != '-')
break;
else if (!strcmp(arg, "-v"))
verbose = 1;
else
usage(count_objects_usage);
}
/* we do not take arguments other than flags for now */
if (i < ac)
usage(count_objects_usage);
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;
if (!packed_git)
prepare_packed_git();
for (p = packed_git; p; p = p->next) {
if (!p->pack_local)
continue;
packed += num_packed_objects(p);
}
printf("count: %lu\n", loose);
printf("size: %lu\n", loose_size / 2);
printf("in-pack: %lu\n", packed);
printf("prune-packable: %lu\n", packed_loose);
printf("garbage: %lu\n", garbage);
}
else
printf("%lu objects, %lu kilobytes\n",
loose, loose_size / 2);
return 0;
}

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

@ -19,6 +19,7 @@ extern int cmd_version(int argc, const char **argv, char **envp);
extern int cmd_whatchanged(int argc, const char **argv, char **envp); extern int cmd_whatchanged(int argc, const char **argv, char **envp);
extern int cmd_show(int argc, const char **argv, char **envp); extern int cmd_show(int argc, const char **argv, char **envp);
extern int cmd_log(int argc, const char **argv, char **envp); extern int cmd_log(int argc, const char **argv, char **envp);
extern int cmd_count_objects(int argc, const char **argv, char **envp);
extern int cmd_push(int argc, const char **argv, char **envp); extern int cmd_push(int argc, const char **argv, char **envp);

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

@ -1,31 +0,0 @@
#!/bin/sh
#
# Copyright (c) 2005 Junio C Hamano
#
GIT_DIR=`git-rev-parse --git-dir` || exit $?
dc </dev/null 2>/dev/null || {
# This is not a real DC at all -- it just knows how
# this script feeds DC and does the computation itself.
dc () {
while read a b
do
case $a,$b in
0,) acc=0 ;;
*,+) acc=$(($acc + $a)) ;;
p,) echo "$acc" ;;
esac
done
}
}
echo $(find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null | wc -l) objects, \
$({
echo 0
# "no-such" is to help Darwin folks by not using xargs -r.
find "$GIT_DIR/objects"/?? -type f -print 2>/dev/null |
xargs du -k "$GIT_DIR/objects/no-such" 2>/dev/null |
sed -e 's/[ ].*/ +/'
echo p
} | dc) kilobytes

1
git.c
Просмотреть файл

@ -47,6 +47,7 @@ static void handle_internal_command(int argc, const char **argv, char **envp)
{ "whatchanged", cmd_whatchanged }, { "whatchanged", cmd_whatchanged },
{ "show", cmd_show }, { "show", cmd_show },
{ "push", cmd_push }, { "push", cmd_push },
{ "count-objects", cmd_count_objects },
}; };
int i; int i;