From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
"Ramsay Jones" <ramsay@ramsay1.demon.co.uk>,
"Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH v3 3/4] count-objects: report garbage files in pack directory too
Date: Tue, 12 Feb 2013 16:27:56 +0700 [thread overview]
Message-ID: <1360661277-17273-4-git-send-email-pclouds@gmail.com> (raw)
In-Reply-To: <1360661277-17273-1-git-send-email-pclouds@gmail.com>
prepare_packed_git_one() is modified to allow count-objects to hook a
report function to so we don't need to duplicate the pack searching
logic in count-objects.c. When report_pack_garbage is NULL, the
overhead is insignificant.
The garbage is reported with warning() instead of error() in packed
garbage case because it's not an error to have garbage. Loose garbage
is still reported as errors and will be converted to warnings later.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-count-objects.txt | 4 +-
builtin/count-objects.c | 22 +++++++++-
cache.h | 3 ++
sha1_file.c | 83 ++++++++++++++++++++++++++++++++++++-
4 files changed, 107 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index e816823..1611d7c 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -33,8 +33,8 @@ size-pack: disk space consumed by the packs, in KiB
prune-packable: the number of loose objects that are also present in
the packs. These objects could be pruned using `git prune-packed`.
+
-garbage: the number of files in loose object database that are not
-valid loose objects
+garbage: the number of files in object database that are not valid
+loose objects nor valid packs
GIT
---
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 9afaa88..639c9a5 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -9,6 +9,24 @@
#include "builtin.h"
#include "parse-options.h"
+static unsigned long garbage;
+
+static void real_report_garbage(const char *desc,
+ const char *path, int len,
+ const char *name)
+{
+ struct strbuf sb = STRBUF_INIT;
+ if (len && name)
+ strbuf_addf(&sb, "%.*s/%s", len, path, name);
+ else if (!len && name)
+ strbuf_addf(&sb, "%s%s", path, name);
+ else
+ strbuf_addf(&sb, "%s", path);
+ warning("%s: %s", desc, sb.buf);
+ garbage++;
+ strbuf_release(&sb);
+}
+
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
off_t *loose_size,
@@ -76,7 +94,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
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 = 0, packed = 0, packed_loose = 0;
off_t loose_size = 0;
struct option opts[] = {
OPT__VERBOSE(&verbose, N_("be verbose")),
@@ -87,6 +105,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
/* 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;
memcpy(path, objdir, len);
if (len && objdir[len-1] != '/')
path[len++] = '/';
diff --git a/cache.h b/cache.h
index 7339f21..e486499 100644
--- a/cache.h
+++ b/cache.h
@@ -1051,6 +1051,9 @@ extern const char *parse_feature_value(const char *feature_list, const char *fea
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
+/* A hook for count-objects to report invalid files in pack directory */
+extern void (*report_garbage)(const char *desc, const char *path, int len, const char *name);
+
extern void prepare_packed_git(void);
extern void reprepare_packed_git(void);
extern void install_packed_git(struct packed_git *pack);
diff --git a/sha1_file.c b/sha1_file.c
index 8d7da1d..290e348 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -21,6 +21,7 @@
#include "sha1-lookup.h"
#include "bulk-checkin.h"
#include "streaming.h"
+#include "dir.h"
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@ -1000,6 +1001,52 @@ void install_packed_git(struct packed_git *pack)
packed_git = pack;
}
+void (*report_garbage)(const char *desc, const char *path,
+ int len, const char *name);
+
+static void report_pack_garbage(struct string_list *list)
+{
+ struct strbuf sb = STRBUF_INIT;
+ struct packed_git *p;
+ int i;
+
+ if (!report_garbage)
+ return;
+
+ sort_string_list(list);
+
+ for (p = packed_git; p; p = p->next) {
+ struct string_list_item *item;
+ if (!p->pack_local)
+ continue;
+ strbuf_reset(&sb);
+ strbuf_add(&sb, p->pack_name,
+ strlen(p->pack_name) - 5); /* ".pack" */
+ item = string_list_lookup(list, sb.buf);
+ if (!item)
+ continue;
+ /*
+ * string_list_lookup does not guarantee to return the
+ * first matched string if it's duplicated.
+ */
+ while (item - list->items &&
+ !strcmp(item[-1].string, item->string))
+ item--;
+ while (item - list->items < list->nr &&
+ !strcmp(item->string, sb.buf)) {
+ item->util = NULL; /* non-garbage mark */
+ item++;
+ }
+ }
+ for (i = 0; i < list->nr; i++) {
+ struct string_list_item *item = list->items + i;
+ if (!item->util)
+ continue;
+ report_garbage("garbage found", item->string, 0, item->util);
+ }
+ strbuf_release(&sb);
+}
+
static void prepare_packed_git_one(char *objdir, int local)
{
/* Ensure that this buffer is large enough so that we can
@@ -1009,6 +1056,7 @@ static void prepare_packed_git_one(char *objdir, int local)
int len;
DIR *dir;
struct dirent *de;
+ struct string_list garbage = STRING_LIST_INIT_DUP;
sprintf(path, "%s/pack", objdir);
len = strlen(path);
@@ -1024,7 +1072,14 @@ static void prepare_packed_git_one(char *objdir, int local)
int namelen = strlen(de->d_name);
struct packed_git *p;
- if (len + namelen + 1 > sizeof(path))
+ if (len + namelen + 1 > sizeof(path)) {
+ if (report_garbage)
+ report_garbage("path too long",
+ path, len - 1, de->d_name);
+ continue;
+ }
+
+ if (is_dot_or_dotdot(de->d_name))
continue;
strcpy(path + len, de->d_name);
@@ -1045,9 +1100,33 @@ static void prepare_packed_git_one(char *objdir, int local)
if (!p)
continue;
install_packed_git(p);
- }
+ } else if (!report_garbage) {
+ /*
+ * the rest of this if-chain requires
+ * report_garbage != NULL. Stop the chain if
+ * report_garbage is NULL.
+ */
+ ;
+ } else if (has_extension(de->d_name, ".pack")) {
+ struct string_list_item *item;
+ int n = strlen(path) - 5;
+ item = string_list_append_nodup(&garbage,
+ xstrndup(path, n));
+ item->util = ".pack";
+ continue;
+ } else if (has_extension(de->d_name, ".idx")) {
+ struct string_list_item *item;
+ int n = strlen(path) - 4;
+ item = string_list_append_nodup(&garbage,
+ xstrndup(path, n));
+ item->util = ".idx";
+ continue;
+ } else
+ report_garbage("garbage found", path, 0, NULL);
}
closedir(dir);
+ report_pack_garbage(&garbage);
+ string_list_clear(&garbage, 0);
}
static int sort_pack(const void *a_, const void *b_)
--
1.8.1.2.536.gf441e6d
next prev parent reply other threads:[~2013-02-12 9:28 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-12 9:27 [PATCH v3 0/4] count-objects improvements Nguyễn Thái Ngọc Duy
2013-02-12 9:27 ` [PATCH v3 1/4] git-count-objects.txt: describe each line in -v output Nguyễn Thái Ngọc Duy
2013-02-12 9:27 ` [PATCH v3 2/4] sha1_file: reorder code in prepare_packed_git_one() Nguyễn Thái Ngọc Duy
2013-02-12 9:27 ` Nguyễn Thái Ngọc Duy [this message]
2013-02-12 17:23 ` [PATCH v3 3/4] count-objects: report garbage files in pack directory too Junio C Hamano
2013-02-13 9:13 ` [PATCH v4 0/4] count-objects improvements Nguyễn Thái Ngọc Duy
2013-02-13 9:13 ` [PATCH v4 1/4] git-count-objects.txt: describe each line in -v output Nguyễn Thái Ngọc Duy
2013-02-13 9:13 ` [PATCH v4 2/4] sha1_file: reorder code in prepare_packed_git_one() Nguyễn Thái Ngọc Duy
2013-02-13 9:13 ` [PATCH v4 3/4] count-objects: report garbage files in pack directory too Nguyễn Thái Ngọc Duy
2013-02-13 15:55 ` Junio C Hamano
2013-02-13 16:54 ` Junio C Hamano
2013-02-14 9:24 ` Duy Nguyen
2013-02-14 17:02 ` Junio C Hamano
2013-02-15 12:07 ` [PATCH v4+ " Nguyễn Thái Ngọc Duy
2013-02-15 23:20 ` Junio C Hamano
2013-02-13 9:13 ` [PATCH v4 4/4] count-objects: report how much disk space taken by garbage files Nguyễn Thái Ngọc Duy
2013-02-12 9:27 ` [PATCH v3 " Nguyễn Thái Ngọc Duy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1360661277-17273-4-git-send-email-pclouds@gmail.com \
--to=pclouds@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=ramsay@ramsay1.demon.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).