Commit d024419f by Ben Straub

Add git_path_is_empty_dir.

parent c3b5099f
...@@ -195,54 +195,14 @@ static int setup_remotes_and_fetch(git_repository *repo, ...@@ -195,54 +195,14 @@ static int setup_remotes_and_fetch(git_repository *repo,
/* TODO: p_opendir, p_closedir */ /* TODO: p_opendir, p_closedir */
static bool path_is_okay(const char *path) 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 */ /* The path must either not exist, or be an empty directory */
if (!git_path_exists(path)) return true; if (!git_path_exists(path)) return true;
if (!git_path_is_empty_dir(path)) {
if (!git_path_isdir(path)) {
giterr_set(GITERR_INVALID, giterr_set(GITERR_INVALID,
"'%s' exists and is not an empty directory", path); "'%s' exists and is not an empty directory", path);
return false; return false;
} }
return true;
#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;
} }
......
...@@ -389,6 +389,58 @@ bool git_path_isfile(const char *path) ...@@ -389,6 +389,58 @@ bool git_path_isfile(const char *path)
return S_ISREG(st.st_mode) != 0; 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 git_path_lstat(const char *path, struct stat *st)
{ {
int err = 0; int err = 0;
......
...@@ -80,7 +80,9 @@ extern int git_path_to_dir(git_buf *path); ...@@ -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); 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) GIT_INLINE(int) git_path_is_dot_or_dotdot(const char *name)
{ {
return (name[0] == '.' && return (name[0] == '.' &&
...@@ -138,6 +140,11 @@ extern bool git_path_isdir(const char *path); ...@@ -138,6 +140,11 @@ extern bool git_path_isdir(const char *path);
extern bool git_path_isfile(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. * Stat a file and/or link and set error if needed.
*/ */
extern int git_path_lstat(const char *path, struct stat *st); extern int git_path_lstat(const char *path, struct stat *st);
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "repository.h" #include "repository.h"
#define DO_LIVE_NETWORK_TESTS 0 #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; static git_repository *g_repo;
...@@ -77,7 +79,7 @@ void test_clone_clone__local(void) ...@@ -77,7 +79,7 @@ void test_clone_clone__local(void)
git_buf src = GIT_BUF_INIT; git_buf src = GIT_BUF_INIT;
build_local_file_url(&src, cl_fixture("testrepo.git")); 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)); cl_git_pass(git_clone(&g_repo, git_buf_cstr(&src), "./local", NULL));
git_repository_free(g_repo); git_repository_free(g_repo);
git_futils_rmdir_r("./local", GIT_DIRREMOVAL_FILES_AND_DIRS); git_futils_rmdir_r("./local", GIT_DIRREMOVAL_FILES_AND_DIRS);
...@@ -94,10 +96,10 @@ void test_clone_clone__network_full(void) ...@@ -94,10 +96,10 @@ void test_clone_clone__network_full(void)
#if DO_LIVE_NETWORK_TESTS #if DO_LIVE_NETWORK_TESTS
git_remote *origin; 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_assert(!git_repository_is_bare(g_repo));
cl_git_pass(git_remote_load(&origin, g_repo, "origin")); 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 #endif
} }
...@@ -106,10 +108,10 @@ void test_clone_clone__network_bare(void) ...@@ -106,10 +108,10 @@ void test_clone_clone__network_bare(void)
#if DO_LIVE_NETWORK_TESTS #if DO_LIVE_NETWORK_TESTS
git_remote *origin; 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_assert(git_repository_is_bare(g_repo));
cl_git_pass(git_remote_load(&origin, g_repo, "origin")); 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 #endif
} }
...@@ -119,25 +121,19 @@ void test_clone_clone__already_exists(void) ...@@ -119,25 +121,19 @@ void test_clone_clone__already_exists(void)
#if DO_LIVE_NETWORK_TESTS #if DO_LIVE_NETWORK_TESTS
/* Should pass with existing-but-empty dir */ /* Should pass with existing-but-empty dir */
p_mkdir("./foo", GIT_DIR_MODE); p_mkdir("./foo", GIT_DIR_MODE);
cl_git_pass(git_clone(&g_repo, cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
"http://github.com/libgit2/libgit2.git",
"./foo", NULL));
git_repository_free(g_repo); g_repo = NULL; git_repository_free(g_repo); g_repo = NULL;
git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS); git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
#endif #endif
/* Should fail with a file */ /* Should fail with a file */
cl_git_mkfile("./foo", "Bar!"); cl_git_mkfile("./foo", "Bar!");
cl_git_fail(git_clone(&g_repo, cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
"http://github.com/libgit2/libgit2.git",
"./foo", NULL));
git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS); git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
/* Should fail with existing-and-nonempty dir */ /* Should fail with existing-and-nonempty dir */
p_mkdir("./foo", GIT_DIR_MODE); p_mkdir("./foo", GIT_DIR_MODE);
cl_git_mkfile("./foo/bar", "Baz!"); cl_git_mkfile("./foo/bar", "Baz!");
cl_git_fail(git_clone(&g_repo, cl_git_fail(git_clone(&g_repo, LIVE_REPO_URL, "./foo", NULL));
"https://github.com/libgit2/libgit2.git",
"./foo", NULL));
git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS); git_futils_rmdir_r("./foo", GIT_DIRREMOVAL_FILES_AND_DIRS);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment