Commit 387d01b8578ebedc665d8fa707b8897f9a04f380

Ben Straub 2012-04-27T11:47:29

Implemented rev-parse "^{type}" syntax.

diff --git a/src/revparse.c b/src/revparse.c
index da274f8..472cc75 100644
--- a/src/revparse.c
+++ b/src/revparse.c
@@ -116,7 +116,7 @@ static int revparse_lookup_object(git_object **out, git_repository *repo, const 
 
 static int walk_ref_history(git_object **out, const char *refspec, const char *reflogspec)
 {
-   // TODO
+   /* TODO */
 
    /* Empty refspec means current branch */
 
@@ -134,25 +134,25 @@ static git_object* dereference_object(git_object *obj)
 {
    git_otype type = git_object_type(obj);
    git_object *newobj = NULL;
+   git_tree *tree = NULL;
 
    switch (type) {
    case GIT_OBJ_COMMIT:
-      break;
-   case GIT_OBJ_TREE:
-      break;
-   case GIT_OBJ_BLOB:
+      if (0 == git_commit_tree(&tree, (git_commit*)obj)) {
+         return (git_object*)tree;
+      }
       break;
    case GIT_OBJ_TAG:
       if (0 == git_tag_target(&newobj, (git_tag*)obj)) {
          return newobj;
       }
       break;
-   case GIT_OBJ_OFS_DELTA:
-      break;
-   case GIT_OBJ_REF_DELTA:
-      break;
 
    default:
+   case GIT_OBJ_TREE:
+   case GIT_OBJ_BLOB:
+   case GIT_OBJ_OFS_DELTA:
+   case GIT_OBJ_REF_DELTA:
       break;
    }
 
@@ -168,14 +168,14 @@ static int dereference_to_type(git_object **out, git_object *obj, git_otype targ
       git_otype this_type = git_object_type(obj1);
 
       if (this_type == target_type) {
-         *out = obj;
+         *out = obj1;
          return 0;
       }
 
       /* Dereference once, if possible. */
       obj2 = dereference_object(obj1);
-      if (obj2 != obj) {
-         git_object_free(obj2);
+      if (obj1 != obj) {
+         git_object_free(obj1);
       }
       obj1 = obj2;
    }
@@ -212,7 +212,7 @@ static int handle_caret_syntax(git_object **out, git_object *obj, const char *mo
                giterr_set(GITERR_REFERENCE, "Couldn't find object of target type.");
                return GIT_ERROR;
             }
-            newobj = newobj;
+            newobj = newobj2;
          }
          *out = newobj2;
          return 0;
@@ -220,7 +220,7 @@ static int handle_caret_syntax(git_object **out, git_object *obj, const char *mo
       
       /* {/...} -> Walk all commits until we see a commit msg that matches the phrase. */
       if (movement[1] == '/') {
-         // TODO
+         /* TODO */
          return GIT_ERROR;
       }
 
diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c
index 64aca4a..c1be32f 100644
--- a/tests-clar/refs/revparse.c
+++ b/tests-clar/refs/revparse.c
@@ -7,7 +7,7 @@ static git_object *g_obj;
 
 
 
-// Hepers
+/* Helpers */
 static void oid_str_cmp(const git_object *obj, const char *expected)
 {
    char objstr[64] = {0};
@@ -35,7 +35,6 @@ void test_refs_revparse__nonexistant_object(void)
 
 void test_refs_revparse__shas(void)
 {
-   // Full SHA should return a valid object
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "c47800c7266a2be04c571c04d5a6614691ea99bd"));
    oid_str_cmp(g_obj, "c47800c7266a2be04c571c04d5a6614691ea99bd");
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "c47800c"));
@@ -44,14 +43,12 @@ void test_refs_revparse__shas(void)
 
 void test_refs_revparse__head(void)
 {
-   // Named head should return a valid object
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "HEAD"));
    oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
 }
 
 void test_refs_revparse__full_refs(void)
 {
-   // Fully-qualified refs should return valid objects
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "refs/heads/master"));
    oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "refs/heads/test"));
@@ -62,7 +59,6 @@ void test_refs_revparse__full_refs(void)
 
 void test_refs_revparse__partial_refs(void)
 {
-   // Partially-qualified refs should return valid objects
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "point_to_blob"));
    oid_str_cmp(g_obj, "1385f264afb75a56a5bec74243be9b367ba4ca08");
    cl_git_pass(git_revparse_single(&g_obj, g_repo, "packed-test"));
@@ -103,9 +99,15 @@ void test_refs_revparse__not_tag(void)
 
 void test_refs_revparse__to_type(void)
 {
+   cl_git_pass(git_revparse_single(&g_obj, g_repo, "wrapped_tag^{commit}"));
+   oid_str_cmp(g_obj, "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
+   cl_git_pass(git_revparse_single(&g_obj, g_repo, "wrapped_tag^{tree}"));
+   oid_str_cmp(g_obj, "944c0f6e4dfa41595e6eb3ceecdb14f50fe18162");
+   cl_git_pass(git_revparse_single(&g_obj, g_repo, "point_to_blob^{blob}"));
+   oid_str_cmp(g_obj, "1385f264afb75a56a5bec74243be9b367ba4ca08");
 }
 
 void test_refs_revparse__reflog(void)
 {
-   // TODO: how to create a fixture for this? git_reflog_write?
+   /* TODO: how to create a fixture for this? git_reflog_write? */
 }