Remove branch creation command from fast-import.
authorShawn O. Pearce <spearce@spearce.org>
Thu, 24 Aug 2006 22:45:26 +0000 (18:45 -0400)
committerShawn O. Pearce <spearce@spearce.org>
Sun, 14 Jan 2007 07:15:06 +0000 (02:15 -0500)
Jon Smirl was finding it difficult to alter cvs2svn to generate
branch commands prior to the first commit of the same branch.
This change moves the 'from' command to be an optional parameter of
the 'commit' command, thereby allowing a new branch to be defined
at the moment it gets used to create the first commit on that branch.

This change makes it impossible to create a branch with no commits
on it as at least one commit is needed to register the branch.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
fast-import.c

index e42bdbd3a3f81db0cde87a2b8d7c7fbbbfb97e02..3e527edf70d3788b76d1d467913240921426cd28 100644 (file)
@@ -4,7 +4,6 @@ Format of STDIN stream:
   stream ::= cmd*;
 
   cmd ::= new_blob
-        | new_branch
         | new_commit
         | new_tag
         ;
@@ -14,15 +13,12 @@ Format of STDIN stream:
     file_content;
   file_content ::= data;
 
-  new_branch ::= 'branch' sp ref_str lf
-    ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
-    lf;
-
   new_commit ::= 'commit' sp ref_str lf
-       mark?
-       ('author' sp name '<' email '>' ts tz lf)?
-       'committer' sp name '<' email '>' ts tz lf
-       commit_msg
+    ('from' sp (ref_str | hexsha1 | sha1exp_str | idnum) lf)?
+    mark?
+    ('author' sp name '<' email '>' ts tz lf)?
+    'committer' sp name '<' email '>' ts tz lf
+    commit_msg
     file_change*
     lf;
   commit_msg ::= data;
@@ -831,7 +827,7 @@ static void load_tree(struct tree_entry *root)
        } else {
                char type[20];
                buf = read_sha1_file(root->sha1, type, &size);
-               if (!buf || !strcmp(type, tree_type))
+               if (!buf || strcmp(type, tree_type))
                        die("Can't load tree %s", sha1_to_hex(root->sha1));
        }
 
@@ -1299,6 +1295,69 @@ static void file_change_d(struct branch *b)
                free(p_uq);
 }
 
+static void cmd_from(struct branch *b)
+{
+       const char *from, *endp;
+       char *str_uq;
+       struct branch *s;
+
+       if (strncmp("from ", command_buf.buf, 5))
+               return;
+
+       if (b->last_commit)
+               die("Can't reinitailize branch %s", b->name);
+
+       from = strchr(command_buf.buf, ' ') + 1;
+       str_uq = unquote_c_style(from, &endp);
+       if (str_uq) {
+               if (*endp)
+                       die("Garbage after string in: %s", command_buf.buf);
+               from = str_uq;
+       }
+
+       s = lookup_branch(from);
+       if (b == s)
+               die("Can't create a branch from itself: %s", b->name);
+       else if (s) {
+               memcpy(b->sha1, s->sha1, 20);
+               memcpy(b->branch_tree.sha1, s->branch_tree.sha1, 20);
+       } else if (*from == ':') {
+               unsigned long idnum = strtoul(from + 1, NULL, 10);
+               struct object_entry *oe = find_mark(idnum);
+               unsigned long size;
+               char *buf;
+               if (oe->type != OBJ_COMMIT)
+                       die("Mark :%lu not a commit", idnum);
+               memcpy(b->sha1, oe->sha1, 20);
+               buf = unpack_entry(oe->offset, &size);
+               if (!buf || size < 46)
+                       die("Not a valid commit: %s", from);
+               if (memcmp("tree ", buf, 5)
+                       || get_sha1_hex(buf + 5, b->branch_tree.sha1))
+                       die("The commit %s is corrupt", sha1_to_hex(b->sha1));
+               free(buf);
+       } else if (!get_sha1(from, b->sha1)) {
+               if (!memcmp(b->sha1, null_sha1, 20))
+                       memcpy(b->branch_tree.sha1, null_sha1, 20);
+               else {
+                       unsigned long size;
+                       char *buf;
+
+                       buf = read_object_with_reference(b->sha1,
+                               type_names[OBJ_COMMIT], &size, b->sha1);
+                       if (!buf || size < 46)
+                               die("Not a valid commit: %s", from);
+                       if (memcmp("tree ", buf, 5)
+                               || get_sha1_hex(buf + 5, b->branch_tree.sha1))
+                               die("The commit %s is corrupt", sha1_to_hex(b->sha1));
+                       free(buf);
+               }
+       } else
+               die("Invalid ref name or SHA1 expression: %s", from);
+
+       read_next_command();
+}
+
 static void cmd_new_commit()
 {
        struct branch *b;
@@ -1321,11 +1380,12 @@ static void cmd_new_commit()
        }
        b = lookup_branch(sp);
        if (!b)
-               die("Branch not declared: %s", sp);
+               b = new_branch(sp);
        if (str_uq)
                free(str_uq);
 
        read_next_command();
+       cmd_from(b);
        cmd_mark();
        if (!strncmp("author ", command_buf.buf, 7)) {
                author = strdup(command_buf.buf);
@@ -1385,91 +1445,6 @@ static void cmd_new_commit()
        b->last_commit = object_count_by_type[OBJ_COMMIT];
 }
 
-static void cmd_new_branch()
-{
-       struct branch *b;
-       char *str_uq;
-       const char *endp;
-       char *sp;
-
-       /* Obtain the new branch name from the rest of our command */
-       sp = strchr(command_buf.buf, ' ') + 1;
-       str_uq = unquote_c_style(sp, &endp);
-       if (str_uq) {
-               if (*endp)
-                       die("Garbage after ref in: %s", command_buf.buf);
-               sp = str_uq;
-       }
-       b = new_branch(sp);
-       if (str_uq)
-               free(str_uq);
-       read_next_command();
-
-       /* from ... */
-       if (!strncmp("from ", command_buf.buf, 5)) {
-               const char *from;
-               struct branch *s;
-
-               from = strchr(command_buf.buf, ' ') + 1;
-               str_uq = unquote_c_style(from, &endp);
-               if (str_uq) {
-                       if (*endp)
-                               die("Garbage after string in: %s", command_buf.buf);
-                       from = str_uq;
-               }
-
-               s = lookup_branch(from);
-               if (b == s)
-                       die("Can't create a branch from itself: %s", b->name);
-               else if (s) {
-                       memcpy(b->sha1, s->sha1, 20);
-                       memcpy(b->branch_tree.sha1, s->branch_tree.sha1, 20);
-               } else if (*from == ':') {
-                       unsigned long idnum = strtoul(from + 1, NULL, 10);
-                       struct object_entry *oe = find_mark(idnum);
-                       unsigned long size;
-                       char *buf;
-                       if (oe->type != OBJ_COMMIT)
-                               die("Mark :%lu not a commit", idnum);
-                       memcpy(b->sha1, oe->sha1, 20);
-                       buf = unpack_entry(oe->offset, &size);
-                       if (!buf || size < 46)
-                               die("Not a valid commit: %s", from);
-                       if (memcmp("tree ", buf, 5)
-                               || get_sha1_hex(buf + 5, b->branch_tree.sha1))
-                               die("The commit %s is corrupt", sha1_to_hex(b->sha1));
-                       free(buf);
-               } else if (!get_sha1(from, b->sha1)) {
-                       if (!memcmp(b->sha1, null_sha1, 20))
-                               memcpy(b->branch_tree.sha1, null_sha1, 20);
-                       else {
-                               unsigned long size;
-                               char *buf;
-
-                               buf = read_object_with_reference(b->sha1,
-                                       type_names[OBJ_COMMIT], &size, b->sha1);
-                               if (!buf || size < 46)
-                                       die("Not a valid commit: %s", from);
-                               if (memcmp("tree ", buf, 5)
-                                       || get_sha1_hex(buf + 5, b->branch_tree.sha1))
-                                       die("The commit %s is corrupt", sha1_to_hex(b->sha1));
-                               free(buf);
-                       }
-               } else
-                       die("Invalid ref name or SHA1 expression: %s", from);
-
-               if (str_uq)
-                       free(str_uq);
-               read_next_command();
-       } else {
-               memcpy(b->sha1, null_sha1, 20);
-               memcpy(b->branch_tree.sha1, null_sha1, 20);
-       }
-
-       if (command_buf.eof || command_buf.len > 1)
-               die("An lf did not terminate the branch command as expected.");
-}
-
 static void cmd_new_tag()
 {
        char *str_uq;
@@ -1623,8 +1598,6 @@ int main(int argc, const char **argv)
                        break;
                else if (!strcmp("blob", command_buf.buf))
                        cmd_new_blob();
-               else if (!strncmp("branch ", command_buf.buf, 7))
-                       cmd_new_branch();
                else if (!strncmp("commit ", command_buf.buf, 7))
                        cmd_new_commit();
                else if (!strncmp("tag ", command_buf.buf, 4))