{"thread":{"id":"39855","subject":"workdirs: cannot clone a local workdir directory","startedAt":"2015-07-15T09:40:18Z","lastAt":"2015-09-28T13:06:16Z","messageCount":28,"participants":["Bjørnar Snoksrud","Duy Nguyen","Nguyễn Thái Ngọc Duy","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"266148","messageId":"CA+cck7GR1Gs+OvhweQZFs0=5uKu=RwEgY=0_0CZSCDqtDWrR2A@mail.gmail.com","threadId":"39855","inReplyTo":null,"subject":"workdirs: cannot clone a local workdir directory","fromName":"Bjørnar Snoksrud","fromEmail":"snoksrud@gmail.com","sentAt":"2015-07-15T09:40:18Z","receivedAt":"2015-07-15T09:40:18Z","isPatch":false,"sender":{"key":"snoksrud@gmail.com","avatar":"https://gravatar.com/avatar/bd7f988a0a0941712c4bb875eb852d6038a15a6e18cb4dc880ba8f6d8c4040fd?d=mp&s=160"},"body":"I reported this before, but now I have a nice topic to hang it on -\n\nI have re-reproduced the bug using a build from master as of today,\nusing the new worktree commands.\n\nReproduction:\nCreating a repo `foo`, checkout --to'ing it to ../bar, then try to\nclone both resulting repositories..\n\n$ git --version\ngit version 2.4.4.600.g6397abd\n$ mkdir foo\n$ cd foo\n$ git init\nInitialized empty Git repository in /bar/foo/.git/\n$ git commit -m init --allow-empty\n[master (root-commit) c6da399] init\n$ git branch bar\n$ git checkout bar --to ../bar\nEnter ../bar (identifier bar)\nSwitched to branch 'bar'\n$ cd ../bar\n$ cd bar\n$ git status -sb\n## bar\n$ cd ..\n$ git clone bar baz\nCloning into 'baz'...\nfatal: '/path/bar' does not appear to be a git repository\nfatal: Could not read from remote repository.\n\nPlease make sure you have the correct access rights\nand the repository exists.\n$ git clone foo baz\nCloning into 'baz'...\ndone.\n\n\n\n-- \nbjornar@snoksrud.no\n"},{"id":"266151","messageId":"20150715132552.GA28574@lanh","threadId":"39855","inReplyTo":"CA+cck7GR1Gs+OvhweQZFs0=5uKu=RwEgY=0_0CZSCDqtDWrR2A@mail.gmail.com","subject":"Re: workdirs: cannot clone a local workdir directory","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-07-15T13:25:52Z","receivedAt":"2015-07-15T13:25:52Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jul 15, 2015 at 11:40:18AM +0200, Bjørnar Snoksrud wrote:\n> I reported this before, but now I have a nice topic to hang it on -\n> \n> I have re-reproduced the bug using a build from master as of today,\n> using the new worktree commands.\n\nSomething like the following patch should work if you need it now.\n\nBecause this may conflict (in the test cases) with Eric's series to\nmove \"git checkout --to\" to \"git worktree add\", and because the next\nrelease is already delayed to let \"git worktree add\" in, I think we\ncould keep this patch out of tree for now. I will split it up, add\ntests and resubmit once the release is out. Please remind me if you\nsee nothing from me for too long.\n\nNote to self, \"git clone --reference\" remains broken.\n\n-- 8< --\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 00535d0..0e594f1 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -373,8 +373,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n \t} else {\n \t\tstruct strbuf src = STRBUF_INIT;\n \t\tstruct strbuf dest = STRBUF_INIT;\n-\t\tstrbuf_addf(&src, \"%s/objects\", src_repo);\n-\t\tstrbuf_addf(&dest, \"%s/objects\", dest_repo);\n+\t\tget_common_dir(&src, src_repo);\n+\t\tget_common_dir(&dest, dest_repo);\n+\t\tstrbuf_addstr(&src, \"/objects\");\n+\t\tstrbuf_addf(&dest, \"/objects\");\n \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n \t\tstrbuf_release(&src);\n \t\tstrbuf_release(&dest);\ndiff --git a/path.c b/path.c\nindex 10f4cbf..7f7b56f 100644\n--- a/path.c\n+++ b/path.c\n@@ -416,18 +416,22 @@ const char *enter_repo(const char *path, int strict)\n \t\t}\n \t\tif (!suffix[i])\n \t\t\treturn NULL;\n-\t\tgitfile = read_gitfile(used_path) ;\n+\t\tgitfile = read_gitfile(used_path);\n \t\tif (gitfile)\n \t\t\tstrcpy(used_path, gitfile);\n \t\tif (chdir(used_path))\n \t\t\treturn NULL;\n \t\tpath = validated_path;\n \t}\n-\telse if (chdir(path))\n-\t\treturn NULL;\n+\telse {\n+\t\tconst char *gitfile = read_gitfile(used_path);\n+\t\tif (gitfile)\n+\t\t\tpath = gitfile;\n+\t\tif (chdir(path))\n+\t\t\treturn NULL;\n+\t}\n \n-\tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n-\t    validate_headref(\"HEAD\") == 0) {\n+\tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n \t\tcheck_repository_format();\n \t\treturn path;\n-- 8< --\n"},{"id":"268468","messageId":"1440204002-7638-1-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"20150715132552.GA28574@lanh","subject":"[PATCH v2 0/5] fix local clone from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:39:57Z","receivedAt":"2015-08-22T00:39:57Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Wed, Jul 15, 2015 at 8:25 PM, Duy Nguyen <pclouds@gmail.com> wrote:\n> On Wed, Jul 15, 2015 at 11:40:18AM +0200, Bjørnar Snoksrud wrote:\n>> I reported this before, but now I have a nice topic to hang it on -\n>>\n>> I have re-reproduced the bug using a build from master as of today,\n>> using the new worktree commands.\n>\n> Something like the following patch should work if you need it now.\n>\n> Because this may conflict (in the test cases) with Eric's series to\n> move \"git checkout --to\" to \"git worktree add\", and because the next\n> release is already delayed to let \"git worktree add\" in, I think we\n> could keep this patch out of tree for now. I will split it up, add\n> tests and resubmit once the release is out. Please remind me if you\n> see nothing from me for too long.\n\nHere it is. Mostly the same as the previous patch except that the last\npatch is new.\n\nNguyễn Thái Ngọc Duy (5):\n  path.c: delete an extra space\n  enter_repo: avoid duplicating logic, use is_git_directory() instead\n  enter_repo: allow .git files in strict mode\n  clone: allow --local from a linked checkout\n  clone: better error when --reference is a linked checkout\n\n builtin/clone.c         | 13 ++++++++++---\n path.c                  | 14 +++++++++-----\n t/t2025-worktree-add.sh |  5 +++++\n 3 files changed, 24 insertions(+), 8 deletions(-)\n\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268471","messageId":"1440204002-7638-2-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 1/5] path.c: delete an extra space","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:39:58Z","receivedAt":"2015-08-22T00:39:58Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/path.c b/path.c\nindex 95acbaf..a536ee3 100644\n--- a/path.c\n+++ b/path.c\n@@ -431,7 +431,7 @@ const char *enter_repo(const char *path, int strict)\n \t\t}\n \t\tif (!suffix[i])\n \t\t\treturn NULL;\n-\t\tgitfile = read_gitfile(used_path) ;\n+\t\tgitfile = read_gitfile(used_path);\n \t\tif (gitfile)\n \t\t\tstrcpy(used_path, gitfile);\n \t\tif (chdir(used_path))\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268469","messageId":"1440204002-7638-3-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:39:59Z","receivedAt":"2015-08-22T00:39:59Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex a536ee3..7340e11 100644\n--- a/path.c\n+++ b/path.c\n@@ -441,8 +441,7 @@ const char *enter_repo(const char *path, int strict)\n \telse if (chdir(path))\n \t\treturn NULL;\n \n-\tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n-\t    validate_headref(\"HEAD\") == 0) {\n+\tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n \t\tcheck_repository_format();\n \t\treturn path;\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268470","messageId":"1440204002-7638-4-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 3/5] enter_repo: allow .git files in strict mode","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:40:00Z","receivedAt":"2015-08-22T00:40:00Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Strict mode is about not guessing where .git is. If the user points to a\n.git file, we know exactly where the target .git dir will be.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 7340e11..32d4ca6 100644\n--- a/path.c\n+++ b/path.c\n@@ -438,8 +438,13 @@ const char *enter_repo(const char *path, int strict)\n \t\t\treturn NULL;\n \t\tpath = validated_path;\n \t}\n-\telse if (chdir(path))\n-\t\treturn NULL;\n+\telse {\n+\t\tconst char *gitfile = read_gitfile(used_path);\n+\t\tif (gitfile)\n+\t\t\tpath = gitfile;\n+\t\tif (chdir(path))\n+\t\t\treturn NULL;\n+\t}\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268472","messageId":"1440204002-7638-5-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 4/5] clone: allow --local from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:40:01Z","receivedAt":"2015-08-22T00:40:01Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Noticed-by: Bjørnar Snoksrud <snoksrud@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c         | 6 ++++--\n t/t2025-worktree-add.sh | 5 +++++\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 578da85..836fb64 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -424,8 +424,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n \t} else {\n \t\tstruct strbuf src = STRBUF_INIT;\n \t\tstruct strbuf dest = STRBUF_INIT;\n-\t\tstrbuf_addf(&src, \"%s/objects\", src_repo);\n-\t\tstrbuf_addf(&dest, \"%s/objects\", dest_repo);\n+\t\tget_common_dir(&src, src_repo);\n+\t\tget_common_dir(&dest, dest_repo);\n+\t\tstrbuf_addstr(&src, \"/objects\");\n+\t\tstrbuf_addf(&dest, \"/objects\");\n \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n \t\tstrbuf_release(&src);\n \t\tstrbuf_release(&dest);\ndiff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\nindex 8267411..3694174 100755\n--- a/t/t2025-worktree-add.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -193,4 +193,9 @@ test_expect_success '\"add\" -B/--detach mutually exclusive' '\n \ttest_must_fail git worktree add -B poodle --detach bamboo master\n '\n \n+test_expect_success 'local clone from linked checkout' '\n+\tgit clone --local here here-clone &&\n+\t( cd here-clone && git fsck )\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"268473","messageId":"1440204002-7638-6-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v2 5/5] clone: better error when --reference is a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-08-22T00:40:02Z","receivedAt":"2015-08-22T00:40:02Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 836fb64..7a010bb 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -294,9 +294,14 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)\n \t\tchar *ref_git_git = mkpathdup(\"%s/.git\", ref_git);\n \t\tfree(ref_git);\n \t\tref_git = ref_git_git;\n-\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git)))\n+\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git))) {\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tif (get_common_dir(&sb, ref_git))\n+\t\t\tdie(_(\"reference repository '%s' as a linked checkout is not supported yet.\"),\n+\t\t\t    item->string);\n \t\tdie(_(\"reference repository '%s' is not a local repository.\"),\n \t\t    item->string);\n+\t}\n \n \tif (!access(mkpath(\"%s/shallow\", ref_git), F_OK))\n \t\tdie(_(\"reference repository '%s' is shallow\"), item->string);\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269573","messageId":"xmqqd1xu9oxe.fsf@gitster.mtv.corp.google.com","threadId":"39855","inReplyTo":"1440204002-7638-5-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 4/5] clone: allow --local from a linked checkout","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-09-07T16:25:49Z","receivedAt":"2015-09-07T16:25:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Noticed-by: Bjørnar Snoksrud <snoksrud@gmail.com>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  builtin/clone.c         | 6 ++++--\n>  t/t2025-worktree-add.sh | 5 +++++\n>  2 files changed, 9 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/clone.c b/builtin/clone.c\n> index 578da85..836fb64 100644\n> --- a/builtin/clone.c\n> +++ b/builtin/clone.c\n> @@ -424,8 +424,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n>  \t} else {\n>  \t\tstruct strbuf src = STRBUF_INIT;\n>  \t\tstruct strbuf dest = STRBUF_INIT;\n> -\t\tstrbuf_addf(&src, \"%s/objects\", src_repo);\n> -\t\tstrbuf_addf(&dest, \"%s/objects\", dest_repo);\n> +\t\tget_common_dir(&src, src_repo);\n> +\t\tget_common_dir(&dest, dest_repo);\n> +\t\tstrbuf_addstr(&src, \"/objects\");\n> +\t\tstrbuf_addf(&dest, \"/objects\");\n\nWhy addstr vs addf?  Shouldn't both be addstr?\n\n>  \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n>  \t\tstrbuf_release(&src);\n>  \t\tstrbuf_release(&dest);\n> diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\n> index 8267411..3694174 100755\n> --- a/t/t2025-worktree-add.sh\n> +++ b/t/t2025-worktree-add.sh\n> @@ -193,4 +193,9 @@ test_expect_success '\"add\" -B/--detach mutually exclusive' '\n>  \ttest_must_fail git worktree add -B poodle --detach bamboo master\n>  '\n>  \n> +test_expect_success 'local clone from linked checkout' '\n> +\tgit clone --local here here-clone &&\n> +\t( cd here-clone && git fsck )\n> +'\n> +\n>  test_done\n"},{"id":"269574","messageId":"xmqq8u8i9okf.fsf@gitster.mtv.corp.google.com","threadId":"39855","inReplyTo":"1440204002-7638-3-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-09-07T16:33:36Z","receivedAt":"2015-09-07T16:33:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n\nThe cover letter talks about \"local clone\", and in this entire\nseries, I saw new tests only for the local case, but doesn't this\nand the next change also affect the case where a Git daemon or a\nupload-pack process is serving the remote repository?\n\nAnd if so, how is that case affected?\n\n>  path.c | 3 +--\n>  1 file changed, 1 insertion(+), 2 deletions(-)\n>\n> diff --git a/path.c b/path.c\n> index a536ee3..7340e11 100644\n> --- a/path.c\n> +++ b/path.c\n> @@ -441,8 +441,7 @@ const char *enter_repo(const char *path, int strict)\n>  \telse if (chdir(path))\n>  \t\treturn NULL;\n>  \n> -\tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n> -\t    validate_headref(\"HEAD\") == 0) {\n> +\tif (is_git_directory(\".\")) {\n>  \t\tset_git_dir(\".\");\n>  \t\tcheck_repository_format();\n>  \t\treturn path;\n"},{"id":"269842","messageId":"CACsJy8CD+cNdM5EppcStJViRA7yPpyAHyUX=ct4LEK6RCrJrFw@mail.gmail.com","threadId":"39855","inReplyTo":"xmqq8u8i9okf.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T00:49:37Z","receivedAt":"2015-09-13T00:49:37Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Mon, Sep 7, 2015 at 11:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>\n>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>> ---\n>\n> The cover letter talks about \"local clone\", and in this entire\n> series, I saw new tests only for the local case, but doesn't this\n> and the next change also affect the case where a Git daemon or a\n> upload-pack process is serving the remote repository?\n>\n> And if so, how is that case affected?\n\nPeople who serve .git-dir repos should not be affected (I think we\nhave enough test cases covering that). People can serve .git-file\nrepos as well, which is sort of tested in the local clone test case\nbecause upload-pack is involved for providing remote refs, I think.\n--\nDuy\n"},{"id":"269844","messageId":"1442106148-22895-1-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1440204002-7638-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 0/5] fix local clone from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:23Z","receivedAt":"2015-09-13T01:02:23Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Fixes strbuf_addf in 4/5. Makes a note about the relation of\nenter_repo to this local clone in 3/5. Changes since v1\n\n-- 8< --\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 7a010bb..3e14491 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -432,7 +432,7 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n \t\tget_common_dir(&src, src_repo);\n \t\tget_common_dir(&dest, dest_repo);\n \t\tstrbuf_addstr(&src, \"/objects\");\n-\t\tstrbuf_addf(&dest, \"/objects\");\n+\t\tstrbuf_addstr(&dest, \"/objects\");\n \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n \t\tstrbuf_release(&src);\n \t\tstrbuf_release(&dest);\n-- 8< --\n\nNguyễn Thái Ngọc Duy (5):\n  path.c: delete an extra space\n  enter_repo: avoid duplicating logic, use is_git_directory() instead\n  enter_repo: allow .git files in strict mode\n  clone: allow --local from a linked checkout\n  clone: better error when --reference is a linked checkout\n\n builtin/clone.c         | 13 ++++++++++---\n path.c                  | 14 +++++++++-----\n t/t2025-worktree-add.sh |  5 +++++\n 3 files changed, 24 insertions(+), 8 deletions(-)\n\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269843","messageId":"1442106148-22895-2-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 1/5] path.c: delete an extra space","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:24Z","receivedAt":"2015-09-13T01:02:24Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/path.c b/path.c\nindex 95acbaf..a536ee3 100644\n--- a/path.c\n+++ b/path.c\n@@ -431,7 +431,7 @@ const char *enter_repo(const char *path, int strict)\n \t\t}\n \t\tif (!suffix[i])\n \t\t\treturn NULL;\n-\t\tgitfile = read_gitfile(used_path) ;\n+\t\tgitfile = read_gitfile(used_path);\n \t\tif (gitfile)\n \t\t\tstrcpy(used_path, gitfile);\n \t\tif (chdir(used_path))\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269845","messageId":"1442106148-22895-3-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:25Z","receivedAt":"2015-09-13T01:02:25Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex a536ee3..7340e11 100644\n--- a/path.c\n+++ b/path.c\n@@ -441,8 +441,7 @@ const char *enter_repo(const char *path, int strict)\n \telse if (chdir(path))\n \t\treturn NULL;\n \n-\tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n-\t    validate_headref(\"HEAD\") == 0) {\n+\tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n \t\tcheck_repository_format();\n \t\treturn path;\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269847","messageId":"1442106148-22895-4-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 3/5] enter_repo: allow .git files in strict mode","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:26Z","receivedAt":"2015-09-13T01:02:26Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Strict mode is about not guessing where .git is. If the user points to a\n.git file, we know exactly where the target .git dir will be.\n\nThis is needed even in local clone case because transport.c code uses\nupload-pack for fetching remote refs.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 7340e11..32d4ca6 100644\n--- a/path.c\n+++ b/path.c\n@@ -438,8 +438,13 @@ const char *enter_repo(const char *path, int strict)\n \t\t\treturn NULL;\n \t\tpath = validated_path;\n \t}\n-\telse if (chdir(path))\n-\t\treturn NULL;\n+\telse {\n+\t\tconst char *gitfile = read_gitfile(used_path);\n+\t\tif (gitfile)\n+\t\t\tpath = gitfile;\n+\t\tif (chdir(path))\n+\t\t\treturn NULL;\n+\t}\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269846","messageId":"1442106148-22895-5-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 4/5] clone: allow --local from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:27Z","receivedAt":"2015-09-13T01:02:27Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Noticed-by: Bjørnar Snoksrud <snoksrud@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c         | 6 ++++--\n t/t2025-worktree-add.sh | 5 +++++\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 578da85..39d4adf 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -424,8 +424,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n \t} else {\n \t\tstruct strbuf src = STRBUF_INIT;\n \t\tstruct strbuf dest = STRBUF_INIT;\n-\t\tstrbuf_addf(&src, \"%s/objects\", src_repo);\n-\t\tstrbuf_addf(&dest, \"%s/objects\", dest_repo);\n+\t\tget_common_dir(&src, src_repo);\n+\t\tget_common_dir(&dest, dest_repo);\n+\t\tstrbuf_addstr(&src, \"/objects\");\n+\t\tstrbuf_addstr(&dest, \"/objects\");\n \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n \t\tstrbuf_release(&src);\n \t\tstrbuf_release(&dest);\ndiff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\nindex 8267411..3694174 100755\n--- a/t/t2025-worktree-add.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -193,4 +193,9 @@ test_expect_success '\"add\" -B/--detach mutually exclusive' '\n \ttest_must_fail git worktree add -B poodle --detach bamboo master\n '\n \n+test_expect_success 'local clone from linked checkout' '\n+\tgit clone --local here here-clone &&\n+\t( cd here-clone && git fsck )\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269848","messageId":"1442106148-22895-6-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v3 5/5] clone: better error when --reference is a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-13T01:02:28Z","receivedAt":"2015-09-13T01:02:28Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 39d4adf..3e14491 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -294,9 +294,14 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)\n \t\tchar *ref_git_git = mkpathdup(\"%s/.git\", ref_git);\n \t\tfree(ref_git);\n \t\tref_git = ref_git_git;\n-\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git)))\n+\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git))) {\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tif (get_common_dir(&sb, ref_git))\n+\t\t\tdie(_(\"reference repository '%s' as a linked checkout is not supported yet.\"),\n+\t\t\t    item->string);\n \t\tdie(_(\"reference repository '%s' is not a local repository.\"),\n \t\t    item->string);\n+\t}\n \n \tif (!access(mkpath(\"%s/shallow\", ref_git), F_OK))\n \t\tdie(_(\"reference repository '%s' is shallow\"), item->string);\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"269849","messageId":"xmqqlhcbxh7l.fsf@gitster.mtv.corp.google.com","threadId":"39855","inReplyTo":"CACsJy8CD+cNdM5EppcStJViRA7yPpyAHyUX=ct4LEK6RCrJrFw@mail.gmail.com","subject":"Re: [PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-09-13T01:04:30Z","receivedAt":"2015-09-13T01:04:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n> On Mon, Sep 7, 2015 at 11:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>\n>>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>>> ---\n>>\n>> The cover letter talks about \"local clone\", and in this entire\n>> series, I saw new tests only for the local case, but doesn't this\n>> and the next change also affect the case where a Git daemon or a\n>> upload-pack process is serving the remote repository?\n>>\n>> And if so, how is that case affected?\n>\n> People who serve .git-dir repos should not be affected (I think we\n> have enough test cases covering that). People can serve .git-file\n> repos as well, which is sort of tested in the local clone test case\n> because upload-pack is involved for providing remote refs, I think.\n\nUnfortunately, the above is still not unclear to me.\n\nWas serving from a linked repository working without these five\npatches, i.e. was the local case the only one that was broken and\nneeded fixing with these five patches?  If so, the log message\nshould mention that (i.e. \"remote case was working OK but local was\nbroken because ...; change this and that to make local one work as\nwell\").  If the remote case also was broken and fixed by these five\npatches, then that is also worth mentioning the same way.\n\nI didn't ask you to explain it to me in the first place in a\nresponse.  The review comment pointed out that the proposed log\nmessage was unclear and those who will be reading \"git log\" output\nneed clearer description.\n\nThanks.\n"},{"id":"269911","messageId":"CACsJy8D+3o-SKq-MAC1+KzRzMjcU6GUij1OokLWznfZ8V7zUmA@mail.gmail.com","threadId":"39855","inReplyTo":"xmqqlhcbxh7l.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-14T11:57:54Z","receivedAt":"2015-09-14T11:57:54Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Sun, Sep 13, 2015 at 8:04 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Duy Nguyen <pclouds@gmail.com> writes:\n>\n>> On Mon, Sep 7, 2015 at 11:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n>>>\n>>>> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n>>>> ---\n>>>\n>>> The cover letter talks about \"local clone\", and in this entire\n>>> series, I saw new tests only for the local case, but doesn't this\n>>> and the next change also affect the case where a Git daemon or a\n>>> upload-pack process is serving the remote repository?\n>>>\n>>> And if so, how is that case affected?\n>>\n>> People who serve .git-dir repos should not be affected (I think we\n>> have enough test cases covering that). People can serve .git-file\n>> repos as well, which is sort of tested in the local clone test case\n>> because upload-pack is involved for providing remote refs, I think.\n>\n> Unfortunately, the above is still not unclear to me.\n>\n> Was serving from a linked repository working without these five\n> patches, i.e. was the local case the only one that was broken and\n> needed fixing with these five patches?  If so, the log message\n> should mention that (i.e. \"remote case was working OK but local was\n> broken because ...; change this and that to make local one work as\n> well\").  If the remote case also was broken and fixed by these five\n> patches, then that is also worth mentioning the same way.\n>\n> I didn't ask you to explain it to me in the first place in a\n> response.  The review comment pointed out that the proposed log\n> message was unclear and those who will be reading \"git log\" output\n> need clearer description.\n\nI know. I sent the re-roll before receiving this. I think I still\nhaven't mentioned the impact on remote case. Another update coming,\nmaybe next weekend.\n-- \nDuy\n"},{"id":"270451","messageId":"xmqqfv278kde.fsf@gitster.mtv.corp.google.com","threadId":"39855","inReplyTo":"CACsJy8D+3o-SKq-MAC1+KzRzMjcU6GUij1OokLWznfZ8V7zUmA@mail.gmail.com","subject":"Re: [PATCH v2 2/5] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-09-21T22:42:37Z","receivedAt":"2015-09-21T22:42:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Duy Nguyen <pclouds@gmail.com> writes:\n\n> I know. I sent the re-roll before receiving this. I think I still\n> haven't mentioned the impact on remote case. Another update coming,\n> maybe next weekend.\n\nThanks.\n"},{"id":"270769","messageId":"xmqqwpve2ru2.fsf@gitster.mtv.corp.google.com","threadId":"39855","inReplyTo":"1442106148-22895-4-git-send-email-pclouds@gmail.com","subject":"Re: [PATCH v3 3/5] enter_repo: allow .git files in strict mode","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-09-25T19:59:17Z","receivedAt":"2015-09-25T19:59:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Nguyễn Thái Ngọc Duy  <pclouds@gmail.com> writes:\n\n> Strict mode is about not guessing where .git is. If the user points to a\n> .git file, we know exactly where the target .git dir will be.\n>\n> This is needed even in local clone case because transport.c code uses\n> upload-pack for fetching remote refs.\n>\n> Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n> ---\n>  path.c | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n>\n> diff --git a/path.c b/path.c\n> index 7340e11..32d4ca6 100644\n> --- a/path.c\n> +++ b/path.c\n> @@ -438,8 +438,13 @@ const char *enter_repo(const char *path, int strict)\n>  \t\t\treturn NULL;\n>  \t\tpath = validated_path;\n>  \t}\n> -\telse if (chdir(path))\n> -\t\treturn NULL;\n> +\telse {\n> +\t\tconst char *gitfile = read_gitfile(used_path);\n\nAt this point, used_path[] has not been touched since this function\nwas called.  What file are we reading from?\n\nIs that just a typo of used_path?  Do we lack test that cover this\ncodepath?\n\nThanks.\n\n> +\t\tif (gitfile)\n> +\t\t\tpath = gitfile;\n> +\t\tif (chdir(path))\n> +\t\t\treturn NULL;\n> +\t}\n>  \n>  \tif (is_git_directory(\".\")) {\n>  \t\tset_git_dir(\".\");\n"},{"id":"270804","messageId":"1443445576-29526-1-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1442106148-22895-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 0/6] fix local clone from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:10Z","receivedAt":"2015-09-28T13:06:10Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"This fixes another embarassing bug in 4/6 and adds tests to make sure\nit works. Changes since v3\n\n-- 8< --\ndiff --git a/path.c b/path.c\nindex 32d4ca6..a346134 100644\n--- a/path.c\n+++ b/path.c\n@@ -439,7 +439,7 @@ const char *enter_repo(const char *path, int strict)\n \t\tpath = validated_path;\n \t}\n \telse {\n-\t\tconst char *gitfile = read_gitfile(used_path);\n+\t\tconst char *gitfile = read_gitfile(path);\n \t\tif (gitfile)\n \t\t\tpath = gitfile;\n \t\tif (chdir(path))\ndiff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh\nindex 9393322..9670e8c 100755\n--- a/t/t0002-gitfile.sh\n+++ b/t/t0002-gitfile.sh\n@@ -116,4 +116,46 @@ test_expect_success 'setup_git_dir twice in subdir' '\n \t)\n '\n \n+test_expect_success 'enter_repo non-strict mode' '\n+\ttest_create_repo enter_repo &&\n+\t(\n+\t\tcd enter_repo &&\n+\t\ttest_tick &&\n+\t\ttest_commit foo &&\n+\t\tmv .git .realgit &&\n+\t\techo \"gitdir: .realgit\" >.git\n+\t) &&\n+\tgit ls-remote enter_repo >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'enter_repo linked checkout' '\n+\t(\n+\t\tcd enter_repo &&\n+\t\tgit worktree add  ../foo refs/tags/foo\n+\t) &&\n+\tgit ls-remote foo >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n+test_expect_success 'enter_repo strict mode' '\n+\tgit ls-remote --upload-pack=\"git upload-pack --strict\" foo/.git >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- 8< --\n\nNguyễn Thái Ngọc Duy (6):\n  path.c: delete an extra space\n  t0002: add test for enter_repo(), non-strict mode\n  enter_repo: avoid duplicating logic, use is_git_directory() instead\n  enter_repo: allow .git files in strict mode\n  clone: allow --local from a linked checkout\n  clone: better error when --reference is a linked checkout\n\n builtin/clone.c         | 13 ++++++++++---\n path.c                  | 14 +++++++++-----\n t/t0002-gitfile.sh      | 42 ++++++++++++++++++++++++++++++++++++++++++\n t/t2025-worktree-add.sh |  5 +++++\n 4 files changed, 66 insertions(+), 8 deletions(-)\n\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270805","messageId":"1443445576-29526-2-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 1/6] path.c: delete an extra space","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:11Z","receivedAt":"2015-09-28T13:06:11Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/path.c b/path.c\nindex 95acbaf..a536ee3 100644\n--- a/path.c\n+++ b/path.c\n@@ -431,7 +431,7 @@ const char *enter_repo(const char *path, int strict)\n \t\t}\n \t\tif (!suffix[i])\n \t\t\treturn NULL;\n-\t\tgitfile = read_gitfile(used_path) ;\n+\t\tgitfile = read_gitfile(used_path);\n \t\tif (gitfile)\n \t\t\tstrcpy(used_path, gitfile);\n \t\tif (chdir(used_path))\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270806","messageId":"1443445576-29526-3-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 2/6] t0002: add test for enter_repo(), non-strict mode","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:12Z","receivedAt":"2015-09-28T13:06:12Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n t/t0002-gitfile.sh | 18 ++++++++++++++++++\n 1 file changed, 18 insertions(+)\n\ndiff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh\nindex 9393322..545bfe2 100755\n--- a/t/t0002-gitfile.sh\n+++ b/t/t0002-gitfile.sh\n@@ -116,4 +116,22 @@ test_expect_success 'setup_git_dir twice in subdir' '\n \t)\n '\n \n+test_expect_success 'enter_repo non-strict mode' '\n+\ttest_create_repo enter_repo &&\n+\t(\n+\t\tcd enter_repo &&\n+\t\ttest_tick &&\n+\t\ttest_commit foo &&\n+\t\tmv .git .realgit &&\n+\t\techo \"gitdir: .realgit\" >.git\n+\t) &&\n+\tgit ls-remote enter_repo >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270807","messageId":"1443445576-29526-4-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 3/6] enter_repo: avoid duplicating logic, use is_git_directory() instead","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:13Z","receivedAt":"2015-09-28T13:06:13Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"It matters for linked checkouts where 'refs' directory won't be\navailable in $GIT_DIR. is_git_directory() knows about $GIT_COMMON_DIR\nand can handle this case.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c             |  3 +--\n t/t0002-gitfile.sh | 14 ++++++++++++++\n 2 files changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex a536ee3..7340e11 100644\n--- a/path.c\n+++ b/path.c\n@@ -441,8 +441,7 @@ const char *enter_repo(const char *path, int strict)\n \telse if (chdir(path))\n \t\treturn NULL;\n \n-\tif (access(\"objects\", X_OK) == 0 && access(\"refs\", X_OK) == 0 &&\n-\t    validate_headref(\"HEAD\") == 0) {\n+\tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\n \t\tcheck_repository_format();\n \t\treturn path;\ndiff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh\nindex 545bfe2..2e709cc 100755\n--- a/t/t0002-gitfile.sh\n+++ b/t/t0002-gitfile.sh\n@@ -134,4 +134,18 @@ test_expect_success 'enter_repo non-strict mode' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'enter_repo linked checkout' '\n+\t(\n+\t\tcd enter_repo &&\n+\t\tgit worktree add  ../foo refs/tags/foo\n+\t) &&\n+\tgit ls-remote foo >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270809","messageId":"1443445576-29526-5-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 4/6] enter_repo: allow .git files in strict mode","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:14Z","receivedAt":"2015-09-28T13:06:14Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Strict mode is about not guessing where .git is. If the user points to a\n.git file, we know exactly where the target .git dir will be. This makes\nit possible to serve .git files as repository on the server side.\n\nThis may be needed even in local clone case because transport.c code\nuses upload-pack for fetching remote refs. But right now the\nclone/transport code goes with non-strict.\n\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n path.c             |  9 +++++++--\n t/t0002-gitfile.sh | 10 ++++++++++\n 2 files changed, 17 insertions(+), 2 deletions(-)\n\ndiff --git a/path.c b/path.c\nindex 7340e11..a346134 100644\n--- a/path.c\n+++ b/path.c\n@@ -438,8 +438,13 @@ const char *enter_repo(const char *path, int strict)\n \t\t\treturn NULL;\n \t\tpath = validated_path;\n \t}\n-\telse if (chdir(path))\n-\t\treturn NULL;\n+\telse {\n+\t\tconst char *gitfile = read_gitfile(path);\n+\t\tif (gitfile)\n+\t\t\tpath = gitfile;\n+\t\tif (chdir(path))\n+\t\t\treturn NULL;\n+\t}\n \n \tif (is_git_directory(\".\")) {\n \t\tset_git_dir(\".\");\ndiff --git a/t/t0002-gitfile.sh b/t/t0002-gitfile.sh\nindex 2e709cc..9670e8c 100755\n--- a/t/t0002-gitfile.sh\n+++ b/t/t0002-gitfile.sh\n@@ -148,4 +148,14 @@ test_expect_success 'enter_repo linked checkout' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'enter_repo strict mode' '\n+\tgit ls-remote --upload-pack=\"git upload-pack --strict\" foo/.git >actual &&\n+\tcat >expected <<-\\EOF &&\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\tHEAD\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/heads/master\n+\t946e985ab20de757ca5b872b16d64e92ff3803a9\trefs/tags/foo\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270808","messageId":"1443445576-29526-6-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 5/6] clone: allow --local from a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:15Z","receivedAt":"2015-09-28T13:06:15Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Noticed-by: Bjørnar Snoksrud <snoksrud@gmail.com>\nSigned-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c         | 6 ++++--\n t/t2025-worktree-add.sh | 5 +++++\n 2 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 578da85..39d4adf 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -424,8 +424,10 @@ static void clone_local(const char *src_repo, const char *dest_repo)\n \t} else {\n \t\tstruct strbuf src = STRBUF_INIT;\n \t\tstruct strbuf dest = STRBUF_INIT;\n-\t\tstrbuf_addf(&src, \"%s/objects\", src_repo);\n-\t\tstrbuf_addf(&dest, \"%s/objects\", dest_repo);\n+\t\tget_common_dir(&src, src_repo);\n+\t\tget_common_dir(&dest, dest_repo);\n+\t\tstrbuf_addstr(&src, \"/objects\");\n+\t\tstrbuf_addstr(&dest, \"/objects\");\n \t\tcopy_or_link_directory(&src, &dest, src_repo, src.len);\n \t\tstrbuf_release(&src);\n \t\tstrbuf_release(&dest);\ndiff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh\nindex 8267411..3694174 100755\n--- a/t/t2025-worktree-add.sh\n+++ b/t/t2025-worktree-add.sh\n@@ -193,4 +193,9 @@ test_expect_success '\"add\" -B/--detach mutually exclusive' '\n \ttest_must_fail git worktree add -B poodle --detach bamboo master\n '\n \n+test_expect_success 'local clone from linked checkout' '\n+\tgit clone --local here here-clone &&\n+\t( cd here-clone && git fsck )\n+'\n+\n test_done\n-- \n2.3.0.rc1.137.g477eb31\n"},{"id":"270810","messageId":"1443445576-29526-7-git-send-email-pclouds@gmail.com","threadId":"39855","inReplyTo":"1443445576-29526-1-git-send-email-pclouds@gmail.com","subject":"[PATCH v4 6/6] clone: better error when --reference is a linked checkout","fromName":"Nguyễn Thái Ngọc Duy","fromEmail":"pclouds@gmail.com","sentAt":"2015-09-28T13:06:16Z","receivedAt":"2015-09-28T13:06:16Z","isPatch":true,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>\n---\n builtin/clone.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/clone.c b/builtin/clone.c\nindex 39d4adf..3e14491 100644\n--- a/builtin/clone.c\n+++ b/builtin/clone.c\n@@ -294,9 +294,14 @@ static int add_one_reference(struct string_list_item *item, void *cb_data)\n \t\tchar *ref_git_git = mkpathdup(\"%s/.git\", ref_git);\n \t\tfree(ref_git);\n \t\tref_git = ref_git_git;\n-\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git)))\n+\t} else if (!is_directory(mkpath(\"%s/objects\", ref_git))) {\n+\t\tstruct strbuf sb = STRBUF_INIT;\n+\t\tif (get_common_dir(&sb, ref_git))\n+\t\t\tdie(_(\"reference repository '%s' as a linked checkout is not supported yet.\"),\n+\t\t\t    item->string);\n \t\tdie(_(\"reference repository '%s' is not a local repository.\"),\n \t\t    item->string);\n+\t}\n \n \tif (!access(mkpath(\"%s/shallow\", ref_git), F_OK))\n \t\tdie(_(\"reference repository '%s' is shallow\"), item->string);\n-- \n2.3.0.rc1.137.g477eb31\n"}]}