-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.");
-}
-