X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=builtin-mktree.c;h=098395fda1932674e29f8d2cb332c722a6cb275f;hb=e4d1afbcf2e39a997ae90befd629ee53e444c4c9;hp=5ff04753b756a72c521d6a95321417812e90e865;hpb=e01662bb5da721d65226f4b173858ea3bf0bde30;p=git.git diff --git a/builtin-mktree.c b/builtin-mktree.c index 5ff04753b..098395fda 100644 --- a/builtin-mktree.c +++ b/builtin-mktree.c @@ -63,7 +63,7 @@ static void write_tree(unsigned char *sha1) } static const char *mktree_usage[] = { - "git mktree [-z] [--missing]", + "git mktree [-z] [--missing] [--batch]", NULL }; @@ -71,7 +71,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m { char *ptr, *ntr; unsigned mode; - enum object_type type; + enum object_type mode_type; /* object type derived from mode */ + enum object_type obj_type; /* object type derived from sha */ char *path; unsigned char sha1[20]; @@ -94,17 +95,8 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m if (S_ISGITLINK(mode)) allow_missing = 1; - if (!allow_missing) - type = sha1_object_info(sha1, NULL); - else - type = object_type(mode); - - if (type < 0) - die("object %s unavailable", sha1_to_hex(sha1)); *ntr++ = 0; /* now at the beginning of SHA1 */ - if (type != type_from_string(ptr)) - die("object type %s mismatch (%s)", ptr, typename(type)); path = ntr + 41; /* at the beginning of name */ if (line_termination && path[0] == '"') { @@ -113,6 +105,37 @@ static void mktree_line(char *buf, size_t len, int line_termination, int allow_m die("invalid quoting"); path = strbuf_detach(&p_uq, NULL); } + + /* + * Object type is redundantly derivable three ways. + * These should all agree. + */ + mode_type = object_type(mode); + if (mode_type != type_from_string(ptr)) { + die("entry '%s' object type (%s) doesn't match mode type (%s)", + path, ptr, typename(mode_type)); + } + + /* Check the type of object identified by sha1 */ + obj_type = sha1_object_info(sha1, NULL); + if (obj_type < 0) { + if (allow_missing) { + ; /* no problem - missing objects are presumed to be of the right type */ + } else { + die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1)); + } + } else { + if (obj_type != mode_type) { + /* + * The object exists but is of the wrong type. + * This is a problem regardless of allow_missing + * because the new tree entry will never be correct. + */ + die("entry '%s' object %s is a %s but specified type was (%s)", + path, sha1_to_hex(sha1), typename(obj_type), typename(mode_type)); + } + } + append_to_tree(mode, sha1, path); } @@ -122,20 +145,46 @@ int cmd_mktree(int ac, const char **av, const char *prefix) unsigned char sha1[20]; int line_termination = '\n'; int allow_missing = 0; + int is_batch_mode = 0; + int got_eof = 0; + const struct option option[] = { OPT_SET_INT('z', NULL, &line_termination, "input is NUL terminated", '\0'), OPT_SET_INT( 0 , "missing", &allow_missing, "allow missing objects", 1), + OPT_SET_INT( 0 , "batch", &is_batch_mode, "allow creation of more than one tree", 1), OPT_END() }; - ac = parse_options(ac, av, option, mktree_usage, 0); - - while (strbuf_getline(&sb, stdin, line_termination) != EOF) - mktree_line(sb.buf, sb.len, line_termination, allow_missing); - + ac = parse_options(ac, av, prefix, option, mktree_usage, 0); + + while (!got_eof) { + while (1) { + if (strbuf_getline(&sb, stdin, line_termination) == EOF) { + got_eof = 1; + break; + } + if (sb.buf[0] == '\0') { + /* empty lines denote tree boundaries in batch mode */ + if (is_batch_mode) + break; + die("input format error: (blank line only valid in batch mode)"); + } + mktree_line(sb.buf, sb.len, line_termination, allow_missing); + } + if (is_batch_mode && got_eof && used < 1) { + /* + * Execution gets here if the last tree entry is terminated with a + * new-line. The final new-line has been made optional to be + * consistent with the original non-batch behaviour of mktree. + */ + ; /* skip creating an empty tree */ + } else { + write_tree(sha1); + puts(sha1_to_hex(sha1)); + fflush(stdout); + } + used=0; /* reset tree entry buffer for re-use in batch mode */ + } strbuf_release(&sb); - - write_tree(sha1); - puts(sha1_to_hex(sha1)); exit(0); }