mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-28 04:29:42 +00:00
Merge pull request #1097 from nulltoken/topic/head_tree_error
Make `git_repository_head_tree()` return error codes
This commit is contained in:
commit
c4d8df27bc
@ -440,7 +440,9 @@ static int checkout_get_actions(
|
||||
const git_index_entry *he;
|
||||
|
||||
/* if there is no HEAD, that's okay - we'll make an empty iterator */
|
||||
(void)git_repository_head_tree(&head, data->repo);
|
||||
if (((error = git_repository_head_tree(&head, data->repo)) < 0) &&
|
||||
!(error == GIT_ENOTFOUND || error == GIT_EORPHANEDHEAD))
|
||||
return -1;
|
||||
|
||||
if ((error = git_iterator_for_tree_range(
|
||||
&hiter, data->repo, head, pfx, pfx)) < 0)
|
||||
|
40
src/object.c
40
src/object.c
@ -304,46 +304,6 @@ size_t git_object__size(git_otype type)
|
||||
return git_objects_table[type].size;
|
||||
}
|
||||
|
||||
int git_object__resolve_to_type(git_object **obj, git_otype type)
|
||||
{
|
||||
int error = 0;
|
||||
git_object *scan, *next;
|
||||
|
||||
if (type == GIT_OBJ_ANY)
|
||||
return 0;
|
||||
|
||||
scan = *obj;
|
||||
|
||||
while (!error && scan && git_object_type(scan) != type) {
|
||||
|
||||
switch (git_object_type(scan)) {
|
||||
case GIT_OBJ_COMMIT:
|
||||
{
|
||||
git_tree *tree = NULL;
|
||||
error = git_commit_tree(&tree, (git_commit *)scan);
|
||||
next = (git_object *)tree;
|
||||
break;
|
||||
}
|
||||
|
||||
case GIT_OBJ_TAG:
|
||||
error = git_tag_target(&next, (git_tag *)scan);
|
||||
break;
|
||||
|
||||
default:
|
||||
giterr_set(GITERR_REFERENCE, "Object does not resolve to type");
|
||||
error = -1;
|
||||
next = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
git_object_free(scan);
|
||||
scan = next;
|
||||
}
|
||||
|
||||
*obj = scan;
|
||||
return error;
|
||||
}
|
||||
|
||||
static int peel_error(int error, const char* msg)
|
||||
{
|
||||
giterr_set(GITERR_INVALID, "The given object cannot be peeled - %s", msg);
|
||||
|
@ -1384,22 +1384,21 @@ int git_repository_is_bare(git_repository *repo)
|
||||
|
||||
int git_repository_head_tree(git_tree **tree, git_repository *repo)
|
||||
{
|
||||
git_oid head_oid;
|
||||
git_object *obj = NULL;
|
||||
git_reference *head;
|
||||
git_object *obj;
|
||||
int error;
|
||||
|
||||
if (git_reference_name_to_oid(&head_oid, repo, GIT_HEAD_FILE) < 0) {
|
||||
/* cannot resolve HEAD - probably brand new repo */
|
||||
giterr_clear();
|
||||
*tree = NULL;
|
||||
return 0;
|
||||
}
|
||||
if ((error = git_repository_head(&head, repo)) < 0)
|
||||
return error;
|
||||
|
||||
if (git_object_lookup(&obj, repo, &head_oid, GIT_OBJ_ANY) < 0 ||
|
||||
git_object__resolve_to_type(&obj, GIT_OBJ_TREE) < 0)
|
||||
return -1;
|
||||
if ((error = git_reference_peel(&obj, head, GIT_OBJ_TREE)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
*tree = (git_tree *)obj;
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
git_reference_free(head);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_repository_message(char *buffer, size_t len, git_repository *repo)
|
||||
|
@ -121,8 +121,10 @@ int git_status_foreach_ext(
|
||||
(err = git_repository__ensure_not_bare(repo, "status")) < 0)
|
||||
return err;
|
||||
|
||||
if ((err = git_repository_head_tree(&head, repo)) < 0)
|
||||
return err;
|
||||
/* if there is no HEAD, that's okay - we'll make an empty iterator */
|
||||
if (((err = git_repository_head_tree(&head, repo)) < 0) &&
|
||||
!(err == GIT_ENOTFOUND || err == GIT_EORPHANEDHEAD))
|
||||
return err;
|
||||
|
||||
memset(&diffopt, 0, sizeof(diffopt));
|
||||
memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
|
||||
|
@ -19,9 +19,9 @@ void test_repo_head__head_detached(void)
|
||||
{
|
||||
git_reference *ref;
|
||||
|
||||
cl_assert(git_repository_head_detached(repo) == 0);
|
||||
cl_git_pass(git_repository_head_detached(repo));
|
||||
|
||||
git_repository_detach_head(repo);
|
||||
cl_git_pass(git_repository_detach_head(repo));
|
||||
|
||||
cl_assert_equal_i(true, git_repository_head_detached(repo));
|
||||
|
||||
@ -36,7 +36,7 @@ void test_repo_head__head_orphan(void)
|
||||
{
|
||||
git_reference *ref;
|
||||
|
||||
cl_assert(git_repository_head_orphan(repo) == 0);
|
||||
cl_git_pass(git_repository_head_detached(repo));
|
||||
|
||||
make_head_orphaned(repo, NON_EXISTING_HEAD);
|
||||
|
||||
|
53
tests-clar/repo/headtree.c
Normal file
53
tests-clar/repo/headtree.c
Normal file
@ -0,0 +1,53 @@
|
||||
#include "clar_libgit2.h"
|
||||
#include "repository.h"
|
||||
#include "repo_helpers.h"
|
||||
#include "posix.h"
|
||||
|
||||
static git_repository *repo;
|
||||
static git_tree *tree;
|
||||
|
||||
void test_repo_headtree__initialize(void)
|
||||
{
|
||||
repo = cl_git_sandbox_init("testrepo.git");
|
||||
tree = NULL;
|
||||
}
|
||||
|
||||
void test_repo_headtree__cleanup(void)
|
||||
{
|
||||
git_tree_free(tree);
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
|
||||
void test_repo_headtree__can_retrieve_the_root_tree_from_a_detached_head(void)
|
||||
{
|
||||
cl_git_pass(git_repository_detach_head(repo));
|
||||
|
||||
cl_git_pass(git_repository_head_tree(&tree, repo));
|
||||
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), "az"));
|
||||
}
|
||||
|
||||
void test_repo_headtree__can_retrieve_the_root_tree_from_a_non_detached_head(void)
|
||||
{
|
||||
cl_assert_equal_i(false, git_repository_head_detached(repo));
|
||||
|
||||
cl_git_pass(git_repository_head_tree(&tree, repo));
|
||||
|
||||
cl_assert(git_oid_streq(git_tree_id(tree), "az"));
|
||||
}
|
||||
|
||||
void test_repo_headtree__when_head_is_orphaned_returns_EORPHANEDHEAD(void)
|
||||
{
|
||||
make_head_orphaned(repo, NON_EXISTING_HEAD);
|
||||
|
||||
cl_assert_equal_i(true, git_repository_head_orphan(repo));
|
||||
|
||||
cl_assert_equal_i(GIT_EORPHANEDHEAD, git_repository_head_tree(&tree, repo));
|
||||
}
|
||||
|
||||
void test_repo_headtree__when_head_is_missing_returns_ENOTFOUND(void)
|
||||
{
|
||||
delete_head(repo);
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_repository_head_tree(&tree, repo));
|
||||
}
|
Loading…
Reference in New Issue
Block a user