@matheusbsbs / matheus-bagliano / commits / dfaa209a79
Fork 0

git clone: don't clone into non-empty directory

When using git clone with --separate-git-dir realgitdir and realgitdir already exists, it's content is destroyed. So, make sure we don't clone into an existing non-empty directory. When d45420c1 (clone: do not clean up directories we didn't create, 2018-01-02) tightened the clean-up procedure after a failed cloning into an empty directory, it assumed that the existing directory given is an empty one so it is OK to keep that directory, while running the clean-up procedure that is designed to remove everything in it (since there won't be any, anyway). Check and make sure that the $GIT_DIR is empty even cloning into an existing repository. Signed-off-by: Ben Wijen <ben@wijen.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ben Wijen committed Jul 10, 2020 at 10:47 UTC dfaa209a79a831e8ff4f6b8e14a8b0c35b4f6b6e
2 files changed +13 -3
builtin/clone.c
+10 -2
@@ -946,7 +946,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
946 int is_bundle = 0, is_local;
947 const char *repo_name, *repo, *work_tree, *git_dir;
948 char *path, *dir, *display_repo = NULL;
949 - int dest_exists;
949 + int dest_exists, real_dest_exists = 0;
950 const struct ref *refs, *remote_head;
951 const struct ref *remote_head_points_at;
952 const struct ref *our_head_points_at;
@@ -1021,6 +1021,14 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1021 die(_("destination path '%s' already exists and is not "
1022 "an empty directory."), dir);
1023
1024 + if (real_git_dir) {
1025 + real_dest_exists = path_exists(real_git_dir);
1026 + if (real_dest_exists && !is_empty_dir(real_git_dir))
1027 + die(_("repository path '%s' already exists and is not "
1028 + "an empty directory."), real_git_dir);
1029 + }
1030 +
1031 +
1032 strbuf_addf(&reflog_msg, "clone: from %s",
1033 display_repo ? display_repo : repo);
1034 free(display_repo);
@@ -1057,7 +1065,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
1065 }
1066
1067 if (real_git_dir) {
1060 - if (path_exists(real_git_dir))
1068 + if (real_dest_exists)
1069 junk_git_dir_flags |= REMOVE_DIR_KEEP_TOPLEVEL;
1070 junk_git_dir = real_git_dir;
1071 } else {
t/t5601-clone.sh
+3 -1
@@ -271,7 +271,9 @@ test_expect_success 'fetch from gitfile parent' '
271
272 test_expect_success 'clone separate gitdir where target already exists' '
273 rm -rf dst &&
274 - test_must_fail git clone --separate-git-dir realgitdir src dst
274 + echo foo=bar >>realgitdir/config &&
275 + test_must_fail git clone --separate-git-dir realgitdir src dst &&
276 + grep foo=bar realgitdir/config
277 '
278
279 test_expect_success 'clone --reference from original' '