Code

Merge branch 'dp/maint-1.6.5-fast-import-non-commit-tag' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 19 Jan 2010 02:15:12 +0000 (18:15 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 19 Jan 2010 02:15:12 +0000 (18:15 -0800)
* dp/maint-1.6.5-fast-import-non-commit-tag:
  fast-import: tag may point to any object type

1  2 
fast-import.c

diff --combined fast-import.c
index cd8704987168be08bf488ffd191f57f2f80aea22,36c5a8ebd99fb1ec1a250f7f3be1ab13c3eca3a8..60d0aa2bb45490b90b1d68b26bb7ae5f7d035541
@@@ -19,11 -19,11 +19,11 @@@ Format of STDIN stream
  
    new_commit ::= 'commit' sp ref_str lf
      mark?
 -    ('author' sp name sp '<' email '>' sp when lf)?
 -    'committer' sp name sp '<' email '>' sp when lf
 +    ('author' (sp name)? sp '<' email '>' sp when lf)?
 +    'committer' (sp name)? sp '<' email '>' sp when lf
      commit_msg
 -    ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
 -    ('merge' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)*
 +    ('from' sp committish lf)?
 +    ('merge' sp committish lf)*
      file_change*
      lf?;
    commit_msg ::= data;
    file_obm ::= 'M' sp mode sp (hexsha1 | idnum) sp path_str lf;
    file_inm ::= 'M' sp mode sp 'inline' sp path_str lf
      data;
 +  note_obm ::= 'N' sp (hexsha1 | idnum) sp committish lf;
 +  note_inm ::= 'N' sp 'inline' sp committish lf
 +    data;
  
    new_tag ::= 'tag' sp tag_str lf
 -    'from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf
 -    ('tagger' sp name sp '<' email '>' sp when lf)?
 +    'from' sp committish lf
 +    ('tagger' (sp name)? sp '<' email '>' sp when lf)?
      tag_msg;
    tag_msg ::= data;
  
    reset_branch ::= 'reset' sp ref_str lf
 -    ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
 +    ('from' sp committish lf)?
      lf?;
  
    checkpoint ::= 'checkpoint' lf
@@@ -91,7 -88,6 +91,7 @@@
       # stream formatting is: \, " and LF.  Otherwise these values
       # are UTF8.
       #
 +  committish  ::= (ref_str | hexsha1 | sha1exp_str | idnum);
    ref_str     ::= ref;
    sha1exp_str ::= sha1exp;
    tag_str     ::= tag;
@@@ -2010,80 -2006,6 +2010,80 @@@ static void file_change_cr(struct branc
                leaf.tree);
  }
  
 +static void note_change_n(struct branch *b)
 +{
 +      const char *p = command_buf.buf + 2;
 +      static struct strbuf uq = STRBUF_INIT;
 +      struct object_entry *oe = oe;
 +      struct branch *s;
 +      unsigned char sha1[20], commit_sha1[20];
 +      uint16_t inline_data = 0;
 +
 +      /* <dataref> or 'inline' */
 +      if (*p == ':') {
 +              char *x;
 +              oe = find_mark(strtoumax(p + 1, &x, 10));
 +              hashcpy(sha1, oe->sha1);
 +              p = x;
 +      } else if (!prefixcmp(p, "inline")) {
 +              inline_data = 1;
 +              p += 6;
 +      } else {
 +              if (get_sha1_hex(p, sha1))
 +                      die("Invalid SHA1: %s", command_buf.buf);
 +              oe = find_object(sha1);
 +              p += 40;
 +      }
 +      if (*p++ != ' ')
 +              die("Missing space after SHA1: %s", command_buf.buf);
 +
 +      /* <committish> */
 +      s = lookup_branch(p);
 +      if (s) {
 +              hashcpy(commit_sha1, s->sha1);
 +      } else if (*p == ':') {
 +              uintmax_t commit_mark = strtoumax(p + 1, NULL, 10);
 +              struct object_entry *commit_oe = find_mark(commit_mark);
 +              if (commit_oe->type != OBJ_COMMIT)
 +                      die("Mark :%" PRIuMAX " not a commit", commit_mark);
 +              hashcpy(commit_sha1, commit_oe->sha1);
 +      } else if (!get_sha1(p, commit_sha1)) {
 +              unsigned long size;
 +              char *buf = read_object_with_reference(commit_sha1,
 +                      commit_type, &size, commit_sha1);
 +              if (!buf || size < 46)
 +                      die("Not a valid commit: %s", p);
 +              free(buf);
 +      } else
 +              die("Invalid ref name or SHA1 expression: %s", p);
 +
 +      if (inline_data) {
 +              static struct strbuf buf = STRBUF_INIT;
 +
 +              if (p != uq.buf) {
 +                      strbuf_addstr(&uq, p);
 +                      p = uq.buf;
 +              }
 +              read_next_command();
 +              parse_data(&buf);
 +              store_object(OBJ_BLOB, &buf, &last_blob, sha1, 0);
 +      } else if (oe) {
 +              if (oe->type != OBJ_BLOB)
 +                      die("Not a blob (actually a %s): %s",
 +                              typename(oe->type), command_buf.buf);
 +      } else {
 +              enum object_type type = sha1_object_info(sha1, NULL);
 +              if (type < 0)
 +                      die("Blob not found: %s", command_buf.buf);
 +              if (type != OBJ_BLOB)
 +                      die("Not a blob (actually a %s): %s",
 +                          typename(type), command_buf.buf);
 +      }
 +
 +      tree_content_set(&b->branch_tree, sha1_to_hex(commit_sha1), sha1,
 +              S_IFREG | 0644, NULL);
 +}
 +
  static void file_change_deleteall(struct branch *b)
  {
        release_tree_content_recursive(b->branch_tree.tree);
@@@ -2253,8 -2175,6 +2253,8 @@@ static void parse_new_commit(void
                        file_change_cr(b, 1);
                else if (!prefixcmp(command_buf.buf, "C "))
                        file_change_cr(b, 0);
 +              else if (!prefixcmp(command_buf.buf, "N "))
 +                      note_change_n(b);
                else if (!strcmp("deleteall", command_buf.buf))
                        file_change_deleteall(b);
                else {
@@@ -2305,6 -2225,7 +2305,7 @@@ static void parse_new_tag(void
        struct tag *t;
        uintmax_t from_mark = 0;
        unsigned char sha1[20];
+       enum object_type type;
  
        /* Obtain the new tag name from the rest of our command */
        sp = strchr(command_buf.buf, ' ') + 1;
        s = lookup_branch(from);
        if (s) {
                hashcpy(sha1, s->sha1);
+               type = OBJ_COMMIT;
        } else if (*from == ':') {
                struct object_entry *oe;
                from_mark = strtoumax(from + 1, NULL, 10);
                oe = find_mark(from_mark);
-               if (oe->type != OBJ_COMMIT)
-                       die("Mark :%" PRIuMAX " not a commit", from_mark);
+               type = oe->type;
                hashcpy(sha1, oe->sha1);
        } else if (!get_sha1(from, sha1)) {
                unsigned long size;
                char *buf;
  
-               buf = read_object_with_reference(sha1,
-                       commit_type, &size, sha1);
+               buf = read_sha1_file(sha1, &type, &size);
                if (!buf || size < 46)
                        die("Not a valid commit: %s", from);
                free(buf);
                    "object %s\n"
                    "type %s\n"
                    "tag %s\n",
-                   sha1_to_hex(sha1), commit_type, t->name);
+                   sha1_to_hex(sha1), typename(type), t->name);
        if (tagger)
                strbuf_addf(&new_data,
                            "tagger %s\n", tagger);
@@@ -2485,9 -2405,6 +2485,9 @@@ int main(int argc, const char **argv
  
        git_extract_argv0_path(argv[0]);
  
 +      if (argc == 2 && !strcmp(argv[1], "-h"))
 +              usage(fast_import_usage);
 +
        setup_git_directory();
        git_config(git_pack_config, NULL);
        if (!pack_compression_seen && core_compression_seen)