]> git.proxmox.com Git - libgit2.git/commitdiff
repository: introduce git_repository_set_head_detached()
authornulltoken <emeric.fermas@gmail.com>
Sat, 15 Sep 2012 20:07:09 +0000 (22:07 +0200)
committernulltoken <emeric.fermas@gmail.com>
Mon, 17 Sep 2012 08:48:35 +0000 (10:48 +0200)
include/git2/repository.h
src/repository.c
tests-clar/repo/head.c

index e68e0548f1e7e0b779a5947c74f27171806a7aaa..59a7d2c9848b06476231a54dac10c9bc9e49a111 100644 (file)
@@ -506,6 +506,26 @@ GIT_EXTERN(int) git_repository_hashfile(
     git_otype type,
     const char *as_path);
 
+/**
+ * Make the repository HEAD directly point to the Commit.
+ *
+ * If the provided committish cannot be found in the repository, the HEAD
+ * is unaltered and GIT_ENOTFOUND is returned.
+ *
+ * If the provided commitish cannot be peeled into a commit, the HEAD
+ * is unaltered and -1 is returned.
+ *
+ * Otherwise, the HEAD will eventually be detached and will directly point to
+ * the peeled Commit.
+ *
+ * @param repo Repository pointer
+ * @param commitish Object id of the Commit the HEAD should point to
+ * @return 0 on success, or an error code
+ */
+GIT_EXTERN(int) git_repository_set_head_detached(
+       git_repository* repo,
+       const git_oid* commitish);
+
 /**
  * Detach the HEAD.
  *
index def96816ffe39e7644dcfec0e970a15d01e4616c..a3e781478df97714c6b62046e2fa6050a351458d 100644 (file)
@@ -1442,6 +1442,32 @@ cleanup:
        return error;
 }
 
+int git_repository_set_head_detached(
+       git_repository* repo,
+       const git_oid* commitish)
+{
+       int error;
+       git_object *object,
+               *peeled = NULL;
+       git_reference *new_head = NULL;
+
+       assert(repo && commitish);
+
+       if ((error = git_object_lookup(&object, repo, commitish, GIT_OBJ_ANY)) < 0)
+               return error;
+
+       if ((error = git_object_peel(&peeled, object, GIT_OBJ_COMMIT)) < 0)
+               goto cleanup;
+
+       error = git_reference_create_oid(&new_head, repo, GIT_HEAD_FILE, git_object_id(peeled), 1);
+
+cleanup:
+       git_object_free(object);
+       git_object_free(peeled);
+       git_reference_free(new_head);
+       return error;
+}
+
 int git_repository_detach_head(
        git_repository* repo)
 {
index 74d2a1c88d8e78b7936776e3525d40fb74ce4087..372cdd61de096fea30d8090f7bbd4d875a2951ad 100644 (file)
@@ -66,6 +66,40 @@ static void assert_head_is_correctly_detached(void)
        git_reference_free(head);
 }
 
+void test_repo_head__set_head_detached_Return_ENOTFOUND_when_the_object_doesnt_exist(void)
+{
+       git_oid oid;
+
+       cl_git_pass(git_oid_fromstr(&oid, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"));
+
+       cl_assert_equal_i(GIT_ENOTFOUND, git_repository_set_head_detached(repo, &oid));
+}
+
+void test_repo_head__set_head_detached_Fails_when_the_object_isnt_a_commitish(void)
+{
+       git_object *blob;
+
+       cl_git_pass(git_revparse_single(&blob, repo, "point_to_blob"));
+
+       cl_git_fail(git_repository_set_head_detached(repo, git_object_id(blob)));
+
+       git_object_free(blob);
+}
+
+void test_repo_head__set_head_detached_Detaches_HEAD_and_make_it_point_to_the_peeled_commit(void)
+{
+       git_object *tag;
+
+       cl_git_pass(git_revparse_single(&tag, repo, "tags/test"));
+       cl_assert_equal_i(GIT_OBJ_TAG, git_object_type(tag));
+
+       cl_git_pass(git_repository_set_head_detached(repo, git_object_id(tag)));
+
+       assert_head_is_correctly_detached();
+
+       git_object_free(tag);
+}
+
 void test_repo_head__detach_head_Detaches_HEAD_and_make_it_point_to_the_peeled_commit(void)
 {
        cl_assert_equal_i(false, git_repository_head_detached(repo));