From 5f25b6299d3e9853cf1f43734228d6e25d8f3415 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 17 Aug 2011 14:30:33 -0700 Subject: rev-list: fix finish_object() call The callback to traverse_commit_list() are to take linked name_path and a string for the last path component. If the callee used its parameters, it would have seen duplicated leading paths. In this particular case, the callee does not use this argument but that is not a reason to leave the call broken. Signed-off-by: Junio C Hamano diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 56727e8..d789279 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -182,7 +182,7 @@ static void show_object(struct object *obj, const struct name_path *path, const */ const char *ep = strchr(name, '\n'); - finish_object(obj, path, name); + finish_object(obj, path, component); if (ep) { printf("%s %.*s\n", sha1_to_hex(obj->sha1), (int) (ep - name), -- cgit v0.10.2-6-g49f6 From 91f175165aba17903ab928da543052ea335fc924 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 17 Aug 2011 14:30:34 -0700 Subject: revision.c: add show_object_with_name() helper function There are two copies of traverse_commit_list callback that show the object name followed by pathname the object was found, to produce output similar to "rev-list --objects". Unify them. Signed-off-by: Junio C Hamano diff --git a/builtin/rev-list.c b/builtin/rev-list.c index d789279..f5ce487 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -176,21 +176,8 @@ static void finish_object(struct object *obj, const struct name_path *path, cons 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(name, '\n'); - finish_object(obj, path, component); - if (ep) { - printf("%s %.*s\n", sha1_to_hex(obj->sha1), - (int) (ep - name), - name); - } - else - printf("%s %s\n", sha1_to_hex(obj->sha1), name); - free(name); + show_object_with_name(stdout, obj, path, component); } static void show_edge(struct commit *commit) diff --git a/revision.c b/revision.c index c46cfaa..c5b38cc 100644 --- a/revision.c +++ b/revision.c @@ -40,6 +40,25 @@ char *path_name(const struct name_path *path, const char *name) return n; } +void show_object_with_name(FILE *out, struct object *obj, const struct name_path *path, const char *component) +{ + char *name = path_name(path, component); + const char *ep = strchr(name, '\n'); + + /* + * An object with name "foo\n0000000..." can be used to + * confuse downstream "git pack-objects" very badly. + */ + if (ep) { + fprintf(out, "%s %.*s\n", sha1_to_hex(obj->sha1), + (int) (ep - name), + name); + } + else + fprintf(out, "%s %s\n", sha1_to_hex(obj->sha1), name); + free(name); +} + void add_object(struct object *obj, struct object_array *p, struct name_path *path, diff --git a/revision.h b/revision.h index 3d64ada..da00a58 100644 --- a/revision.h +++ b/revision.h @@ -185,6 +185,8 @@ struct name_path { char *path_name(const struct name_path *path, const char *name); +extern void show_object_with_name(FILE *, struct object *, const struct name_path *, const char *); + 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 ce5cbbe..970a1eb 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -85,20 +85,7 @@ static void show_commit(struct commit *commit, 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 *name = path_name(path, component); - const char *ep = strchr(name, '\n'); - if (ep) { - 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(obj->sha1), name); - free((char *)name); + show_object_with_name(pack_pipe, obj, path, component); } static void show_edge(struct commit *commit) -- cgit v0.10.2-6-g49f6 From beba25abbc34a07e07ce933210cda15202ef76cc Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Wed, 17 Aug 2011 14:30:35 -0700 Subject: revision.c: update show_object_with_name() without using malloc() Allocating and then immediately freeing temporary memory a million times when listing a million objects is distasteful. Signed-off-by: Junio C Hamano diff --git a/revision.c b/revision.c index c5b38cc..072ddac 100644 --- a/revision.c +++ b/revision.c @@ -40,23 +40,45 @@ char *path_name(const struct name_path *path, const char *name) return n; } +static int show_path_component_truncated(FILE *out, const char *name, int len) +{ + int cnt; + for (cnt = 0; cnt < len; cnt++) { + int ch = name[cnt]; + if (!ch || ch == '\n') + return -1; + fputc(ch, out); + } + return len; +} + +static int show_path_truncated(FILE *out, const struct name_path *path) +{ + int emitted, ours; + + if (!path) + return 0; + emitted = show_path_truncated(out, path->up); + if (emitted < 0) + return emitted; + if (emitted) + fputc('/', out); + ours = show_path_component_truncated(out, path->elem, path->elem_len); + if (ours < 0) + return ours; + return ours || emitted; +} + void show_object_with_name(FILE *out, struct object *obj, const struct name_path *path, const char *component) { - char *name = path_name(path, component); - const char *ep = strchr(name, '\n'); + struct name_path leaf; + leaf.up = (struct name_path *)path; + leaf.elem = component; + leaf.elem_len = strlen(component); - /* - * An object with name "foo\n0000000..." can be used to - * confuse downstream "git pack-objects" very badly. - */ - if (ep) { - fprintf(out, "%s %.*s\n", sha1_to_hex(obj->sha1), - (int) (ep - name), - name); - } - else - fprintf(out, "%s %s\n", sha1_to_hex(obj->sha1), name); - free(name); + fprintf(out, "%s ", sha1_to_hex(obj->sha1)); + show_path_truncated(out, &leaf); + fputc('\n', out); } void add_object(struct object *obj, -- cgit v0.10.2-6-g49f6