diff --git a/include/git2/repository.h b/include/git2/repository.h index d606cfa2a..f891e91e9 100644 --- a/include/git2/repository.h +++ b/include/git2/repository.h @@ -305,7 +305,7 @@ GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo); * Check if a repository is empty * * An empty repository has just been initialized and contains - * no commits. + * no references. * * @param repo Repo to test * @return 1 if the repository is empty, 0 if it isn't, error code diff --git a/src/repository.c b/src/repository.c index 101497c4d..2d6ce4dbb 100644 --- a/src/repository.c +++ b/src/repository.c @@ -1241,36 +1241,47 @@ int git_repository_head_orphan(git_repository *repo) return 0; } +int at_least_one_cb(const char *refname, void *payload) +{ + GIT_UNUSED(refname); + GIT_UNUSED(payload); + + return GIT_EUSER; +} + +static int repo_contains_no_reference(git_repository *repo) +{ + int error; + + error = git_reference_foreach(repo, GIT_REF_LISTALL, at_least_one_cb, NULL); + + if (error == GIT_EUSER) + return 0; + + return error == 0 ? 1 : error; +} + int git_repository_is_empty(git_repository *repo) { - git_reference *head = NULL, *branch = NULL; - int error; + git_reference *head = NULL; + int error, ref_count = 0; if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) return -1; - if (git_reference_type(head) != GIT_REF_SYMBOLIC) { - git_reference_free(head); - return 0; - } + if (!(error = git_reference_type(head) == GIT_REF_SYMBOLIC)) + goto cleanup; - if (strcmp(git_reference_target(head), GIT_REFS_HEADS_DIR "master") != 0) { - git_reference_free(head); - return 0; - } + if (!(error = strcmp( + git_reference_target(head), + GIT_REFS_HEADS_DIR "master") == 0)) + goto cleanup; - error = git_reference_resolve(&branch, head); + error = repo_contains_no_reference(repo); +cleanup: git_reference_free(head); - git_reference_free(branch); - - if (error == GIT_ENOTFOUND) - return 1; - - if (error < 0) - return -1; - - return 0; + return error < 0 ? -1 : error; } const char *git_repository_path(git_repository *repo) diff --git a/tests-clar/repo/getters.c b/tests-clar/repo/getters.c index 299a2cb42..b372f5b70 100644 --- a/tests-clar/repo/getters.c +++ b/tests-clar/repo/getters.c @@ -1,16 +1,26 @@ #include "clar_libgit2.h" -void test_repo_getters__empty(void) +void test_repo_getters__is_empty_correctly_deals_with_pristine_looking_repos(void) { - git_repository *repo_empty, *repo_normal; + git_repository *repo; - cl_git_pass(git_repository_open(&repo_normal, cl_fixture("testrepo.git"))); - cl_assert(git_repository_is_empty(repo_normal) == 0); - git_repository_free(repo_normal); + repo = cl_git_sandbox_init("empty_bare.git"); + cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt"); - cl_git_pass(git_repository_open(&repo_empty, cl_fixture("empty_bare.git"))); - cl_assert(git_repository_is_empty(repo_empty) == 1); - git_repository_free(repo_empty); + cl_assert_equal_i(true, git_repository_is_empty(repo)); + + cl_git_sandbox_cleanup(); +} + +void test_repo_getters__is_empty_can_detect_used_repositories(void) +{ + git_repository *repo; + + cl_git_pass(git_repository_open(&repo, cl_fixture("testrepo.git"))); + + cl_assert_equal_i(false, git_repository_is_empty(repo)); + + git_repository_free(repo); } void test_repo_getters__retrieving_the_odb_honors_the_refcount(void)