Browse Source

Remove branch creation command from fast-import.

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>
maint
Shawn O. Pearce 19 years ago
parent
commit
00e2b8842c
  1. 169
      fast-import.c

169
fast-import.c

@ -4,7 +4,6 @@ Format of STDIN stream: @@ -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: @@ -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) @@ -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) @@ -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() @@ -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() @@ -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) @@ -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))

Loading…
Cancel
Save