提交 fb9a5415 编写于 作者: J Johannes Schindelin 提交者: Junio C Hamano

git-bundle: avoid fork() in verify_bundle()

We can use the revision walker easily for checking if the
prerequisites are met, instead of fork()ing off a rev-list,
which would list only the first unmet prerequisite.
Signed-off-by: NJohannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: NJunio C Hamano <junkio@cox.net>
上级 fa257b05
......@@ -19,7 +19,7 @@ static const char bundle_signature[] = "# v2 git bundle\n";
struct ref_list {
unsigned int nr, alloc;
struct {
struct ref_list_entry {
unsigned char sha1[20];
char *name;
} *list;
......@@ -167,33 +167,54 @@ static int verify_bundle(struct bundle_header *header)
* to be verbose about the errors
*/
struct ref_list *p = &header->prerequisites;
char **argv;
int pid, out, i, ret = 0;
char buffer[1024];
struct rev_info revs;
const char *argv[] = {NULL, "--all"};
struct object_array refs;
struct commit *commit;
int i, ret = 0, req_nr;
const char *message = "The bundle requires these lacking revs:";
argv = xmalloc((p->nr + 4) * sizeof(const char *));
argv[0] = "rev-list";
argv[1] = "--not";
argv[2] = "--all";
for (i = 0; i < p->nr; i++)
argv[i + 3] = xstrdup(sha1_to_hex(p->list[i].sha1));
argv[p->nr + 3] = NULL;
out = -1;
pid = fork_with_pipe((const char **)argv, NULL, &out);
if (pid < 0)
return error("Could not fork rev-list");
while (read_string(out, buffer, sizeof(buffer)) > 0)
; /* do nothing */
close(out);
for (i = 0; i < p->nr; i++)
free(argv[i + 3]);
free(argv);
while (waitpid(pid, &i, 0) < 0)
if (errno != EINTR)
return -1;
if (!ret && (!WIFEXITED(i) || WEXITSTATUS(i)))
return error("At least one prerequisite is lacking.");
init_revisions(&revs, NULL);
for (i = 0; i < p->nr; i++) {
struct ref_list_entry *e = p->list + i;
struct object *o = parse_object(e->sha1);
if (o) {
o->flags |= BOUNDARY_SHOW;
add_pending_object(&revs, o, e->name);
continue;
}
if (++ret == 1)
error(message);
error("%s %s", sha1_to_hex(e->sha1), e->name);
}
if (revs.pending.nr == 0)
return ret;
req_nr = revs.pending.nr;
setup_revisions(2, argv, &revs, NULL);
memset(&refs, 0, sizeof(struct object_array));
for (i = 0; i < revs.pending.nr; i++) {
struct object_array_entry *e = revs.pending.objects + i;
add_object_array(e->item, e->name, &refs);
}
prepare_revision_walk(&revs);
i = req_nr;
while (i && (commit = get_revision(&revs)))
if (commit->object.flags & BOUNDARY_SHOW)
i--;
for (i = 0; i < req_nr; i++)
if (!(refs.objects[i].item->flags & SHOWN)) {
if (++ret == 1)
error(message);
error("%s %s", sha1_to_hex(refs.objects[i].item->sha1),
refs.objects[i].name);
}
for (i = 0; i < refs.nr; i++)
clear_commit_marks((struct commit *)refs.objects[i].item, -1);
return ret;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册