summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/git2/repository.h2
-rw-r--r--src/repository.c51
-rw-r--r--tests-clar/repo/getters.c26
3 files changed, 50 insertions, 29 deletions
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 git_repository_is_empty(git_repository *repo)
+int at_least_one_cb(const char *refname, void *payload)
{
- git_reference *head = NULL, *branch = NULL;
- int error;
+ GIT_UNUSED(refname);
+ GIT_UNUSED(payload);
- if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
- return -1;
+ return GIT_EUSER;
+}
- if (git_reference_type(head) != GIT_REF_SYMBOLIC) {
- git_reference_free(head);
- return 0;
- }
+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 (strcmp(git_reference_target(head), GIT_REFS_HEADS_DIR "master") != 0) {
- git_reference_free(head);
+ if (error == GIT_EUSER)
return 0;
- }
- error = git_reference_resolve(&branch, head);
-
- git_reference_free(head);
- git_reference_free(branch);
+ return error == 0 ? 1 : error;
+}
- if (error == GIT_ENOTFOUND)
- return 1;
+int git_repository_is_empty(git_repository *repo)
+{
+ git_reference *head = NULL;
+ int error, ref_count = 0;
- if (error < 0)
+ if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
return -1;
- return 0;
+ if (!(error = git_reference_type(head) == GIT_REF_SYMBOLIC))
+ goto cleanup;
+
+ if (!(error = strcmp(
+ git_reference_target(head),
+ GIT_REFS_HEADS_DIR "master") == 0))
+ goto cleanup;
+
+ error = repo_contains_no_reference(repo);
+
+cleanup:
+ git_reference_free(head);
+ 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;
+
+ repo = cl_git_sandbox_init("empty_bare.git");
+ cl_git_remove_placeholders(git_repository_path(repo), "dummy-marker.txt");
+
+ cl_assert_equal_i(true, git_repository_is_empty(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);
+ cl_git_sandbox_cleanup();
+}
- 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);
+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)