{"thread":{"id":"39488","subject":"[PATCH] receive-pack: Create a HEAD ref for ref namespace","startedAt":"2015-06-01T21:24:43Z","lastAt":"2015-06-15T20:59:56Z","messageCount":22,"participants":["Johannes Löthberg","Michael J Gruber","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"262653","messageId":"1433193883-11577-1-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":null,"subject":"[PATCH] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-01T21:24:43Z","receivedAt":"2015-06-01T21:24:43Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Each ref namespace have their own separate branches, tags, and HEAD, so\nwhen pushing to a namespace we need to make sure that there exists a\nHEAD ref for the namespace, otherwise you will not be able to check out\nthe repo after cloning from a namespace\n---\n\nSo, I have absolutely no clue where this should actually be put, so I \njust put it where it fit for now.\n\nAny comments on where to put it, or comments on the patch in general?\n\n builtin/receive-pack.c | 12 +++++++++++-\n 1 file changed, 11 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 5292bb5..c189838 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -864,7 +864,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstruct strbuf namespaced_head_buf = STRBUF_INIT;\n+\tconst char *namespaced_name, *ret, *namespace;\n+\tconst char *namespaced_head_path;\n \tunsigned char *old_sha1 = cmd->old_sha1;\n \tunsigned char *new_sha1 = cmd->new_sha1;\n \n@@ -981,6 +983,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t\treturn NULL; /* good */\n \t}\n \telse {\n+\t\tnamespace = get_git_namespace();\n+\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n+\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n+\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n+\n+\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n+\t\t}\n+\n \t\tstruct strbuf err = STRBUF_INIT;\n \t\tif (shallow_update && si->shallow_ref[cmd->index] &&\n \t\t    update_shallow_ref(cmd, si))\n-- \n2.4.2\n"},{"id":"263006","messageId":"ef4dae3e-3ae8-4727-9448-80f801e1dbdf@email.android.com","threadId":"39488","inReplyTo":"1433193883-11577-1-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T11:53:45Z","receivedAt":"2015-06-05T11:53:45Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Ping.\n\n--\nSincerely, \nJohannes Löthberg \n(Sent from my phone.)"},{"id":"263011","messageId":"55719C47.6030600@drmicha.warpmail.net","threadId":"39488","inReplyTo":"ef4dae3e-3ae8-4727-9448-80f801e1dbdf@email.android.com","subject":"Re: [PATCH] receive-pack: Create a HEAD ref for ref namespace","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2015-06-05T12:55:35Z","receivedAt":"2015-06-05T12:55:35Z","isPatch":true,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Johannes Löthberg venit, vidit, dixit 05.06.2015 13:53:\n> Ping.\n> \n> --\n> Sincerely, \n> Johannes Löthberg \n> (Sent from my phone.)\n> \n\nIt appears your patch proposes to fix a problem. It's a good idea to\nexpose the problem by writing a test so that one can check that the fix\nactually fixes the problem.\n\n(Also, your patch duplicates the line \"struct strbuf namespaced_head_buf\n= STRBUF_INIT;\")\n\nMichael\n"},{"id":"263013","messageId":"20150605135059.GA1165@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"55719C47.6030600@drmicha.warpmail.net","subject":"Re: [PATCH] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T13:50:59Z","receivedAt":"2015-06-05T13:50:59Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Michael J Gruber wrote:\n>It appears your patch proposes to fix a problem. It's a good idea to\n>expose the problem by writing a test so that one can check that the fix\n>actually fixes the problem.\n>\n\nRight, will look into writing a test for it.\n\n>(Also, your patch duplicates the line \"struct strbuf \n>namespaced_head_buf\n>= STRBUF_INIT;\")\n>\n\nHmm, that's weird, no clue how that happened. Thanks.\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263014","messageId":"20150605141040.GB1165@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"55719C47.6030600@drmicha.warpmail.net","subject":"Re: [PATCH] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T14:10:40Z","receivedAt":"2015-06-05T14:10:40Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Michael J Gruber wrote:\n>(Also, your patch duplicates the line \"struct strbuf namespaced_head_buf\n>= STRBUF_INIT;\")\n>\n\nI replied too soon, it doesn't duplicate it, it's a different variable \nnamed similarly.\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263015","messageId":"1433513531-13423-1-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":"1433193883-11577-1-git-send-email-johannes@kyriasis.com","subject":"[PATCH v2] Fix cloning from ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T14:12:09Z","receivedAt":"2015-06-05T14:12:09Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Since v1:\n  * Added a test case\n\nJohannes Löthberg (2):\n  receive-pack: Create a HEAD ref for ref namespace\n  t: Add test for cloning from ref namespace\n\n builtin/receive-pack.c              | 12 +++++++++++-\n t/t9904-clone-from-ref-namespace.sh | 33 +++++++++++++++++++++++++++++++++\n 2 files changed, 44 insertions(+), 1 deletion(-)\n create mode 100755 t/t9904-clone-from-ref-namespace.sh\n\n-- \n2.4.2\n"},{"id":"263016","messageId":"1433513531-13423-2-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":"1433513531-13423-1-git-send-email-johannes@kyriasis.com","subject":"[PATCH v2 1/2] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T14:12:10Z","receivedAt":"2015-06-05T14:12:10Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Each ref namespace have their own separate branches, tags, and HEAD, so\nwhen pushing to a namespace we need to make sure that there exists a\nHEAD ref for the namespace, otherwise you will not be able to check out\nthe repo after cloning from a namespace\n\nSigned-off-by: Johannes Löthberg <johannes@kyriasis.com>\n---\n builtin/receive-pack.c | 12 +++++++++++-\n 1 file changed, 11 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex 5292bb5..c189838 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -864,7 +864,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstruct strbuf namespaced_head_buf = STRBUF_INIT;\n+\tconst char *namespaced_name, *ret, *namespace;\n+\tconst char *namespaced_head_path;\n \tunsigned char *old_sha1 = cmd->old_sha1;\n \tunsigned char *new_sha1 = cmd->new_sha1;\n \n@@ -981,6 +983,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t\treturn NULL; /* good */\n \t}\n \telse {\n+\t\tnamespace = get_git_namespace();\n+\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n+\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n+\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n+\n+\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n+\t\t}\n+\n \t\tstruct strbuf err = STRBUF_INIT;\n \t\tif (shallow_update && si->shallow_ref[cmd->index] &&\n \t\t    update_shallow_ref(cmd, si))\n-- \n2.4.2\n"},{"id":"263017","messageId":"1433513531-13423-3-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":"1433513531-13423-1-git-send-email-johannes@kyriasis.com","subject":"[PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T14:12:11Z","receivedAt":"2015-06-05T14:12:11Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Test that the master ref is set up properly when cloning from a ref\nnamespace\n\nSigned-off-by: Johannes Löthberg <johannes@kyriasis.com>\n---\n t/t9904-clone-from-ref-namespace.sh | 33 +++++++++++++++++++++++++++++++++\n 1 file changed, 33 insertions(+)\n create mode 100755 t/t9904-clone-from-ref-namespace.sh\n\ndiff --git a/t/t9904-clone-from-ref-namespace.sh b/t/t9904-clone-from-ref-namespace.sh\nnew file mode 100755\nindex 0000000..60977f8\n--- /dev/null\n+++ b/t/t9904-clone-from-ref-namespace.sh\n@@ -0,0 +1,33 @@\n+#!/bin/sh\n+#\n+\n+test_description='git clone from ref namespace\n+\n+This test checks that cloning from a ref namespace works'\n+\n+. ./test-lib.sh\n+\n+test_expect_success 'clone from ref namespace' '\n+\trm -rf initial bare clone &&\n+\tgit init initial &&\n+\tgit init --bare bare &&\n+\t(\n+\t\tcd initial &&\n+\t\techo \"commit one\" >> file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit one\" &&\n+\t\tgit push ../bare master &&\n+\n+\t\techo \"commit two\" >> file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit two\"\n+\t\tGIT_NAMESPACE=new_namespace git push ../bare master\n+\t) &&\n+\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n+\t(\n+\t\tcd clone &&\n+\t\tgit show\n+\t)\n+'\n+\n+test_done\n-- \n2.4.2\n"},{"id":"263021","messageId":"xmqqk2vitbjh.fsf@gitster.dls.corp.google.com","threadId":"39488","inReplyTo":"1433513531-13423-3-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-05T15:33:38Z","receivedAt":"2015-06-05T15:33:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Löthberg <johannes@kyriasis.com> writes:\n\n> Test that the master ref is set up properly when cloning from a ref\n> namespace\n>\n> Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>\n> ---\n>  t/t9904-clone-from-ref-namespace.sh | 33 +++++++++++++++++++++++++++++++++\n\nIt seems that 5509 already has a few tests for namespaced transfer\nin both directions.  Perhaps this new test would fit there better?\n\nAlso I think it probably is better to have these as a single patch.\n\n> diff --git a/t/t9904-clone-from-ref-namespace.sh b/t/t9904-clone-from-ref-namespace.sh\n> new file mode 100755\n> index 0000000..60977f8\n> --- /dev/null\n> +++ b/t/t9904-clone-from-ref-namespace.sh\n> @@ -0,0 +1,33 @@\n> +#!/bin/sh\n> +#\n> +\n> +test_description='git clone from ref namespace\n> +\n> +This test checks that cloning from a ref namespace works'\n> +\n> +. ./test-lib.sh\n> +\n> +test_expect_success 'clone from ref namespace' '\n> +\trm -rf initial bare clone &&\n> +\tgit init initial &&\n> +\tgit init --bare bare &&\n> +\t(\n> +\t\tcd initial &&\n> +\t\techo \"commit one\" >> file &&\n\nminor style: drop SP between redirection and its target, i.e.\n\n\t\techo \"commit one\" >file &&\n\n> +\t\tgit add file &&\n> +\t\tgit commit -m \"commit one\" &&\n> +\t\tgit push ../bare master &&\n\nYou want to make sure not just \"push\" does not complain, but that it\nleft ../bare with the right result, i.e. something along the lines\nof\n\n\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n\t\techo refs/heads/master >expect &&\n                test_cmp expect actual &&\n\n\t\tgit -C ../bare rev-parse HEAD >actual &&\n                git rev-parse HEAD >expect &&\n                test_cmp expect actual &&\n\n\n> +\t\techo \"commit two\" >> file &&\n\nLikewise on style.\n\n> +\t\tgit add file &&\n> +\t\tgit commit -m \"commit two\"\n\nBroken &&-chain.\n\n> +\t\tGIT_NAMESPACE=new_namespace git push ../bare master\n\nLikewise on checking the result of the push.\n\n> +\t) &&\n> +\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n> +\t(\n> +\t\tcd clone &&\n> +\t\tgit show\n\nLikewise on checking the result of the clone; not just it has HEAD\nto cause \"show\" to succeed, you would want it shows the right commit\n(i.e. not \"one\", but \"two\").  There may be other things you may want\nto check, too.\n\n> +\t)\n> +'\n> +\n> +test_done\n"},{"id":"263026","messageId":"20150605161225.GA23368@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"xmqqk2vitbjh.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T16:12:25Z","receivedAt":"2015-06-05T16:12:25Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Junio C Hamano wrote:\n>Johannes Löthberg <johannes@kyriasis.com> writes:\n>>  +++++++++++++++++++++++++++++++++\n>\n>It seems that 5509 already has a few tests for namespaced transfer\n>in both directions.  Perhaps this new test would fit there better?\n>\n\nMissed that, will move it there.\n\n>Also I think it probably is better to have these as a single patch.\n>\n\nAs you wish.\n\n>> +\t\tgit add file &&\n>> +\t\tgit commit -m \"commit one\" &&\n>> +\t\tgit push ../bare master &&\n>\n>You want to make sure not just \"push\" does not complain, but that it\n>left ../bare with the right result, i.e. something along the lines\n>of\n>\n>\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n>\t\techo refs/heads/master >expect &&\n>                test_cmp expect actual &&\n>\n>\t\tgit -C ../bare rev-parse HEAD >actual &&\n>                git rev-parse HEAD >expect &&\n>                test_cmp expect actual &&\n>\n>\n\nHmm, it seems that git-rev-parse doesn't handle GIT_NAMESPACE yet, so \ncan't check it for the namespaced push right now. Not sure if I can fix \nthat myself though.\n\n>> +\t) &&\n>> +\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n>> +\t(\n>> +\t\tcd clone &&\n>> +\t\tgit show\n>\n>Likewise on checking the result of the clone; not just it has HEAD\n>to cause \"show\" to succeed, you would want it shows the right commit\n>(i.e. not \"one\", but \"two\").  There may be other things you may want\n>to check, too.\n>\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263027","messageId":"xmqq7frit9ad.fsf@gitster.dls.corp.google.com","threadId":"39488","inReplyTo":"20150605161225.GA23368@leeloo.kyriasis.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-05T16:22:18Z","receivedAt":"2015-06-05T16:22:18Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Löthberg <johannes@kyriasis.com> writes:\n\n> Hmm, it seems that git-rev-parse doesn't handle GIT_NAMESPACE yet, so\n> can't check it for the namespaced push right now. Not sure if I can\n> fix that myself though.\n\nI do not see a need for rev-parse to pay attention to GIT_NAMESPACE\nat all, though.\n\nThe destination that accepts the push with the enviornment variable,\ni.e. your ../bare repository after this:\n\n+\t\tgit commit -m \"commit two\"\n+\t\tGIT_NAMESPACE=new_namespace git push ../bare master\n\nmust be saving the result somewhere in ../bare/, and that is what\nyou want to check (and also no refs are affected outside that\nhierarchy).\n\nSo perhaps along the lines of\n\n        echo $(git rev-parse master) commit \\\n        \trefs/namespaces/new_namespace/refs/heads/master >expect &&\n\tgit -C ../bare for-each-ref refs/namespaces/ >actual &&\n\ttest_cmp expect actual\n\nor something?  You would want to also check that other refs are not\nmolested, so\n\n\t(\n        \techo $(git rev-parse master^) commit \\\n                \trefs/heads/master &&\n\t        echo $(git rev-parse master) commit \\\n\t        \trefs/namespaces/new_namespace/refs/heads/master\n\t) >expect &&\n\tgit -C ../bare for-each-ref >actual &&\n\ttest_cmp expect actual\n\nmight be a more appropriate test.\n"},{"id":"263028","messageId":"20150605162523.GA25914@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"20150605161225.GA23368@leeloo.kyriasis.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T16:25:23Z","receivedAt":"2015-06-05T16:25:23Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Johannes Löthberg wrote:\n>On 05/06, Junio C Hamano wrote:\n>>Johannes Löthberg <johannes@kyriasis.com> writes:\n>>\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n>>\t\techo refs/heads/master >expect &&\n>>               test_cmp expect actual &&\n>>\n>>\t\tgit -C ../bare rev-parse HEAD >actual &&\n>>               git rev-parse HEAD >expect &&\n>>               test_cmp expect actual &&\n>>\n>>\n>\n>Hmm, it seems that git-rev-parse doesn't handle GIT_NAMESPACE yet, so \n>can't check it for the namespaced push right now. Not sure if I can \n>fix that myself though.\n>\n\nWould it be acceptable to check against \n../bare/refs/namespaces/new_namespace/HEAD and \n../bare/refs/namespaces/new_namespace/refs/heads/master instead, until \nrev-parse is thaught about namespaces?\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263030","messageId":"20150605163135.GA26503@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"xmqq7frit9ad.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T16:31:35Z","receivedAt":"2015-06-05T16:31:35Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Junio C Hamano wrote:\n>Johannes Löthberg <johannes@kyriasis.com> writes:\n>\n>> Hmm, it seems that git-rev-parse doesn't handle GIT_NAMESPACE yet, so\n>> can't check it for the namespaced push right now. Not sure if I can\n>> fix that myself though.\n>\n>I do not see a need for rev-parse to pay attention to GIT_NAMESPACE\n>at all, though.\n>\n\nThe ref namespace has its own HEAD, so I'd expect\n\n  GIT_NAMESPACE=foo git rev-parse HEAD\n\nto act sensibly\n\n>The destination that accepts the push with the enviornment variable,\n>i.e. your ../bare repository after this:\n>\n>+\t\tgit commit -m \"commit two\"\n>+\t\tGIT_NAMESPACE=new_namespace git push ../bare master\n>\n>must be saving the result somewhere in ../bare/, and that is what\n>you want to check (and also no refs are affected outside that\n>hierarchy).\n>\n>So perhaps along the lines of\n>\n>        echo $(git rev-parse master) commit \\\n>        \trefs/namespaces/new_namespace/refs/heads/master >expect &&\n>\tgit -C ../bare for-each-ref refs/namespaces/ >actual &&\n>\ttest_cmp expect actual\n>\n>or something?  You would want to also check that other refs are not\n>molested, so\n>\n>\t(\n>        \techo $(git rev-parse master^) commit \\\n>                \trefs/heads/master &&\n>\t        echo $(git rev-parse master) commit \\\n>\t        \trefs/namespaces/new_namespace/refs/heads/master\n>\t) >expect &&\n>\tgit -C ../bare for-each-ref >actual &&\n>\ttest_cmp expect actual\n>\n>might be a more appropriate test.\n\nSounds okay.\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263036","messageId":"xmqqtwumrtl9.fsf@gitster.dls.corp.google.com","threadId":"39488","inReplyTo":"20150605162523.GA25914@leeloo.kyriasis.com","subject":"Re: [PATCH v2 2/2] t: Add test for cloning from ref namespace","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-05T16:46:42Z","receivedAt":"2015-06-05T16:46:42Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Löthberg <johannes@kyriasis.com> writes:\n\n> Would it be acceptable to check against\n> ../bare/refs/namespaces/new_namespace/HEAD and\n> ../bare/refs/namespaces/new_namespace/refs/heads/master instead, until\n> rev-parse is thaught about namespaces?\n\nYes.\n\nBecause I do not immediately see any legitimate reason for the rest\nof the system (including rev-parse) to ever start paying attention\nto GIT_NAMESPACE, I think that is not even \"instead, until\" but is\nthe right solution.\n\nThanks.\n"},{"id":"263038","messageId":"1433523731-25172-1-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":"1433193883-11577-1-git-send-email-johannes@kyriasis.com","subject":"[PATCH v3] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T17:02:11Z","receivedAt":"2015-06-05T17:02:11Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Each ref namespace have their own separate branches, tags, and HEAD, so\nwhen pushing to a namespace we need to make sure that there exists a\nHEAD ref for the namespace, otherwise you will not be able to check out\nthe repo after cloning from a namespace\n\nSigned-off-by: Johannes Löthberg <johannes@kyriasis.com>\n---\nsince v2:\n  * Added test case in t5509\n  * Check that the remote refs get set properly in the test\n\n builtin/receive-pack.c           | 12 +++++++++-\n t/t5509-fetch-push-namespaces.sh | 49 +++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 59 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex d2ec52b..0c18c92 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -864,7 +864,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstruct strbuf namespaced_head_buf = STRBUF_INIT;\n+\tconst char *namespaced_name, *ret, *namespace;\n+\tconst char *namespaced_head_path;\n \tunsigned char *old_sha1 = cmd->old_sha1;\n \tunsigned char *new_sha1 = cmd->new_sha1;\n \n@@ -981,6 +983,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t\treturn NULL; /* good */\n \t}\n \telse {\n+\t\tnamespace = get_git_namespace();\n+\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n+\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n+\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n+\n+\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n+\t\t}\n+\n \t\tstruct strbuf err = STRBUF_INIT;\n \t\tif (shallow_update && si->shallow_ref[cmd->index] &&\n \t\t    update_shallow_ref(cmd, si))\ndiff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh\nindex cc0b31f..7bc3a1f 100755\n--- a/t/t5509-fetch-push-namespaces.sh\n+++ b/t/t5509-fetch-push-namespaces.sh\n@@ -1,6 +1,7 @@\n #!/bin/sh\n \n-test_description='fetch/push involving ref namespaces'\n+test_description='fetch/push/clone involving ref namespaces'\n+\n . ./test-lib.sh\n \n test_expect_success setup '\n@@ -82,4 +83,50 @@ test_expect_success 'mirroring a repository using a ref namespace' '\n \t)\n '\n \n+test_expect_success 'cloning from ref namespace' '\n+\trm -rf initial bare clone &&\n+\tgit init initial &&\n+\tgit init --bare bare &&\n+\t(\n+\t\tcd initial &&\n+\t\techo \"commit one\" >file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit one\" &&\n+\t\tgit push ../bare master &&\n+\n+\t\techo refs/heads/master >expect &&\n+\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\tgit rev-parse HEAD >expect &&\n+\t\tgit -C ../bare rev-parse HEAD >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\techo \"commit two\" >>file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit two\" &&\n+\t\tGIT_NAMESPACE=new_namespace git push ../bare master &&\n+\n+\t\techo \"ref: refs/namespaces/new_namespace/refs/heads/master\" >expect &&\n+\t\ttest_cmp expect ../bare/refs/namespaces/new_namespace/HEAD  &&\n+\n+\t\t(\n+\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master^) \\\n+\t\t\t                         refs/heads/master &&\n+\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n+\t\t\t                         refs/namespaces/new_namespace/HEAD &&\n+\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n+\t\t\t                         refs/namespaces/new_namespace/refs/heads/master\n+\t\t) >expect &&\n+\t\tgit -C ../bare for-each-ref refs/ >actual &&\n+\t\ttest_cmp expect actual\n+\t) &&\n+\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n+\t(\n+\t\tcd clone &&\n+\t\tgit show\n+\t)\n+'\n+\n+\n test_done\n-- \n2.4.2\n"},{"id":"263040","messageId":"20150605170806.GA28379@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"1433523731-25172-1-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH v3] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T17:08:06Z","receivedAt":"2015-06-05T17:08:06Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"I should also look into why the other tests in t5509 fail later.\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263043","messageId":"xmqqh9qmrs2j.fsf@gitster.dls.corp.google.com","threadId":"39488","inReplyTo":"1433523731-25172-1-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH v3] receive-pack: Create a HEAD ref for ref namespace","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-05T17:19:32Z","receivedAt":"2015-06-05T17:19:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Löthberg <johannes@kyriasis.com> writes:\n\n> diff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh\n> index cc0b31f..7bc3a1f 100755\n> --- a/t/t5509-fetch-push-namespaces.sh\n> +++ b/t/t5509-fetch-push-namespaces.sh\n> @@ -1,6 +1,7 @@\n>  #!/bin/sh\n>  \n> -test_description='fetch/push involving ref namespaces'\n> +test_description='fetch/push/clone involving ref namespaces'\n> +\n\nOK ;-)\n\n>  . ./test-lib.sh\n>  \n>  test_expect_success setup '\n> @@ -82,4 +83,50 @@ test_expect_success 'mirroring a repository using a ref namespace' '\n>  \t)\n>  '\n>  \n> +test_expect_success 'cloning from ref namespace' '\n> +\trm -rf initial bare clone &&\n> +\tgit init initial &&\n> +\tgit init --bare bare &&\n> +\t(\n> +\t\tcd initial &&\n> +\t\techo \"commit one\" >file &&\n> +\t\tgit add file &&\n> +\t\tgit commit -m \"commit one\" &&\n> +\t\tgit push ../bare master &&\n> +\n> +\t\techo refs/heads/master >expect &&\n> +\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n> +\t\ttest_cmp expect actual &&\n> +\n> +\t\tgit rev-parse HEAD >expect &&\n> +\t\tgit -C ../bare rev-parse HEAD >actual &&\n> +\t\ttest_cmp expect actual &&\n> +\n> +\t\techo \"commit two\" >>file &&\n> +\t\tgit add file &&\n> +\t\tgit commit -m \"commit two\" &&\n> +\t\tGIT_NAMESPACE=new_namespace git push ../bare master &&\n> +\n> +\t\techo \"ref: refs/namespaces/new_namespace/refs/heads/master\" >expect &&\n> +\t\ttest_cmp expect ../bare/refs/namespaces/new_namespace/HEAD  &&\n\nUse \"symbolic-ref refs/namespaces/new_namespace/HEAD\"; HEAD is not\nrequired to be expressed as a textual symref.\n\n> +\n> +\t\t(\n> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master^) \\\n> +\t\t\t                         refs/heads/master &&\n> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n> +\t\t\t                         refs/namespaces/new_namespace/HEAD &&\n> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n> +\t\t\t                         refs/namespaces/new_namespace/refs/heads/master\n> +\t\t) >expect &&\n\nUse of 'printf' is clever and I like it.  Have you considered\nletting it do the iteration as well?  I.e.\n\n\tprintf \"%s commit\\t%s\\n\" \\\n        \tone two \\\n                three four \\\n                five six \\\n\t>expect &&\n\nmight be easier to read.\n\n> +\t\tgit -C ../bare for-each-ref refs/ >actual &&\n> +\t\ttest_cmp expect actual\n> +\t) &&\n> +\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n> +\t(\n> +\t\tcd clone &&\n> +\t\tgit show\n\nWe can accept any random commit at HEAD as long as it exists at this\npoint?  Don't we need to make sure that a ref whose tip is still \"one\"\nis not propagated to this new clone?\n\n> +\t)\n> +'\n> +\n> +\n>  test_done\n"},{"id":"263044","messageId":"20150605172736.GA30419@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"xmqqh9qmrs2j.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v3] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T17:27:36Z","receivedAt":"2015-06-05T17:27:36Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Junio C Hamano wrote:\n>Johannes Löthberg <johannes@kyriasis.com> writes:\n>\n>> +\n>> +\t\techo \"ref: refs/namespaces/new_namespace/refs/heads/master\" >expect &&\n>> +\t\ttest_cmp expect ../bare/refs/namespaces/new_namespace/HEAD  &&\n>\n>Use \"symbolic-ref refs/namespaces/new_namespace/HEAD\"; HEAD is not\n>required to be expressed as a textual symref.\n>\n\nGotcha.\n\n>> +\n>> +\t\t(\n>> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master^) \\\n>> +\t\t\t                         refs/heads/master &&\n>> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n>> +\t\t\t                         refs/namespaces/new_namespace/HEAD &&\n>> +\t\t\tprintf \"%s commit\\t%s\\n\" $(git rev-parse master) \\\n>> +\t\t\t                         refs/namespaces/new_namespace/refs/heads/master\n>> +\t\t) >expect &&\n>\n>Use of 'printf' is clever and I like it.  Have you considered\n>letting it do the iteration as well?  I.e.\n>\n>\tprintf \"%s commit\\t%s\\n\" \\\n>        \tone two \\\n>                three four \\\n>                five six \\\n>\t>expect &&\n>\n>might be easier to read.\n>\n\nDidn't think about that actually. Will do.\n\n>> +\t\tgit -C ../bare for-each-ref refs/ >actual &&\n>> +\t\ttest_cmp expect actual\n>> +\t) &&\n>> +\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n>> +\t(\n>> +\t\tcd clone &&\n>> +\t\tgit show\n>\n>We can accept any random commit at HEAD as long as it exists at this\n>point?  Don't we need to make sure that a ref whose tip is still \"one\"\n>is not propagated to this new clone?\n>\n\nOh crap, I just remembered that I forgot to address that part, sorry.\n\n>> +\t)\n>> +'\n>> +\n>> +\n>>  test_done\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263046","messageId":"1433526142-2413-1-git-send-email-johannes@kyriasis.com","threadId":"39488","inReplyTo":"1433193883-11577-1-git-send-email-johannes@kyriasis.com","subject":"[PATCH v4] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-05T17:42:22Z","receivedAt":"2015-06-05T17:42:22Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"Each ref namespace have their own separate branches, tags, and HEAD, so\nwhen pushing to a namespace we need to make sure that there exists a\nHEAD ref for the namespace, otherwise you will not be able to check out\nthe repo after cloning from a namespace\n\nSigned-off-by: Johannes Löthberg <johannes@kyriasis.com>\n---\nChanges since v3:\n  test:\n    * Use a single printf statement\n    * Check that the contents of the file and sha of the commits in the\n      initial and cloned repositories matches\n\n builtin/receive-pack.c           | 12 +++++++++-\n t/t5509-fetch-push-namespaces.sh | 50 +++++++++++++++++++++++++++++++++++++++-\n 2 files changed, 60 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex d2ec52b..0c18c92 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -864,7 +864,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstruct strbuf namespaced_head_buf = STRBUF_INIT;\n+\tconst char *namespaced_name, *ret, *namespace;\n+\tconst char *namespaced_head_path;\n \tunsigned char *old_sha1 = cmd->old_sha1;\n \tunsigned char *new_sha1 = cmd->new_sha1;\n \n@@ -981,6 +983,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t\treturn NULL; /* good */\n \t}\n \telse {\n+\t\tnamespace = get_git_namespace();\n+\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n+\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n+\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n+\n+\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n+\t\t}\n+\n \t\tstruct strbuf err = STRBUF_INIT;\n \t\tif (shallow_update && si->shallow_ref[cmd->index] &&\n \t\t    update_shallow_ref(cmd, si))\ndiff --git a/t/t5509-fetch-push-namespaces.sh b/t/t5509-fetch-push-namespaces.sh\nindex cc0b31f..88c8aa9 100755\n--- a/t/t5509-fetch-push-namespaces.sh\n+++ b/t/t5509-fetch-push-namespaces.sh\n@@ -1,6 +1,7 @@\n #!/bin/sh\n \n-test_description='fetch/push involving ref namespaces'\n+test_description='fetch/push/clone involving ref namespaces'\n+\n . ./test-lib.sh\n \n test_expect_success setup '\n@@ -82,4 +83,51 @@ test_expect_success 'mirroring a repository using a ref namespace' '\n \t)\n '\n \n+test_expect_success 'cloning from ref namespace' '\n+\trm -rf initial bare clone &&\n+\tgit init initial &&\n+\tgit init --bare bare &&\n+\t(\n+\t\tcd initial &&\n+\t\techo \"commit one\" >file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit one\" &&\n+\t\tgit push ../bare master &&\n+\n+\t\techo refs/heads/master >expect &&\n+\t\tgit -C ../bare symbolic-ref HEAD >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\tgit rev-parse HEAD >expect &&\n+\t\tgit -C ../bare rev-parse HEAD >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\techo \"commit two\" >>file &&\n+\t\tgit add file &&\n+\t\tgit commit -m \"commit two\" &&\n+\t\tGIT_NAMESPACE=new_namespace git push ../bare master &&\n+\n+\t\techo \"ref: refs/namespaces/new_namespace/refs/heads/master\" >expect &&\n+\t\ttest_cmp expect ../bare/refs/namespaces/new_namespace/HEAD &&\n+\n+\t\tprintf \"%s commit\\t%s\\n\" \\\n+\t\t    $(git rev-parse master^) refs/heads/master \\\n+\t\t    $(git rev-parse master) refs/namespaces/new_namespace/HEAD \\\n+\t\t    $(git rev-parse master) refs/namespaces/new_namespace/refs/heads/master >expect &&\n+\t\tgit -C ../bare for-each-ref refs/ >actual &&\n+\t\ttest_cmp expect actual\n+\t) &&\n+\tGIT_NAMESPACE=new_namespace git clone bare clone &&\n+\t(\n+\t\tgit -C initial cat-file blob master:file >expect &&\n+\t\tgit -C clone cat-file blob master:file >actual &&\n+\t\ttest_cmp expect actual &&\n+\n+\t\tgit -C initial rev-parse master >expect &&\n+\t\tgit -C clone rev-parse master >actual &&\n+\t\ttest_cmp expect actual\n+\t)\n+'\n+\n+\n test_done\n-- \n2.4.2\n"},{"id":"263544","messageId":"20150610233921.GA28452@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"1433526142-2413-1-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH v4] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-10T23:39:21Z","receivedAt":"2015-06-10T23:39:21Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 05/06, Johannes Löthberg wrote:\n>Each ref namespace have their own separate branches, tags, and HEAD, so\n>when pushing to a namespace we need to make sure that there exists a\n>HEAD ref for the namespace, otherwise you will not be able to check out\n>the repo after cloning from a namespace\n>\n>Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>\n>---\n>Changes since v3:\n>  test:\n>    * Use a single printf statement\n>    * Check that the contents of the file and sha of the commits in the\n>      initial and cloned repositories matches\n>\n\nAny other comments?\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"},{"id":"263900","messageId":"xmqqlhfk7l6l.fsf@gitster.dls.corp.google.com","threadId":"39488","inReplyTo":"1433526142-2413-1-git-send-email-johannes@kyriasis.com","subject":"Re: [PATCH v4] receive-pack: Create a HEAD ref for ref namespace","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-15T20:48:02Z","receivedAt":"2015-06-15T20:48:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Löthberg <johannes@kyriasis.com> writes:\n\n> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\n> index d2ec52b..0c18c92 100644\n> --- a/builtin/receive-pack.c\n> +++ b/builtin/receive-pack.c\n> @@ -864,7 +864,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n>  {\n>  \tconst char *name = cmd->ref_name;\n>  \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n> -\tconst char *namespaced_name, *ret;\n> +\tstruct strbuf namespaced_head_buf = STRBUF_INIT;\n> +\tconst char *namespaced_name, *ret, *namespace;\n> +\tconst char *namespaced_head_path;\n>  \tunsigned char *old_sha1 = cmd->old_sha1;\n>  \tunsigned char *new_sha1 = cmd->new_sha1;\n>  \n> @@ -981,6 +983,14 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n>  \t\treturn NULL; /* good */\n>  \t}\n>  \telse {\n> +\t\tnamespace = get_git_namespace();\n> +\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n> +\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n> +\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n> +\n> +\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n\nIn a normal environment without any namespace, get_git_namespace()\nwill return an empty string, which is not \"refs/namespaces/\", so we\ncreate a symref HEAD (that is .git/HEAD) that points at whatever\nname the command is about.  And this is done every time any ref is\nupdated, flipping the HEAD to point at whatever was pushed the last,\nisn't it?\n\nWhy is this a good change?  I am puzzled...\n\n> +\t\t}\n> +\n>  \t\tstruct strbuf err = STRBUF_INIT;\n\nThis adds decl-after-stmt.\n\nGoing back to the proposed log message...\n\n> Each ref namespace have their own separate branches, tags, and HEAD, so\n> when pushing to a namespace we need to make sure that there exists a\n> HEAD ref for the namespace, otherwise you will not be able to check out\n> the repo after cloning from a namespace\n\nWhat this paragraph describes is entirely correct, I think.  But I\ndo not think receive-pack is the \"we\" in that paragraph.\n\nWhen setting up a \"namespace\" a and b, shouldn't you be doing\nessentially\n\n\tr=refs/namespaces/\n\tfor ns in a b\n        do\n\t\tgit symbolic-ref $r$ns/HEAD $r$ns/refs/heads/master\n\tdone\n\nor something, which is an equivalent to what \"git init\" does to a\nnormal repository?\n"},{"id":"263905","messageId":"20150615205956.GA15571@leeloo.kyriasis.com","threadId":"39488","inReplyTo":"xmqqlhfk7l6l.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4] receive-pack: Create a HEAD ref for ref namespace","fromName":"Johannes Löthberg","fromEmail":"johannes@kyriasis.com","sentAt":"2015-06-15T20:59:56Z","receivedAt":"2015-06-15T20:59:56Z","isPatch":true,"sender":{"key":"johannes@kyriasis.com","avatar":"https://gravatar.com/avatar/af2dea1b1759403329a1b7eaa28a07b5c5d1901e9f55723103d6324ffb7737ae?d=mp&s=160"},"body":"On 15/06, Junio C Hamano wrote:\n>Johannes Löthberg <johannes@kyriasis.com> writes:\n>>  \telse {\n>> +\t\tnamespace = get_git_namespace();\n>> +\t\tif (strcmp(namespace, \"refs/namespaces/\")) {\n>> +\t\t\tstrbuf_addf(&namespaced_head_buf, \"%s%s\", namespace, \"HEAD\");\n>> +\t\t\tnamespaced_head_path = strbuf_detach(&namespaced_head_buf, NULL);\n>> +\n>> +\t\t\tcreate_symref(namespaced_head_path, namespaced_name, NULL);\n>\n>In a normal environment without any namespace, get_git_namespace()\n>will return an empty string, which is not \"refs/namespaces/\", so we\n>create a symref HEAD (that is .git/HEAD) that points at whatever\n>name the command is about.  And this is done every time any ref is\n>updated, flipping the HEAD to point at whatever was pushed the last,\n>isn't it?\n>\n>Why is this a good change?  I am puzzled...\n>\n\nThis creates a HEAD symref in the namespace itself, since there's no \nother place that creates it. It could probably be done better, but I'm \nnot very familiar with the Git codebase.\n\n>> +\t\t}\n>> +\n>>  \t\tstruct strbuf err = STRBUF_INIT;\n>\n>This adds decl-after-stmt.\n>\n>Going back to the proposed log message...\n>\n>> Each ref namespace have their own separate branches, tags, and HEAD, so\n>> when pushing to a namespace we need to make sure that there exists a\n>> HEAD ref for the namespace, otherwise you will not be able to check out\n>> the repo after cloning from a namespace\n>\n>What this paragraph describes is entirely correct, I think.  But I\n>do not think receive-pack is the \"we\" in that paragraph.\n>\n>When setting up a \"namespace\" a and b, shouldn't you be doing\n>essentially\n>\n>\tr=refs/namespaces/\n>\tfor ns in a b\n>        do\n>\t\tgit symbolic-ref $r$ns/HEAD $r$ns/refs/heads/master\n>\tdone\n>\n>or something, which is an equivalent to what \"git init\" does to a\n>normal repository?\n>\n\nThe only way to set up a namespace is by pushing to it.\n\n-- \nSincerely,\n  Johannes Löthberg\n  PGP Key ID: 0x50FB9B273A9D0BB5\n  https://theos.kyriasis.com/~kyrias/\n"}]}