зеркало из https://github.com/microsoft/git.git
Merge branch 'lt/pack-object-memuse'
* lt/pack-object-memuse: show_object(): push path_name() call further down process_{tree,blob}: show objects without buffering Conflicts: builtin-pack-objects.c builtin-rev-list.c list-objects.c list-objects.h upload-pack.c
This commit is contained in:
Коммит
9824a388e5
|
@ -1907,13 +1907,19 @@ static void show_commit(struct commit *commit, void *data)
|
|||
commit->object.flags |= OBJECT_ADDED;
|
||||
}
|
||||
|
||||
static void show_object(struct object_array_entry *p, void *data)
|
||||
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)
|
||||
|
|
|
@ -156,27 +156,29 @@ static void finish_commit(struct commit *commit, void *data)
|
|||
commit->buffer = NULL;
|
||||
}
|
||||
|
||||
static void finish_object(struct object_array_entry *p, void *data)
|
||||
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, void *data)
|
||||
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, data);
|
||||
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)
|
||||
|
|
|
@ -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,6 +134,11 @@ 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,
|
||||
show_commit_fn show_commit,
|
||||
show_object_fn show_object,
|
||||
|
@ -141,10 +146,9 @@ void traverse_commit_list(struct rev_info *revs,
|
|||
{
|
||||
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, data);
|
||||
}
|
||||
for (i = 0; i < revs->pending.nr; i++) {
|
||||
|
@ -155,25 +159,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], data);
|
||||
free(objects.objects);
|
||||
if (revs->pending.nr) {
|
||||
free(revs->pending.objects);
|
||||
revs->pending.nr = 0;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define LIST_OBJECTS_H
|
||||
|
||||
typedef void (*show_commit_fn)(struct commit *, void *);
|
||||
typedef void (*show_object_fn)(struct object_array_entry *, void *);
|
||||
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 *, show_commit_fn, show_object_fn, void *);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -146,6 +146,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,
|
||||
|
|
|
@ -78,20 +78,22 @@ static void show_commit(struct commit *commit, void *data)
|
|||
commit->buffer = NULL;
|
||||
}
|
||||
|
||||
static void show_object(struct object_array_entry *p, void *data)
|
||||
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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче