From: Junio C Hamano Date: Wed, 8 Dec 2010 20:25:29 +0000 (-0800) Subject: Merge branch 'jn/fast-import-blob-access' into next X-Git-Tag: ko-next~81 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=a42f0b3dea41edc239ceb12e79de2d49950f132a;p=git.git Merge branch 'jn/fast-import-blob-access' into next * jn/fast-import-blob-access: t9300: remove unnecessary use of /dev/stdin fast-import: Allow cat-blob requests at arbitrary points in stream fast-import: let importers retrieve blobs fast-import: clarify documentation of "feature" command fast-import: stricter parsing of integer options Conflicts: fast-import.c --- a42f0b3dea41edc239ceb12e79de2d49950f132a diff --cc fast-import.c index 3c58e6f04,f71ea3e7b..785776086 --- a/fast-import.c +++ b/fast-import.c @@@ -362,10 -364,11 +365,14 @@@ static uintmax_t next_mark static struct strbuf new_data = STRBUF_INIT; static int seen_data_command; +/* Signal handling */ +static volatile sig_atomic_t checkpoint_requested; + + /* Where to write output of cat-blob commands */ + static int cat_blob_fd = STDOUT_FILENO; + static void parse_argv(void); + static void parse_cat_blob(void); static void write_branch_report(FILE *rpt, struct branch *b) { @@@ -2739,9 -2700,83 +2751,84 @@@ static void parse_reset_branch(void unread_command_buf = 1; } + static void cat_blob_write(const char *buf, unsigned long size) + { + if (write_in_full(cat_blob_fd, buf, size) != size) + die_errno("Write to frontend failed"); + } + + static void cat_blob(struct object_entry *oe, unsigned char sha1[20]) + { + struct strbuf line = STRBUF_INIT; + unsigned long size; + enum object_type type = 0; + char *buf; + + if (!oe || oe->pack_id == MAX_PACK_ID) { + buf = read_sha1_file(sha1, &type, &size); + } else { + type = oe->type; + buf = gfi_unpack_entry(oe, &size); + } + + /* + * Output based on batch_one_object() from cat-file.c. + */ + if (type <= 0) { + strbuf_reset(&line); + strbuf_addf(&line, "%s missing\n", sha1_to_hex(sha1)); + cat_blob_write(line.buf, line.len); + strbuf_release(&line); + free(buf); + return; + } + if (!buf) + die("Can't read object %s", sha1_to_hex(sha1)); + if (type != OBJ_BLOB) + die("Object %s is a %s but a blob was expected.", + sha1_to_hex(sha1), typename(type)); + strbuf_reset(&line); + strbuf_addf(&line, "%s %s %lu\n", sha1_to_hex(sha1), + typename(type), size); + cat_blob_write(line.buf, line.len); + strbuf_release(&line); + cat_blob_write(buf, size); + cat_blob_write("\n", 1); + free(buf); + } + + static void parse_cat_blob(void) + { + const char *p; + struct object_entry *oe = oe; + unsigned char sha1[20]; + + /* cat-blob SP LF */ + p = command_buf.buf + strlen("cat-blob "); + if (*p == ':') { + char *x; + oe = find_mark(strtoumax(p + 1, &x, 10)); + if (x == p + 1) + die("Invalid mark: %s", command_buf.buf); + if (!oe) + die("Unknown mark: %s", command_buf.buf); + if (*x) + die("Garbage after mark: %s", command_buf.buf); + hashcpy(sha1, oe->idx.sha1); + } else { + if (get_sha1_hex(p, sha1)) + die("Invalid SHA1: %s", command_buf.buf); + if (p[40]) + die("Garbage after SHA1: %s", command_buf.buf); + oe = find_object(sha1); + } + + cat_blob(oe, sha1); + } + -static void parse_checkpoint(void) +static void checkpoint(void) { + checkpoint_requested = 0; if (object_count) { cycle_packfile(); dump_branches();