mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-09 13:04:42 +00:00
Add git_path_is_empty_dir.
This commit is contained in:
parent
c3b5099fe4
commit
d024419f16
44
src/clone.c
44
src/clone.c
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
52
src/path.c
52
src/path.c
@ -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);
|
|||||||
*/
|
*/
|
||||||
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] == '.' &&
|
||||||
@ -137,6 +139,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.
|
||||||
*/
|
*/
|
||||||
|
@ -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)
|
|||||||
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)
|
|||||||
#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)
|
|||||||
#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)
|
|||||||
#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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user