提交 7d71be24 编写于 作者: J Junio C Hamano

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
...@@ -1907,13 +1907,19 @@ static void show_commit(struct commit *commit) ...@@ -1907,13 +1907,19 @@ static void show_commit(struct commit *commit)
commit->object.flags |= OBJECT_ADDED; 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); char *name = path_name(path, last);
add_object_entry(p->item->sha1, p->item->type, p->name, 0);
p->item->flags |= OBJECT_ADDED; add_preferred_base_object(name);
free((char *)p->name); add_object_entry(obj->sha1, obj->type, name, 0);
p->name = NULL; 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) static void show_edge(struct commit *commit)
......
...@@ -168,27 +168,29 @@ static void finish_commit(struct commit *commit) ...@@ -168,27 +168,29 @@ static void finish_commit(struct commit *commit)
commit->buffer = NULL; 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)) if (obj->type == OBJ_BLOB && !has_sha1_file(obj->sha1))
die("missing blob object '%s'", sha1_to_hex(p->item->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 /* An object with name "foo\n0000000..." can be used to
* confuse downstream "git pack-objects" very badly. * 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) { if (ep) {
printf("%s %.*s\n", sha1_to_hex(p->item->sha1), printf("%s %.*s\n", sha1_to_hex(obj->sha1),
(int) (ep - p->name), (int) (ep - name),
p->name); name);
} }
else 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) static void show_edge(struct commit *commit)
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
static void process_blob(struct rev_info *revs, static void process_blob(struct rev_info *revs,
struct blob *blob, struct blob *blob,
struct object_array *p, show_object_fn show,
struct name_path *path, struct name_path *path,
const char *name) const char *name)
{ {
...@@ -23,7 +23,7 @@ static void process_blob(struct rev_info *revs, ...@@ -23,7 +23,7 @@ static void process_blob(struct rev_info *revs,
if (obj->flags & (UNINTERESTING | SEEN)) if (obj->flags & (UNINTERESTING | SEEN))
return; return;
obj->flags |= SEEN; 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, ...@@ -50,7 +50,7 @@ static void process_blob(struct rev_info *revs,
*/ */
static void process_gitlink(struct rev_info *revs, static void process_gitlink(struct rev_info *revs,
const unsigned char *sha1, const unsigned char *sha1,
struct object_array *p, show_object_fn show,
struct name_path *path, struct name_path *path,
const char *name) const char *name)
{ {
...@@ -59,7 +59,7 @@ static void process_gitlink(struct rev_info *revs, ...@@ -59,7 +59,7 @@ static void process_gitlink(struct rev_info *revs,
static void process_tree(struct rev_info *revs, static void process_tree(struct rev_info *revs,
struct tree *tree, struct tree *tree,
struct object_array *p, show_object_fn show,
struct name_path *path, struct name_path *path,
const char *name) const char *name)
{ {
...@@ -77,7 +77,7 @@ static void process_tree(struct rev_info *revs, ...@@ -77,7 +77,7 @@ static void process_tree(struct rev_info *revs,
if (parse_tree(tree) < 0) if (parse_tree(tree) < 0)
die("bad tree object %s", sha1_to_hex(obj->sha1)); die("bad tree object %s", sha1_to_hex(obj->sha1));
obj->flags |= SEEN; obj->flags |= SEEN;
add_object(obj, p, path, name); show(obj, path, name);
me.up = path; me.up = path;
me.elem = name; me.elem = name;
me.elem_len = strlen(name); me.elem_len = strlen(name);
...@@ -88,14 +88,14 @@ static void process_tree(struct rev_info *revs, ...@@ -88,14 +88,14 @@ static void process_tree(struct rev_info *revs,
if (S_ISDIR(entry.mode)) if (S_ISDIR(entry.mode))
process_tree(revs, process_tree(revs,
lookup_tree(entry.sha1), lookup_tree(entry.sha1),
p, &me, entry.path); show, &me, entry.path);
else if (S_ISGITLINK(entry.mode)) else if (S_ISGITLINK(entry.mode))
process_gitlink(revs, entry.sha1, process_gitlink(revs, entry.sha1,
p, &me, entry.path); show, &me, entry.path);
else else
process_blob(revs, process_blob(revs,
lookup_blob(entry.sha1), lookup_blob(entry.sha1),
p, &me, entry.path); show, &me, entry.path);
} }
free(tree->buffer); free(tree->buffer);
tree->buffer = NULL; tree->buffer = NULL;
...@@ -134,16 +134,20 @@ void mark_edges_uninteresting(struct commit_list *list, ...@@ -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 traverse_commit_list(struct rev_info *revs,
void (*show_commit)(struct commit *), show_commit_fn show_commit,
void (*show_object)(struct object_array_entry *)) show_object_fn show_object)
{ {
int i; int i;
struct commit *commit; struct commit *commit;
struct object_array objects = { 0, 0, NULL };
while ((commit = get_revision(revs)) != NULL) { while ((commit = get_revision(revs)) != NULL) {
process_tree(revs, commit->tree, &objects, NULL, ""); add_pending_tree(revs, commit->tree);
show_commit(commit); show_commit(commit);
} }
for (i = 0; i < revs->pending.nr; i++) { for (i = 0; i < revs->pending.nr; i++) {
...@@ -154,25 +158,22 @@ void traverse_commit_list(struct rev_info *revs, ...@@ -154,25 +158,22 @@ void traverse_commit_list(struct rev_info *revs,
continue; continue;
if (obj->type == OBJ_TAG) { if (obj->type == OBJ_TAG) {
obj->flags |= SEEN; obj->flags |= SEEN;
add_object_array(obj, name, &objects); show_object(obj, NULL, name);
continue; continue;
} }
if (obj->type == OBJ_TREE) { if (obj->type == OBJ_TREE) {
process_tree(revs, (struct tree *)obj, &objects, process_tree(revs, (struct tree *)obj, show_object,
NULL, name); NULL, name);
continue; continue;
} }
if (obj->type == OBJ_BLOB) { if (obj->type == OBJ_BLOB) {
process_blob(revs, (struct blob *)obj, &objects, process_blob(revs, (struct blob *)obj, show_object,
NULL, name); NULL, name);
continue; continue;
} }
die("unknown pending object %s (%s)", die("unknown pending object %s (%s)",
sha1_to_hex(obj->sha1), name); 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) { if (revs->pending.nr) {
free(revs->pending.objects); free(revs->pending.objects);
revs->pending.nr = 0; revs->pending.nr = 0;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#define LIST_OBJECTS_H #define LIST_OBJECTS_H
typedef void (*show_commit_fn)(struct commit *); 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 *); typedef void (*show_edge_fn)(struct commit *);
void traverse_commit_list(struct rev_info *revs, show_commit_fn, show_object_fn); void traverse_commit_list(struct rev_info *revs, show_commit_fn, show_object_fn);
......
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
volatile show_early_output_fn_t show_early_output; 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; char *n, *m;
int nlen = strlen(name); int nlen = strlen(name);
int len = nlen + 1; int len = nlen + 1;
......
...@@ -144,6 +144,8 @@ struct name_path { ...@@ -144,6 +144,8 @@ struct name_path {
const char *elem; const char *elem;
}; };
char *path_name(const struct name_path *path, const char *name);
extern void add_object(struct object *obj, extern void add_object(struct object *obj,
struct object_array *p, struct object_array *p,
struct name_path *path, struct name_path *path,
......
...@@ -78,20 +78,22 @@ static void show_commit(struct commit *commit) ...@@ -78,20 +78,22 @@ static void show_commit(struct commit *commit)
commit->buffer = NULL; 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 /* An object with name "foo\n0000000..." can be used to
* confuse downstream git-pack-objects very badly. * 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) { if (ep) {
fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(p->item->sha1), fprintf(pack_pipe, "%s %.*s\n", sha1_to_hex(obj->sha1),
(int) (ep - p->name), (int) (ep - name),
p->name); name);
} }
else else
fprintf(pack_pipe, "%s %s\n", 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) static void show_edge(struct commit *commit)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册