summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2009-05-03 22:02:40 (GMT)
committerJunio C Hamano <gitster@pobox.com>2009-05-03 22:02:40 (GMT)
commit7d71be242d7fc8bd2eaef90e1848d71609c5c577 (patch)
tree7d3da3c0fafed46aebf41506d5e1136d2c2c387c
parenta2dc04ba159def766ee17db00c60bdbda477955d (diff)
parentcf2ab916afa4231f7e9db31796e7c0f712ff6ad1 (diff)
downloadgit-7d71be242d7fc8bd2eaef90e1848d71609c5c577.zip
git-7d71be242d7fc8bd2eaef90e1848d71609c5c577.tar.gz
git-7d71be242d7fc8bd2eaef90e1848d71609c5c577.tar.bz2
Merge branch 'lt/pack-object-memuse' into maint
* lt/pack-object-memuse: show_object(): push path_name() call further down process_{tree,blob}: show objects without buffering
-rw-r--r--builtin-pack-objects.c18
-rw-r--r--builtin-rev-list.c22
-rw-r--r--list-objects.c37
-rw-r--r--list-objects.h2
-rw-r--r--revision.c4
-rw-r--r--revision.h2
-rw-r--r--upload-pack.c14
7 files changed, 56 insertions, 43 deletions
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 6cf5b86..b859cb1 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -1907,13 +1907,19 @@ static void show_commit(struct commit *commit)
commit->object.flags |= OBJECT_ADDED;
}
-static void show_object(struct object_array_entry *p)
+static void show_object(struct object *obj, const struct name_path *path, const char *last)
{
- add_preferred_base_object(p->name);
- add_object_entry(p->item->sha1, p->item->type, p->name, 0);
- p->item->flags |= OBJECT_ADDED;
- free((char *)p->name);
- p->name = NULL;
+ char *name = path_name(path, last);
+
+ add_preferred_base_object(name);
+ add_object_entry(obj->sha1, obj->type, name, 0);
+ obj->flags |= OBJECT_ADDED;
+
+ /*
+ * We will have generated the hash from the name,
+ * but not saved a pointer to it - we can free it
+ */
+ free((char *)name);
}
static void show_edge(struct commit *commit)
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 436afa4..0af7cd9 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -168,27 +168,29 @@ static void finish_commit(struct commit *commit)
commit->buffer = NULL;
}
-static void finish_object(struct object_array_entry *p)
+static void finish_object(struct object *obj, const struct name_path *path, const char *name)
{
- if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
- die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
+ if (obj->type == OBJ_BLOB && !has_sha1_file(obj->sha1))
+ die("missing blob object '%s'", sha1_to_hex(obj->sha1));
}
-static void show_object(struct object_array_entry *p)
+static void show_object(struct object *obj, const struct name_path *path, const char *component)
{
+ char *name = path_name(path, component);
/* An object with name "foo\n0000000..." can be used to
* confuse downstream "git pack-objects" very badly.
*/
- const char *ep = strchr(p->name, '\n');
+ const char *ep = strchr(name, '\n');
- finish_object(p);
+ finish_object(obj, path, name);
if (ep) {
- printf("%s %.*s\n", sha1_to_hex(p->item->sha1),
- (int) (ep - p->name),
- p->name);
+ printf("%s %.*s\n", sha1_to_hex(obj->sha1),
+ (int) (ep - name),
+ name);
}
else
- printf("%s %s\n", sha1_to_hex(p->item->sha1), p->name);
+ printf("%s %s\n", sha1_to_hex(obj->sha1), name);
+ free(name);
}
static void show_edge(struct commit *commit)
diff --git a/list-objects.c b/list-objects.c
index dd243c7..30ded3d 100644
--- a/list-objects.c
+++ b/list-objects.c
@@ -10,7 +10,7 @@
static void process_blob(struct rev_info *revs,
struct blob *blob,
- struct object_array *p,
+ show_object_fn show,
struct name_path *path,
const char *name)
{
@@ -23,7 +23,7 @@ static void process_blob(struct rev_info *revs,
if (obj->flags & (UNINTERESTING | SEEN))
return;
obj->flags |= SEEN;
- add_object(obj, p, path, name);
+ show(obj, path, name);
}
/*
@@ -50,7 +50,7 @@ static void process_blob(struct rev_info *revs,
*/
static void process_gitlink(struct rev_info *revs,
const unsigned char *sha1,
- struct object_array *p,
+ show_object_fn show,
struct name_path *path,
const char *name)
{
@@ -59,7 +59,7 @@ static void process_gitlink(struct rev_info *revs,
static void process_tree(struct rev_info *revs,
struct tree *tree,
- struct object_array *p,
+ show_object_fn show,
struct name_path *path,
const char *name)
{
@@ -77,7 +77,7 @@ static void process_tree(struct rev_info *revs,
if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN;
- add_object(obj, p, path, name);
+ show(obj, path, name);
me.up = path;
me.elem = name;
me.elem_len = strlen(name);
@@ -88,14 +88,14 @@ static void process_tree(struct rev_info *revs,
if (S_ISDIR(entry.mode))
process_tree(revs,
lookup_tree(entry.sha1),
- p, &me, entry.path);
+ show, &me, entry.path);
else if (S_ISGITLINK(entry.mode))
process_gitlink(revs, entry.sha1,
- p, &me, entry.path);
+ show, &me, entry.path);
else
process_blob(revs,
lookup_blob(entry.sha1),
- p, &me, entry.path);
+ show, &me, entry.path);
}
free(tree->buffer);
tree->buffer = NULL;
@@ -134,16 +134,20 @@ void mark_edges_uninteresting(struct commit_list *list,
}
}
+static void add_pending_tree(struct rev_info *revs, struct tree *tree)
+{
+ add_pending_object(revs, &tree->object, "");
+}
+
void traverse_commit_list(struct rev_info *revs,
- void (*show_commit)(struct commit *),
- void (*show_object)(struct object_array_entry *))
+ show_commit_fn show_commit,
+ show_object_fn show_object)
{
int i;
struct commit *commit;
- struct object_array objects = { 0, 0, NULL };
while ((commit = get_revision(revs)) != NULL) {
- process_tree(revs, commit->tree, &objects, NULL, "");
+ add_pending_tree(revs, commit->tree);
show_commit(commit);
}
for (i = 0; i < revs->pending.nr; i++) {
@@ -154,25 +158,22 @@ void traverse_commit_list(struct rev_info *revs,
continue;
if (obj->type == OBJ_TAG) {
obj->flags |= SEEN;
- add_object_array(obj, name, &objects);
+ show_object(obj, NULL, name);
continue;
}
if (obj->type == OBJ_TREE) {
- process_tree(revs, (struct tree *)obj, &objects,
+ process_tree(revs, (struct tree *)obj, show_object,
NULL, name);
continue;
}
if (obj->type == OBJ_BLOB) {
- process_blob(revs, (struct blob *)obj, &objects,
+ process_blob(revs, (struct blob *)obj, show_object,
NULL, name);
continue;
}
die("unknown pending object %s (%s)",
sha1_to_hex(obj->sha1), name);
}
- for (i = 0; i < objects.nr; i++)
- show_object(&objects.objects[i]);
- free(objects.objects);
if (revs->pending.nr) {
free(revs->pending.objects);
revs->pending.nr = 0;
diff --git a/list-objects.h b/list-objects.h
index 0f41391..0b2de64 100644
--- a/list-objects.h
+++ b/list-objects.h
@@ -2,7 +2,7 @@
#define LIST_OBJECTS_H
typedef void (*show_commit_fn)(struct commit *);
-typedef void (*show_object_fn)(struct object_array_entry *);
+typedef void (*show_object_fn)(struct object *, const struct name_path *, const char *);
typedef void (*show_edge_fn)(struct commit *);
void traverse_commit_list(struct rev_info *revs, show_commit_fn, show_object_fn);
diff --git a/revision.c b/revision.c
index 34ee490..d7d345b 100644
--- a/revision.c
+++ b/revision.c
@@ -15,9 +15,9 @@
volatile show_early_output_fn_t show_early_output;
-static char *path_name(struct name_path *path, const char *name)
+char *path_name(const struct name_path *path, const char *name)
{
- struct name_path *p;
+ const struct name_path *p;
char *n, *m;
int nlen = strlen(name);
int len = nlen + 1;
diff --git a/revision.h b/revision.h
index 66d211a..bfe2707 100644
--- a/revision.h
+++ b/revision.h
@@ -144,6 +144,8 @@ struct name_path {
const char *elem;
};
+char *path_name(const struct name_path *path, const char *name);
+
extern void add_object(struct object *obj,
struct object_array *p,
struct name_path *path,
diff --git a/upload-pack.c b/upload-pack.c
index 19c24db..b98b1d6 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -78,20 +78,22 @@ static void show_commit(struct commit *commit)
commit->buffer = NULL;
}
-static void show_object(struct object_array_entry *p)
+static void show_object(struct object *obj, const struct name_path *path, const char *component)
{
/* An object with name "foo\n0000000..." can be used to
* confuse downstream git-pack-objects very badly.
*/
- const char *ep = strchr(p->name, '\n');
+ const char *name = path_name(path, component);
+ const char *ep = strchr(name, '\n');
if (ep) {
- fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(p->item->sha1),
- (int) (ep - p->name),
- p->name);
+ fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(obj->sha1),
+ (int) (ep - name),
+ name);
}
else
fprintf(pack_pipe, "%s %s\n",
- sha1_to_hex(p->item->sha1), p->name);
+ sha1_to_hex(obj->sha1), name);
+ free((char *)name);
}
static void show_edge(struct commit *commit)