Code

Merge branch 'jn/fast-import-blob-access' into next
authorJunio C Hamano <gitster@pobox.com>
Wed, 8 Dec 2010 20:25:29 +0000 (12:25 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 Dec 2010 20:25:29 +0000 (12:25 -0800)
* 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

1  2 
Documentation/git-fast-import.txt
fast-import.c
t/t9300-fast-import.sh

Simple merge
diff --cc fast-import.c
index 3c58e6f04a878c14f398b0fbb501475e842ea0ac,f71ea3e7bc5e0fc110dec9f983f37bbfcef9855d..785776086ccc22dcd5488e3ac0bad3318f57043e
@@@ -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 parse_checkpoint(void)
+ 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 <object> 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 checkpoint(void)
  {
 +      checkpoint_requested = 0;
        if (object_count) {
                cycle_packfile();
                dump_branches();
Simple merge