Commit b46c7ee5e270cc29e2fc0420a55e347a3242b3b5

Edward Thomson 2015-11-03T17:18:00

refs: complain when a directory exists at ref When a (non-empty) directory exists at the reference target location, complain with a more actionable error message.

diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index 6d8c762..c550ee9 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -733,8 +733,11 @@ static int loose_lock(git_filebuf *file, refdb_fs_backend *backend, const char *
 
 	error = git_filebuf_open(file, ref_path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE);
 
+	if (error == GIT_EDIRECTORY)
+		giterr_set(GITERR_REFERENCE, "cannot lock ref '%s', there are refs beneath that folder", name);
+
 	git_buf_free(&ref_path);
-        return error;
+	return error;
 }
 
 static int loose_commit(git_filebuf *file, const git_reference *ref)
diff --git a/tests/refs/create.c b/tests/refs/create.c
index 192551d..48194ae 100644
--- a/tests/refs/create.c
+++ b/tests/refs/create.c
@@ -151,6 +151,23 @@ void test_refs_create__propagate_eexists(void)
 	cl_assert(error == GIT_EEXISTS);
 }
 
+void test_refs_create__existing_dir_propagates_edirectory(void)
+{
+	git_reference *new_reference, *fail_reference;
+	git_oid id;
+	const char *dir_head = "refs/heads/new-dir/new-head",
+		*fail_head = "refs/heads/new-dir";
+
+	git_oid_fromstr(&id, current_master_tip);
+
+	/* Create and write the new object id reference */
+	cl_git_pass(git_reference_create(&new_reference, g_repo, dir_head, &id, 1, NULL));
+	cl_git_fail_with(GIT_EDIRECTORY,
+		git_reference_create(&fail_reference, g_repo, fail_head, &id, false, NULL));
+
+	git_reference_free(new_reference);
+}
+
 static void test_invalid_name(const char *name)
 {
 	git_reference *new_reference;