Allow cloning to an existing empty directory
The die() message updated accordingly. The previous behaviour was to only allow cloning when the destination directory doesn't exist. [jc: added trivial tests] Signed-off-by: Alexander Potashev <aspotashev@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
8ca12c0d62
commit
55892d2398
@ -357,6 +357,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
struct stat buf;
|
||||
const char *repo_name, *repo, *work_tree, *git_dir;
|
||||
char *path, *dir;
|
||||
int dest_exists;
|
||||
const struct ref *refs, *head_points_at, *remote_head, *mapped_refs;
|
||||
struct strbuf key = STRBUF_INIT, value = STRBUF_INIT;
|
||||
struct strbuf branch_top = STRBUF_INIT, reflog_msg = STRBUF_INIT;
|
||||
@ -406,8 +407,10 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
dir = guess_dir_name(repo_name, is_bundle, option_bare);
|
||||
strip_trailing_slashes(dir);
|
||||
|
||||
if (!stat(dir, &buf))
|
||||
die("destination directory '%s' already exists.", dir);
|
||||
dest_exists = !stat(dir, &buf);
|
||||
if (dest_exists && !is_empty_dir(dir))
|
||||
die("destination path '%s' already exists and is not "
|
||||
"an empty directory.", dir);
|
||||
|
||||
strbuf_addf(&reflog_msg, "clone: from %s", repo);
|
||||
|
||||
@ -431,7 +434,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
|
||||
if (safe_create_leading_directories_const(work_tree) < 0)
|
||||
die("could not create leading directories of '%s': %s",
|
||||
work_tree, strerror(errno));
|
||||
if (mkdir(work_tree, 0755))
|
||||
if (!dest_exists && mkdir(work_tree, 0755))
|
||||
die("could not create work tree dir '%s': %s.",
|
||||
work_tree, strerror(errno));
|
||||
set_git_work_tree(work_tree);
|
||||
|
19
dir.c
19
dir.c
@ -777,6 +777,25 @@ int is_inside_dir(const char *dir)
|
||||
return get_relative_cwd(buffer, sizeof(buffer), dir) != NULL;
|
||||
}
|
||||
|
||||
int is_empty_dir(const char *path)
|
||||
{
|
||||
DIR *dir = opendir(path);
|
||||
struct dirent *e;
|
||||
int ret = 1;
|
||||
|
||||
if (!dir)
|
||||
return 0;
|
||||
|
||||
while ((e = readdir(dir)) != NULL)
|
||||
if (!is_dot_or_dotdot(e->d_name)) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int remove_dir_recursively(struct strbuf *path, int only_empty)
|
||||
{
|
||||
DIR *dir = opendir(path->buf);
|
||||
|
2
dir.h
2
dir.h
@ -84,6 +84,8 @@ static inline int is_dot_or_dotdot(const char *name)
|
||||
(name[1] == '.' && name[2] == '\0')));
|
||||
}
|
||||
|
||||
extern int is_empty_dir(const char *dir);
|
||||
|
||||
extern void setup_standard_excludes(struct dir_struct *dir);
|
||||
extern int remove_dir_recursively(struct strbuf *path, int only_empty);
|
||||
|
||||
|
@ -125,4 +125,23 @@ test_expect_success 'clone to destination with extra trailing /' '
|
||||
|
||||
'
|
||||
|
||||
test_expect_success 'clone to an existing empty directory' '
|
||||
mkdir target-3 &&
|
||||
git clone src target-3 &&
|
||||
T=$( cd target-3 && git rev-parse HEAD ) &&
|
||||
S=$( cd src && git rev-parse HEAD ) &&
|
||||
test "$T" = "$S"
|
||||
'
|
||||
|
||||
test_expect_success 'clone to an existing non-empty directory' '
|
||||
mkdir target-4 &&
|
||||
>target-4/Fakefile &&
|
||||
test_must_fail git clone src target-4
|
||||
'
|
||||
|
||||
test_expect_success 'clone to an existing path' '
|
||||
>target-5 &&
|
||||
test_must_fail git clone src target-5
|
||||
'
|
||||
|
||||
test_done
|
||||
|
Loading…
Reference in New Issue
Block a user