diff options
author | Junio C Hamano <gitster@pobox.com> | 2015-11-05 12:18:07 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2015-11-05 12:18:08 -0800 |
commit | 4349f597f08b6dc50fc6198b8e1b96e19df37c65 (patch) | |
tree | cda184215e2f3e14bb4d9871af0df367ea0ea01f | |
parent | 53be145209eeac5972d4ea4374d667fdf594f78f (diff) | |
parent | d78db8424ec5c3f3327441cd1a897064af39da91 (diff) | |
download | git-4349f597f08b6dc50fc6198b8e1b96e19df37c65.tar.gz |
Merge branch 'nd/clone-linked-checkout' into maint
It was not possible to use a repository-lookalike created by "git
worktree add" as a local source of "git clone".
* nd/clone-linked-checkout:
clone: better error when --reference is a linked checkout
clone: allow --local from a linked checkout
enter_repo: allow .git files in strict mode
enter_repo: avoid duplicating logic, use is_git_directory() instead
t0002: add test for enter_repo(), non-strict mode
path.c: delete an extra space
-rw-r--r-- | builtin/clone.c | 13 | ||||
-rw-r--r-- | path.c | 14 | ||||
-rwxr-xr-x | t/t0002-gitfile.sh | 42 | ||||
-rwxr-xr-x | t/t2025-worktree-add.sh | 5 |
4 files changed, 66 insertions, 8 deletions
diff --git a/builtin/clone.c b/builtin/clone.c index cc896e22d1..9eaecd9a7c 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -294,9 +294,14 @@ static int add_one_reference(struct string_list_item *item, void *cb_data) char *ref_git_git = mkpathdup("%s/.git", ref_git); free(ref_git); ref_git = ref_git_git; - } else if (!is_directory(mkpath("%s/objects", ref_git))) + } else if (!is_directory(mkpath("%s/objects", ref_git))) { + struct strbuf sb = STRBUF_INIT; + if (get_common_dir(&sb, ref_git)) + die(_("reference repository '%s' as a linked checkout is not supported yet."), + item->string); die(_("reference repository '%s' is not a local repository."), item->string); + } if (!access(mkpath("%s/shallow", ref_git), F_OK)) die(_("reference repository '%s' is shallow"), item->string); @@ -424,8 +429,10 @@ static void clone_local(const char *src_repo, const char *dest_repo) } else { struct strbuf src = STRBUF_INIT; struct strbuf dest = STRBUF_INIT; - strbuf_addf(&src, "%s/objects", src_repo); - strbuf_addf(&dest, "%s/objects", dest_repo); + get_common_dir(&src, src_repo); + get_common_dir(&dest, dest_repo); + strbuf_addstr(&src, "/objects"); + strbuf_addstr(&dest, "/objects"); copy_or_link_directory(&src, &dest, src_repo, src.len); strbuf_release(&src); strbuf_release(&dest); @@ -445,18 +445,22 @@ const char *enter_repo(const char *path, int strict) } if (!suffix[i]) return NULL; - gitfile = read_gitfile(used_path) ; + gitfile = read_gitfile(used_path); if (gitfile) strcpy(used_path, gitfile); if (chdir(used_path)) return NULL; path = validated_path; } - else if (chdir(path)) - return NULL; + else { + const char *gitfile = read_gitfile(path); + if (gitfile) + path = gitfile; + if (chdir(path)) + return NULL; + } - if (access("objects", X_OK) == 0 && access("refs", X_OK) == 0 && - validate_headref("HEAD") == 0) { + if (is_git_directory(".")) { set_git_dir("."); check_repository_format(); return path; diff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh index 9393322c3e..9670e8cbe6 100755 --- a/t/t0002-gitfile.sh +++ b/t/t0002-gitfile.sh @@ -116,4 +116,46 @@ test_expect_success 'setup_git_dir twice in subdir' ' ) ' +test_expect_success 'enter_repo non-strict mode' ' + test_create_repo enter_repo && + ( + cd enter_repo && + test_tick && + test_commit foo && + mv .git .realgit && + echo "gitdir: .realgit" >.git + ) && + git ls-remote enter_repo >actual && + cat >expected <<-\EOF && + 946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo + EOF + test_cmp expected actual +' + +test_expect_success 'enter_repo linked checkout' ' + ( + cd enter_repo && + git worktree add ../foo refs/tags/foo + ) && + git ls-remote foo >actual && + cat >expected <<-\EOF && + 946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo + EOF + test_cmp expected actual +' + +test_expect_success 'enter_repo strict mode' ' + git ls-remote --upload-pack="git upload-pack --strict" foo/.git >actual && + cat >expected <<-\EOF && + 946e985ab20de757ca5b872b16d64e92ff3803a9 HEAD + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/heads/master + 946e985ab20de757ca5b872b16d64e92ff3803a9 refs/tags/foo + EOF + test_cmp expected actual +' + test_done diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 8267411a0e..3694174989 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -193,4 +193,9 @@ test_expect_success '"add" -B/--detach mutually exclusive' ' test_must_fail git worktree add -B poodle --detach bamboo master ' +test_expect_success 'local clone from linked checkout' ' + git clone --local here here-clone && + ( cd here-clone && git fsck ) +' + test_done |