'git commit-tree' was the last remaining built-in to accept a <tree> but not a <tree-ish> (an indirect tree reference through a commit or tag object.) Signed-off-by: Mark Lodato <lodatom@xxxxxxxxx> --- A similar thing should be done for the parent commits. As far as I can tell, this is the only command that requires a commit object, not a tag. Documentation/git-commit-tree.txt | 4 +- builtin/commit-tree.c | 13 ++++++---- t/t1101-commit-tree-indirect.sh | 49 +++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) create mode 100755 t/t1101-commit-tree-indirect.sh diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 6188854..67b6bc0 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -8,7 +8,7 @@ git-commit-tree - Create a new commit object SYNOPSIS -------- -'git commit-tree' <tree> [-p <parent commit>]\* < changelog +'git commit-tree' <tree-ish> [-p <parent commit>]\* < changelog DESCRIPTION ----------- @@ -35,7 +35,7 @@ state was. OPTIONS ------- -<tree>:: +<tree-ish>:: An existing tree object -p <parent commit>:: diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 90dac34..96a421e 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -97,16 +97,19 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) { int i; struct commit_list *parents = NULL; - unsigned char tree_sha1[20]; - unsigned char commit_sha1[20]; + unsigned char sha1[20]; struct strbuf buffer = STRBUF_INIT; + struct tree *tree; git_config(git_default_config, NULL); if (argc < 2 || !strcmp(argv[1], "-h")) usage(commit_tree_usage); - if (get_sha1(argv[1], tree_sha1)) + if (get_sha1(argv[1], sha1)) die("Not a valid object name %s", argv[1]); + tree = parse_tree_indirect(sha1); + if (!tree) + die("%s is not a valid 'tree' object", argv[1]); for (i = 2; i < argc; i += 2) { unsigned char sha1[20]; @@ -124,8 +127,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) if (strbuf_read(&buffer, 0, 0) < 0) die_errno("git commit-tree: failed to read"); - if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) { - printf("%s\n", sha1_to_hex(commit_sha1)); + if (!commit_tree(buffer.buf, tree->object.sha1, parents, sha1, NULL)) { + printf("%s\n", sha1_to_hex(sha1)); return 0; } else diff --git a/t/t1101-commit-tree-indirect.sh b/t/t1101-commit-tree-indirect.sh new file mode 100755 index 0000000..905bad7 --- /dev/null +++ b/t/t1101-commit-tree-indirect.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# Copyright (c) 2010 Mark Lodato +# + +test_description='git commit-tree works with indirect references' + +. ./test-lib.sh + +get_tree() { + git cat-file commit $1 | sed -n -e 's/^tree //p' +} + +test_expect_success 'prepare the repository' ' + touch a && + git add a && + git commit -m x && + git tag -a -m x tag-commit && + git tag -a -m x tag-tree HEAD^{tree} && + git tag -a -m x tag-blob HEAD:a && + git tag -a -m x tag-tag-commit tag-commit +' + +expected_tree="$(get_tree HEAD)" + +test_success() { + test_expect_success "commit-tree succeeds with $2" ' + id="$(echo x | git commit-tree '"$1"')" && + tree="$(get_tree $id)" && + test "x$tree" = "x$expected_tree" + ' +} +test_failure() { + test_expect_code 128 "commit-tree fails with $2" ' + echo x | git commit-tree '"$1"' 2>/dev/null + ' +} + +test_failure HEAD:a "a blob" +test_success HEAD^{tree} "a tree" +test_success HEAD "HEAD" +test_success master "a branch" +test_failure foo "an invalid object name" +test_failure tag-blob "a tag pointing to a blob" +test_success tag-tree "a tag pointing to a tree" +test_success tag-commit "a tag pointing to a commit" +test_success tag-tag-commit "a tag pointing to a tag (to a commit)" + +test_done -- 1.7.0.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html