Commit d024419f165e81f59d919bd56d84abf8e9fb9f57

Ben Straub 2012-07-11T10:40:53

Add git_path_is_empty_dir.

diff --git a/src/clone.c b/src/clone.c
index 3f161c8..803338e 100644
--- a/src/clone.c
+++ b/src/clone.c
@@ -195,54 +195,14 @@ static int setup_remotes_and_fetch(git_repository *repo,
 /* TODO: p_opendir, p_closedir */
 static bool path_is_okay(const char *path)
 {
-#ifdef GIT_WIN32
-	HANDLE hFind = INVALID_HANDLE_VALUE;
-	wchar_t *wbuf;
-	WIN32_FIND_DATAW ffd;
-#else
-	DIR *dir = NULL;
-	struct dirent *e;
-#endif
-
-	bool retval = true;
-
 	/* The path must either not exist, or be an empty directory */
 	if (!git_path_exists(path)) return true;
-
-	if (!git_path_isdir(path)) {
+	if (!git_path_is_empty_dir(path)) {
 		giterr_set(GITERR_INVALID,
 					  "'%s' exists and is not an empty directory", path);
 		return false;
 	}
-
-#ifdef GIT_WIN32
-	wbuf = gitwin_to_utf16(path);
-	gitwin_append_utf16(wbuf, "\\*", 2);
-	hFind = FindFirstFileW(wbuf, &ffd);
-	if (INVALID_HANDLE_VALUE != hFind) {
-		retval = false;
-		FindClose(hFind);
-	}
-	git__free(wbuf);
-#else
-	dir = opendir(path);
-	if (!dir) {
-		giterr_set(GITERR_OS, "Couldn't open '%s'", path);
-		return false;
-	}
-
-	while ((e = readdir(dir)) != NULL) {
-		if (!git_path_is_dot_or_dotdot(e->d_name)) {
-			giterr_set(GITERR_INVALID,
-						  "'%s' exists and is not an empty directory", path);
-			retval = false;
-			break;
-		}
-	}
-	closedir(dir);
-#endif
-
-	return retval;
+	return true;
 }
 
 
diff --git a/src/path.c b/src/path.c
index 3de4b11..e667ec3 100644
--- a/src/path.c
+++ b/src/path.c
@@ -389,6 +389,58 @@ bool git_path_isfile(const char *path)
 	return S_ISREG(st.st_mode) != 0;
 }
 
+#ifdef GIT_WIN32
+
+bool git_path_is_empty_dir(const char *path)
+{
+	HANDLE hFind = INVALID_HANDLE_VALUE;
+	wchar_t *wbuf;
+	WIN32_FIND_DATAW ffd;
+	bool retval = true;
+
+	if (!git_path_isdir(path)) return false;
+
+	wbuf = gitwin_to_utf16(path);
+	gitwin_append_utf16(wbuf, "\\*", 2);
+	hFind = FindFirstFileW(wbuf, &ffd);
+	if (INVALID_HANDLE_VALUE != hFind) {
+		retval = false;
+		FindClose(hFind);
+	}
+	git__free(wbuf);
+	return retval;
+}
+
+#else
+
+bool git_path_is_empty_dir(const char *path)
+{
+	DIR *dir = NULL;
+	struct dirent *e;
+	bool retval = true;
+
+	if (!git_path_isdir(path)) return false;
+
+	dir = opendir(path);
+	if (!dir) {
+		giterr_set(GITERR_OS, "Couldn't open '%s'", path);
+		return false;
+	}
+
+	while ((e = readdir(dir)) != NULL) {
+		if (!git_path_is_dot_or_dotdot(e->d_name)) {
+			giterr_set(GITERR_INVALID,
+						  "'%s' exists and is not an empty directory", path);
+			retval = false;
+			break;
+		}
+	}
+	closedir(dir);
+
+	return retval;
+}
+#endif
+
 int git_path_lstat(const char *path, struct stat *st)
 {
 	int err = 0;
diff --git a/src/path.h b/src/path.h
index 76e01fc..1164770 100644
--- a/src/path.h
+++ b/src/path.h
@@ -80,7 +80,9 @@ extern int git_path_to_dir(git_buf *path);
  */
 extern void git_path_string_to_dir(char* path, size_t size);
 
-/* Taken from git.git */
+/**
+ * Taken from git.git; returns nonzero if the given path is "." or "..".
+ */
 GIT_INLINE(int) git_path_is_dot_or_dotdot(const char *name)
 {
 	return (name[0] == '.' &&
@@ -138,6 +140,11 @@ extern bool git_path_isdir(const char *path);
 extern bool git_path_isfile(const char *path);
 
 /**
+ * Check if the given path is a directory, and is empty.
+ */
+extern bool git_path_is_empty_dir(const char *path);
+
+/**
  * Stat a file and/or link and set error if needed.
  */
 extern int git_path_lstat(const char *path, struct stat *st);
diff --git a/tests-clar/clone/clone.c b/tests-clar/clone/clone.c
index b0c8479..49deeaa 100644
--- a/tests-clar/clone/clone.c
+++ b/tests-clar/clone/clone.c
@@ -4,6 +4,8 @@
 #include "repository.h"
 
 #define DO_LIVE_NETWORK_TESTS 0
+#define DO_LOCAL_TEST 0
+#define LIVE_REPO_URL "http://github.com/libgit2/node-gitteh"
 
 
 static git_repository *g_repo;
@@ -77,7 +79,7 @@ void test_clone_clone__local(void)
 	git_buf src = GIT_BUF_INIT;
 	build_local_file_url(&src, cl_fixture("testrepo.git"));
 
-#if DO_LIVE_NETWORK_TESTS
+#if DO_LOCAL_TEST
 	cl_git_pass(git_clone(&g_repo, git_buf_cstr(&src), "./local", NULL));
 	git_repository_free(g_repo);
 	git_futils_rmdir_r("./local", GIT_DIRREMOVAL_FILES_AND_DIRS);
@@ -94,10 +96,10 @@ void test_clone_clone__network_full(void)
 #if DO_LIVE_NETWORK_TESTS
 	git_remote *origin;
 
-	cl_git_pass(git_clone(&g_repo, "http://github.com/libgit2/node-gitteh", "./attr", NULL));
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./test", NULL));
 	cl_assert(!git_repository_is_bare(g_repo));
 	cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
-	git_futils_rmdir_r("./attr", GIT_DIRREMOVAL_FILES_AND_DIRS);
+	git_futils_rmdir_r("./test", GIT_DIRREMOVAL_FILES_AND_DIRS);
 #endif
 }
 
@@ -106,10 +108,10 @@ void test_clone_clone__network_bare(void)
 #if DO_LIVE_NETWORK_TESTS
 	git_remote *origin;
 
-	cl_git_pass(git_clone_bare(&g_repo, "http://github.com/libgit2/node-gitteh", "attr", NULL));
+	cl_git_pass(git_clone_bare(&g_repo, LIVE_REPO_URL, "test", NULL));
 	cl_assert(git_repository_is_bare(g_repo));
 	cl_git_pass(git_remote_load(&origin, g_repo, "origin"));
-	git_futils_rmdir_r("./attr", GIT_DIRREMOVAL_FILES_AND_DIRS);
+	git_futils_rmdir_r("./test", GIT_DIRREMOVAL_FILES_AND_DIRS);
 #endif
 }
 
@@ -119,25 +121,19 @@ void test_clone_clone__already_exists(void)
 #if DO_LIVE_NETWORK_TESTS
 	/* Should pass with existing-but-empty dir */
 	p_mkdir("./foo", GIT_DIR_MODE);
-	cl_git_pass(git_clone(&g_repo,
-								 "http://github.com/libgit2/libgit2.git",
-								 "./foo", NULL));
+	cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
 	git_repository_free(g_repo); g_repo = NULL;
 	git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
 #endif
 
 	/* Should fail with a file */
 	cl_git_mkfile("./foo", "Bar!");
-	cl_git_fail(git_clone(&g_repo,
-								 "http://github.com/libgit2/libgit2.git",
-								 "./foo", NULL));
+	cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
 	git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
 
 	/* Should fail with existing-and-nonempty dir */
 	p_mkdir("./foo", GIT_DIR_MODE);
 	cl_git_mkfile("./foo/bar", "Baz!");
-	cl_git_fail(git_clone(&g_repo,
-								 "https://github.com/libgit2/libgit2.git",
-								 "./foo", NULL));
+	cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
 	git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
 }