* [PATCH] C version of git-count-objects
@ 2006-04-27 10:12 Peter Hagervall
2006-04-27 13:16 ` Morten Welinder
2006-04-27 13:23 ` Nicolas Pitre
0 siblings, 2 replies; 12+ messages in thread
From: Peter Hagervall @ 2006-04-27 10:12 UTC (permalink / raw)
To: git; +Cc: junkio
Answering the call Linus made[1], sort of, but for a completely
different program.
Anyway, it ought to be at least as portable as the shell script, and a
whole lot faster, however much that matters.
Signed-off-by: Peter Hagervall <hager@cs.umu.se>
[1] http://article.gmane.org/gmane.comp.version-control.git/19073
---
Makefile | 5 +--
count-objects.c | 56 +++++++++++++++++++++++++++++++++++++
git-count-objects.sh | 31 --------------------
3 files changed, 59 insertions(+), 33 deletions(-)
diff --git a/Makefile b/Makefile
index 8ce27a6..53e7591 100644
--- a/Makefile
+++ b/Makefile
@@ -115,7 +115,7 @@ ### --- END CONFIGURATION SECTION ---
SCRIPT_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-count-objects.sh git-diff.sh git-fetch.sh \
+ git-diff.sh git-fetch.sh \
git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
@@ -165,7 +165,8 @@ PROGRAMS = \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
- 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 \
+ git-count-objects$X
BUILT_INS = git-log$X
diff --git a/count-objects.c b/count-objects.c
new file mode 100644
index 0000000..67ab6f0
--- /dev/null
+++ b/count-objects.c
@@ -0,0 +1,56 @@
+#include "cache.h"
+#include "git-compat-util.h"
+
+static char pathname[PATH_MAX + 1];
+static int numobjects, numblocks;
+static const char hex_digits[] = "0123456789abcdef";
+
+void count_objects(void)
+{
+ char subdir[3];
+ int i, j;
+ struct stat statbuf;
+ struct dirent *dirp;
+ DIR *dp;
+ subdir[2] = '\0';
+ for (i = 0; i < 16; i++) {
+ subdir[0] = hex_digits[i];
+ for (j = 0; j < 16; j++) {
+ subdir[1] = hex_digits[j];
+ if (access(subdir, R_OK | X_OK))
+ continue;
+ chdir(subdir);
+ if (!(dp = opendir("."))) {
+ error("can't open subdir %s", subdir);
+ continue;
+ }
+ while ((dirp = readdir(dp))) {
+ if (!strcmp(dirp->d_name, ".") ||
+ !strcmp(dirp->d_name, ".."))
+ continue;
+ if (lstat(dirp->d_name, &statbuf)) {
+ error("can't stat file %s", dirp->d_name);
+ continue;
+ }
+ numblocks += statbuf.st_blocks;
+ numobjects++;
+ }
+ closedir(dp);
+ chdir("..");
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ setup_git_directory();
+
+ if (chdir(".git/objects"))
+ die("%s", strerror(errno));
+
+ count_objects();
+
+ printf("%d objects, %d kilobytes\n", numobjects, numblocks / 2);
+
+ return 0;
+}
diff --git a/git-count-objects.sh b/git-count-objects.sh
deleted file mode 100755
index 40c58ef..0000000
--- a/git-count-objects.sh
+++ /dev/null
@@ -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
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 10:12 [PATCH] C version of git-count-objects Peter Hagervall
@ 2006-04-27 13:16 ` Morten Welinder
2006-04-27 13:23 ` Nicolas Pitre
1 sibling, 0 replies; 12+ messages in thread
From: Morten Welinder @ 2006-04-27 13:16 UTC (permalink / raw)
To: Peter Hagervall; +Cc: git, junkio
> + if (access(subdir, R_OK | X_OK))
> + continue;
> + chdir(subdir);
You've got yourself a needless race condition right there. Just
do the chdir and check the return value. (And besides, access
checks with the wrong set of permissions, should this ever end
up in set[ug]id context.)
Morten
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 10:12 [PATCH] C version of git-count-objects Peter Hagervall
2006-04-27 13:16 ` Morten Welinder
@ 2006-04-27 13:23 ` Nicolas Pitre
2006-04-27 14:07 ` [PATCH] C version of git-count-objects, second try Peter Hagervall
2006-04-27 18:56 ` [PATCH] C version of git-count-objects Junio C Hamano
1 sibling, 2 replies; 12+ messages in thread
From: Nicolas Pitre @ 2006-04-27 13:23 UTC (permalink / raw)
To: Peter Hagervall; +Cc: git, junkio
On Thu, 27 Apr 2006, Peter Hagervall wrote:
> Answering the call Linus made[1], sort of, but for a completely
> different program.
>
> Anyway, it ought to be at least as portable as the shell script, and a
> whole lot faster, however much that matters.
>
[...]
> + for (i = 0; i < 16; i++) {
> + subdir[0] = hex_digits[i];
> + for (j = 0; j < 16; j++) {
> + subdir[1] = hex_digits[j];
> + if (access(subdir, R_OK | X_OK))
> + continue;
> + chdir(subdir);
> + if (!(dp = opendir("."))) {
> + error("can't open subdir %s", subdir);
> + continue;
> + }
Looks like you're missing a chdir(".."); there.
Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] C version of git-count-objects, second try
2006-04-27 13:23 ` Nicolas Pitre
@ 2006-04-27 14:07 ` Peter Hagervall
2006-04-27 18:56 ` [PATCH] C version of git-count-objects Junio C Hamano
1 sibling, 0 replies; 12+ messages in thread
From: Peter Hagervall @ 2006-04-27 14:07 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: git, junkio, mwelinder
On Thu, Apr 27, 2006 at 09:23:47AM -0400, Nicolas Pitre wrote:
> On Thu, 27 Apr 2006, Peter Hagervall wrote:
>
> > Answering the call Linus made[1], sort of, but for a completely
> > different program.
> >
> > Anyway, it ought to be at least as portable as the shell script, and a
> > whole lot faster, however much that matters.
> >
> [...]
> > + for (i = 0; i < 16; i++) {
> > + subdir[0] = hex_digits[i];
> > + for (j = 0; j < 16; j++) {
> > + subdir[1] = hex_digits[j];
> > + if (access(subdir, R_OK | X_OK))
> > + continue;
> > + chdir(subdir);
> > + if (!(dp = opendir("."))) {
> > + error("can't open subdir %s", subdir);
> > + continue;
> > + }
>
> Looks like you're missing a chdir(".."); there.
>
Thanks, I overlooked that one (and the race condition pointed out by
Morten). Anyway, fixed those now, and removed an unused array.
Signed-off-by: Peter Hagervall <hager@cs.umu.se>
---
Makefile | 5 ++-
count-objects.c | 55 +++++++++++++++++++++++++++++++++++++
git-count-objects.sh | 31 --------------------
3 files changed, 58 insertions(+), 33 deletions(-)
diff --git a/Makefile b/Makefile
index 8ce27a6..53e7591 100644
--- a/Makefile
+++ b/Makefile
@@ -115,7 +115,7 @@ ### --- END CONFIGURATION SECTION ---
SCRIPT_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-count-objects.sh git-diff.sh git-fetch.sh \
+ git-diff.sh git-fetch.sh \
git-format-patch.sh git-ls-remote.sh \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
@@ -165,7 +165,8 @@ PROGRAMS = \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
- 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 \
+ git-count-objects$X
BUILT_INS = git-log$X
diff --git a/count-objects.c b/count-objects.c
new file mode 100644
index 0000000..beaa4d9
--- /dev/null
+++ b/count-objects.c
@@ -0,0 +1,55 @@
+#include "cache.h"
+#include "git-compat-util.h"
+
+static int numobjects, numblocks;
+static const char hex_digits[] = "0123456789abcdef";
+
+void count_objects(void)
+{
+ char subdir[3];
+ int i, j;
+ struct stat statbuf;
+ struct dirent *dirp;
+ DIR *dp;
+ subdir[2] = '\0';
+ for (i = 0; i < 16; i++) {
+ subdir[0] = hex_digits[i];
+ for (j = 0; j < 16; j++) {
+ subdir[1] = hex_digits[j];
+ if (chdir(subdir))
+ continue;
+ if (!(dp = opendir("."))) {
+ error("can't open subdir %s", subdir);
+ chdir("..");
+ continue;
+ }
+ while ((dirp = readdir(dp))) {
+ if (!strcmp(dirp->d_name, ".") ||
+ !strcmp(dirp->d_name, ".."))
+ continue;
+ if (lstat(dirp->d_name, &statbuf)) {
+ error("can't stat file %s", dirp->d_name);
+ continue;
+ }
+ numblocks += statbuf.st_blocks;
+ numobjects++;
+ }
+ closedir(dp);
+ chdir("..");
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ setup_git_directory();
+
+ if (chdir(".git/objects"))
+ die("%s", strerror(errno));
+
+ count_objects();
+
+ printf("%d objects, %d kilobytes\n", numobjects, numblocks / 2);
+
+ return 0;
+}
diff --git a/git-count-objects.sh b/git-count-objects.sh
deleted file mode 100755
index 40c58ef..0000000
--- a/git-count-objects.sh
+++ /dev/null
@@ -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
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 13:23 ` Nicolas Pitre
2006-04-27 14:07 ` [PATCH] C version of git-count-objects, second try Peter Hagervall
@ 2006-04-27 18:56 ` Junio C Hamano
2006-04-27 19:39 ` Nicolas Pitre
1 sibling, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2006-04-27 18:56 UTC (permalink / raw)
To: Peter Hagervall; +Cc: git, Nicolas Pitre
Nicolas Pitre <nico@cam.org> writes:
> On Thu, 27 Apr 2006, Peter Hagervall wrote:
>
>> Answering the call Linus made[1], sort of, but for a completely
>> different program.
>>
>> Anyway, it ought to be at least as portable as the shell script, and a
>> whole lot faster, however much that matters.
>>
> [...]
>> + for (i = 0; i < 16; i++) {
>> + subdir[0] = hex_digits[i];
>> + for (j = 0; j < 16; j++) {
>> + subdir[1] = hex_digits[j];
>> + if (access(subdir, R_OK | X_OK))
>> + continue;
>> + chdir(subdir);
>> + if (!(dp = opendir("."))) {
>> + error("can't open subdir %s", subdir);
>> + continue;
>> + }
>
> Looks like you're missing a chdir(".."); there.
Why would you even _need_ to chdir() anywhere, anyway?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 18:56 ` [PATCH] C version of git-count-objects Junio C Hamano
@ 2006-04-27 19:39 ` Nicolas Pitre
2006-04-27 19:46 ` Peter Hagervall
0 siblings, 1 reply; 12+ messages in thread
From: Nicolas Pitre @ 2006-04-27 19:39 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Peter Hagervall, git
On Thu, 27 Apr 2006, Junio C Hamano wrote:
> Nicolas Pitre <nico@cam.org> writes:
>
> > On Thu, 27 Apr 2006, Peter Hagervall wrote:
> >
> >> Answering the call Linus made[1], sort of, but for a completely
> >> different program.
> >>
> >> Anyway, it ought to be at least as portable as the shell script, and a
> >> whole lot faster, however much that matters.
> >>
> > [...]
> >> + for (i = 0; i < 16; i++) {
> >> + subdir[0] = hex_digits[i];
> >> + for (j = 0; j < 16; j++) {
> >> + subdir[1] = hex_digits[j];
> >> + if (access(subdir, R_OK | X_OK))
> >> + continue;
> >> + chdir(subdir);
> >> + if (!(dp = opendir("."))) {
> >> + error("can't open subdir %s", subdir);
> >> + continue;
> >> + }
> >
> > Looks like you're missing a chdir(".."); there.
>
> Why would you even _need_ to chdir() anywhere, anyway?
To avoid appending the filename to the path before each lstat() I'd
guess.
Nicolas
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 19:39 ` Nicolas Pitre
@ 2006-04-27 19:46 ` Peter Hagervall
2006-04-27 20:07 ` Linus Torvalds
0 siblings, 1 reply; 12+ messages in thread
From: Peter Hagervall @ 2006-04-27 19:46 UTC (permalink / raw)
To: Nicolas Pitre; +Cc: Junio C Hamano, git
On Thu, Apr 27, 2006 at 03:39:14PM -0400, Nicolas Pitre wrote:
> On Thu, 27 Apr 2006, Junio C Hamano wrote:
>
> > Nicolas Pitre <nico@cam.org> writes:
> >
> > > On Thu, 27 Apr 2006, Peter Hagervall wrote:
> > >
> > >> Answering the call Linus made[1], sort of, but for a completely
> > >> different program.
> > >>
> > >> Anyway, it ought to be at least as portable as the shell script, and a
> > >> whole lot faster, however much that matters.
> > >>
> > > [...]
> > >> + for (i = 0; i < 16; i++) {
> > >> + subdir[0] = hex_digits[i];
> > >> + for (j = 0; j < 16; j++) {
> > >> + subdir[1] = hex_digits[j];
> > >> + if (access(subdir, R_OK | X_OK))
> > >> + continue;
> > >> + chdir(subdir);
> > >> + if (!(dp = opendir("."))) {
> > >> + error("can't open subdir %s", subdir);
> > >> + continue;
> > >> + }
> > >
> > > Looks like you're missing a chdir(".."); there.
> >
> > Why would you even _need_ to chdir() anywhere, anyway?
>
> To avoid appending the filename to the path before each lstat() I'd
> guess.
Yes, that's pretty much the reason.
Peter
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 19:46 ` Peter Hagervall
@ 2006-04-27 20:07 ` Linus Torvalds
2006-04-27 20:51 ` Peter Hagervall
0 siblings, 1 reply; 12+ messages in thread
From: Linus Torvalds @ 2006-04-27 20:07 UTC (permalink / raw)
To: Peter Hagervall; +Cc: Nicolas Pitre, Junio C Hamano, git
On Thu, 27 Apr 2006, Peter Hagervall wrote:
> >
> > To avoid appending the filename to the path before each lstat() I'd
> > guess.
>
> Yes, that's pretty much the reason.
It's a bad reason, though.
For one thing, it just doesn't work. You'll have to chdir() back, and you
can't use ".." in case the user has set up some symlink thing. So you end
up doing other really strange things.
You can do this much more efficiently with something like this:
const char *obj = git_object_directory();
int len = strlen(obj);
char *dir = malloc(len + 300);
memcpy(dir, obj, len);
if (len && obj[len-1] != '/')
dir[len++] = '/';
dir[len+2] = 0;
for (i = 0; i < 16; i++) {
dir[len] = hexdigit[i];
for (j = 0; j < 16; j+) {
dir[len+1] = hexdigit[j];
dir[len+2] = 0;
DIR *d = opendir(dir);
if (!d)
continue;
nr += count(d, dir, len+2);
closedir(d);
}
}
where the "count()" function just ends up doing something like
int count(DIR *d, const char *prefix, int len)
{
int nr = 0;
struct dirent *de;
prefix[len++] = '/';
while ((de = readdir(d)) != NULL) {
int fd;
if (de->d_name[0] == '.')
continue;
strcpy(prefix + len, de->d_name);
fd = open(prefix, O_RDONLY);
.. check if it's ok, perhaps.. ?
if (ok)
nr++;
close(fd);
}
return nr;
}
and you're done. Efficient, and it's easy to add the endign to the
pathname, because you're passing in a buffer that is big enough, and
you're telling people where they should put their suffixes..
And no, the above has never been compiled or tested, and I wrote it with
one eye closed, while drinking heavily and experimenting with some funky
'shrooms. So caveat emptor.
Linus
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 20:07 ` Linus Torvalds
@ 2006-04-27 20:51 ` Peter Hagervall
2006-04-27 22:07 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Peter Hagervall @ 2006-04-27 20:51 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Nicolas Pitre, Junio C Hamano, git
On Thu, Apr 27, 2006 at 01:07:27PM -0700, Linus Torvalds wrote:
>
>
> On Thu, 27 Apr 2006, Peter Hagervall wrote:
> > >
> > > To avoid appending the filename to the path before each lstat() I'd
> > > guess.
> >
> > Yes, that's pretty much the reason.
>
> It's a bad reason, though.
>
> For one thing, it just doesn't work. You'll have to chdir() back, and you
> can't use ".." in case the user has set up some symlink thing. So you end
> up doing other really strange things.
>
> You can do this much more efficiently with something like this:
>
> const char *obj = git_object_directory();
> int len = strlen(obj);
<snip>
> continue;
> strcpy(prefix + len, de->d_name);
> fd = open(prefix, O_RDONLY);
> .. check if it's ok, perhaps.. ?
> if (ok)
> nr++;
> close(fd);
> }
> return nr;
> }
>
> and you're done. Efficient, and it's easy to add the endign to the
> pathname, because you're passing in a buffer that is big enough, and
> you're telling people where they should put their suffixes..
Thanks, I'll make a third stab at it tomorrow, if anyone is interested
that is?
Peter
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 20:51 ` Peter Hagervall
@ 2006-04-27 22:07 ` Junio C Hamano
2006-04-28 0:10 ` Peter Hagervall
0 siblings, 1 reply; 12+ messages in thread
From: Junio C Hamano @ 2006-04-27 22:07 UTC (permalink / raw)
To: Peter Hagervall; +Cc: git
Peter Hagervall <hager@cs.umu.se> writes:
> Thanks, I'll make a third stab at it tomorrow, if anyone is interested
> that is?
How about something like this instead?
-- >8 --
Makefile | 2 -
builtin-count.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
builtin.h | 1
git.c | 1
4 files changed, 127 insertions(+), 1 deletions(-)
diff --git a/Makefile b/Makefile
index 8ce27a6..14193aa 100644
--- a/Makefile
+++ b/Makefile
@@ -214,7 +214,7 @@ LIB_OBJS = \
$(DIFF_OBJS)
BUILTIN_OBJS = \
- builtin-log.o builtin-help.o
+ builtin-log.o builtin-help.o builtin-count.o
GITLIBS = $(LIB_FILE) $(XDIFF_LIB)
LIBS = $(GITLIBS) -lz
diff --git a/builtin-count.c b/builtin-count.c
new file mode 100644
index 0000000..cbbb7dd
--- /dev/null
+++ b/builtin-count.c
@@ -0,0 +1,124 @@
+/*
+ * Builtin "git count-objects".
+ *
+ * Copyright (c) 2006 Junio C Hamano
+ */
+
+#include "cache.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 (stat(path, &st)) {
+ die("OOPS <%s>", path);
+ 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;
+ 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;
+}
diff --git a/builtin.h b/builtin.h
index 47408a0..76169e3 100644
--- a/builtin.h
+++ b/builtin.h
@@ -19,5 +19,6 @@ extern int cmd_version(int argc, const c
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_log(int argc, const char **argv, char **envp);
+extern int cmd_count_objects(int argc, const char **argv, char **envp);
#endif
diff --git a/git.c b/git.c
index 01b7e28..00fb399 100644
--- a/git.c
+++ b/git.c
@@ -46,6 +46,7 @@ static void handle_internal_command(int
{ "log", cmd_log },
{ "whatchanged", cmd_whatchanged },
{ "show", cmd_show },
+ { "count-objects", cmd_count_objects },
};
int i;
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-27 22:07 ` Junio C Hamano
@ 2006-04-28 0:10 ` Peter Hagervall
2006-04-28 0:25 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Peter Hagervall @ 2006-04-28 0:10 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
On Thu, Apr 27, 2006 at 03:07:37PM -0700, Junio C Hamano wrote:
...
> +int cmd_count_objects(int ac, const char **av, char *ep)
^
...
> +extern int cmd_count_objects(int argc, const char **argv, char **envp);
^^
Looks like we have a type mismatch here, no?
Peter
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] C version of git-count-objects
2006-04-28 0:10 ` Peter Hagervall
@ 2006-04-28 0:25 ` Junio C Hamano
0 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2006-04-28 0:25 UTC (permalink / raw)
To: Peter Hagervall; +Cc: git
Peter Hagervall <hager@cs.umu.se> writes:
> On Thu, Apr 27, 2006 at 03:07:37PM -0700, Junio C Hamano wrote:
>
> ...
>
>> +int cmd_count_objects(int ac, const char **av, char *ep)
> ^
> ...
>
>> +extern int cmd_count_objects(int argc, const char **argv, char **envp);
> ^^
> Looks like we have a type mismatch here, no?
Interesting. Lack of #include <builtin.h> was causing the
compiler not to notice X-<.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2006-04-28 0:26 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-27 10:12 [PATCH] C version of git-count-objects Peter Hagervall
2006-04-27 13:16 ` Morten Welinder
2006-04-27 13:23 ` Nicolas Pitre
2006-04-27 14:07 ` [PATCH] C version of git-count-objects, second try Peter Hagervall
2006-04-27 18:56 ` [PATCH] C version of git-count-objects Junio C Hamano
2006-04-27 19:39 ` Nicolas Pitre
2006-04-27 19:46 ` Peter Hagervall
2006-04-27 20:07 ` Linus Torvalds
2006-04-27 20:51 ` Peter Hagervall
2006-04-27 22:07 ` Junio C Hamano
2006-04-28 0:10 ` Peter Hagervall
2006-04-28 0:25 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).