aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2011-08-21 18:58:09 +0700
committerJunio C Hamano <gitster@pobox.com>2011-08-22 14:20:11 -0700
commit9b0ebc722cfc12bd14934aab5cf77ebe654e36e6 (patch)
tree66a7dad2ef09f95cb548db34157e039bb0753caf
parent13d6ec913330ba90fb1a67ec5789e437f8ac4193 (diff)
downloadgit-9b0ebc722cfc12bd14934aab5cf77ebe654e36e6.tar.gz
git-9b0ebc722cfc12bd14934aab5cf77ebe654e36e6.tar.xz
clone: allow to clone from .git file
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/clone.c19
-rwxr-xr-xt/t5601-clone.sh4
2 files changed, 22 insertions, 1 deletions
diff --git a/builtin/clone.c b/builtin/clone.c
index f579794d9..ec57f3dbe 100644
--- a/builtin/clone.c
+++ b/builtin/clone.c
@@ -101,9 +101,26 @@ static char *get_repo_path(const char *repo, int *is_bundle)
for (i = 0; i < ARRAY_SIZE(suffix); i++) {
const char *path;
path = mkpath("%s%s", repo, suffix[i]);
- if (is_directory(path)) {
+ if (stat(path, &st))
+ continue;
+ if (S_ISDIR(st.st_mode)) {
*is_bundle = 0;
return xstrdup(absolute_path(path));
+ } else if (S_ISREG(st.st_mode) && st.st_size > 8) {
+ /* Is it a "gitfile"? */
+ char signature[8];
+ int len, fd = open(path, O_RDONLY);
+ if (fd < 0)
+ continue;
+ len = read_in_full(fd, signature, 8);
+ close(fd);
+ if (len != 8 || strncmp(signature, "gitdir: ", 8))
+ continue;
+ path = read_gitfile(path);
+ if (path) {
+ *is_bundle = 0;
+ return xstrdup(absolute_path(path));
+ }
}
}
diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh
index 151ea531b..501bd3fb6 100755
--- a/t/t5601-clone.sh
+++ b/t/t5601-clone.sh
@@ -202,6 +202,10 @@ test_expect_success 'clone separate gitdir: output' '
test_cmp expected dst/.git
'
+test_expect_success 'clone from .git file' '
+ git clone dst/.git dst2
+'
+
test_expect_success 'clone separate gitdir where target already exists' '
rm -rf dst &&
test_must_fail git clone --separate-git-dir realgitdir src dst