Commit 5b68ba7e158367c9dc613754c50cad640a63fd52

nulltoken 2012-06-27T17:27:38

revparse: unfound treepath returns ENOTFOUND

diff --git a/src/revparse.c b/src/revparse.c
index 4bc6849..1b466cd 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -537,6 +537,7 @@ static int oid_for_tree_path(git_oid *out, git_tree *tree, git_repository *repo,
 	void *alloc;
 	git_tree *tree2 = tree;
 	const git_tree_entry *entry = NULL;
+	git_otype type;
 
 	if (*path == '\0') {
 		git_oid_cpy(out, git_object_id((git_object *)tree));
@@ -548,20 +549,40 @@ static int oid_for_tree_path(git_oid *out, git_tree *tree, git_repository *repo,
 	while ((tok = git__strtok(&str, "/\\")) != NULL) {
 		entry = git_tree_entry_byname(tree2, tok);
 		if (tree2 != tree) git_tree_free(tree2);
-		if (git_tree_entry__is_tree(entry)) {
-			if (str == '\0')
+
+		if (entry == NULL)
+			break;
+
+		type = git_tree_entry_type(entry);
+
+		switch (type) {
+		case GIT_OBJ_TREE:
+			if (*str == '\0')
 				break;
 			if (git_tree_lookup(&tree2, repo, &entry->oid) < 0) {
 				git__free(alloc);
 				return GIT_ERROR;
 			}
+			break;
+		case GIT_OBJ_BLOB:
+			if (*str != '\0') {
+				entry = NULL;
+				goto out;
+			}
+			break;
+		default:
+			/* TODO: support submodules? */
+			giterr_set(GITERR_INVALID, "Unimplemented");
+			git__free(alloc);
+			return GIT_ERROR;
 		}
 	}
 
+out:
 	if (!entry) {
 		giterr_set(GITERR_INVALID, "Invalid tree path '%s'", path);
 		git__free(alloc);
-		return GIT_ERROR;
+		return GIT_ENOTFOUND;
 	}
 
 	git_oid_cpy(out, git_tree_entry_id(entry));
@@ -631,6 +652,7 @@ static int revparse_global_grep(git_object **out, git_repository *repo, const ch
 			}
 			if (!resultobj) {
 				giterr_set(GITERR_REFERENCE, "Couldn't find a match for %s", pattern);
+				retcode = GIT_ENOTFOUND;
 				git_object_free(walkobj);
 			} else {
 				*out = resultobj;
diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c
index b8b1ed9..aaef90b 100644
--- a/tests-clar/refs/revparse.c
+++ b/tests-clar/refs/revparse.c
@@ -164,9 +164,13 @@ void test_refs_revparse__date(void)
 void test_refs_revparse__colon(void)
 {
 	cl_git_fail(git_revparse_single(&g_obj, g_repo, ":/"));
-	cl_git_fail(git_revparse_single(&g_obj, g_repo, ":/not found in any commit"));
 	cl_git_fail(git_revparse_single(&g_obj, g_repo, ":2:README"));
 
+	cl_assert_equal_i(GIT_ENOTFOUND, git_revparse_single(&g_obj, g_repo, ":/not found in any commit"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_revparse_single(&g_obj, g_repo, "subtrees:ab/42.txt"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_revparse_single(&g_obj, g_repo, "subtrees:ab/4.txt/nope"));
+	cl_assert_equal_i(GIT_ENOTFOUND, git_revparse_single(&g_obj, g_repo, "subtrees:nope"));
+
 	/* Trees */
 	test_object("master:", "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
 	test_object("subtrees:", "ae90f12eea699729ed24555e40b9fd669da12a12");