diff --git a/builtin-mktree.c b/builtin-mktree.c index 17cdb3d63a..e1c9a2701a 100644 --- a/builtin-mktree.c +++ b/builtin-mktree.c @@ -67,7 +67,7 @@ static const char *mktree_usage[] = { NULL }; -static void mktree_line(char *buf, size_t len, int line_termination) +static void mktree_line(char *buf, size_t len, int line_termination, int allow_missing) { char *ptr, *ntr; unsigned mode; @@ -91,10 +91,13 @@ static void mktree_line(char *buf, size_t len, int line_termination) die("input format error: %s", buf); /* It is perfectly normal if we do not have a commit from a submodule */ - if (!S_ISGITLINK(mode)) + if (S_ISGITLINK(mode)) + allow_missing = 1; + + if (!allow_missing) type = sha1_object_info(sha1, NULL); else - type = OBJ_COMMIT; + type = object_type(mode); if (type < 0) die("object %s unavailable", sha1_to_hex(sha1)); @@ -118,15 +121,17 @@ int cmd_mktree(int ac, const char **av, const char *prefix) struct strbuf sb = STRBUF_INIT; unsigned char sha1[20]; int line_termination = '\n'; + int allow_missing = 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_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); + mktree_line(sb.buf, sb.len, line_termination, allow_missing); strbuf_release(&sb); diff --git a/t/t1010-mktree.sh b/t/t1010-mktree.sh index 4d9b1383c6..9956e3ad62 100755 --- a/t/t1010-mktree.sh +++ b/t/t1010-mktree.sh @@ -10,6 +10,11 @@ test_expect_success setup ' mkdir "$d" && echo "$d/one" >"$d/one" && git add "$d" done && + echo zero >one && + git update-index --add --info-only one && + git write-tree --missing-ok >tree.missing && + git ls-tree $(cat tree.missing) >top.missing && + git ls-tree -r $(cat tree.missing) >all.missing && echo one >one && git add one && git write-tree >tree && @@ -48,6 +53,11 @@ test_expect_success 'ls-tree output in wrong order given to mktree (2)' ' test_cmp tree.withsub actual ' +test_expect_success 'allow missing object with --missing' ' + git mktree --missing actual && + test_cmp tree.missing actual +' + test_expect_failure 'mktree reads ls-tree -r output (1)' ' git mktree actual && test_cmp tree actual