{"thread":{"id":"30732","subject":"[PATCH] git fetch one tag only","startedAt":"2012-06-07T01:40:45Z","lastAt":"2012-06-08T22:22:11Z","messageCount":9,"participants":["cheng renquan","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"193024","messageId":"CAH5vBdK_M+7Hjk=juVeP7Phqvs2+npknFD-=45OVR032k5S-0A@mail.gmail.com","threadId":"30732","inReplyTo":null,"subject":"[PATCH] git fetch one tag only","fromName":"cheng renquan","fromEmail":"crquan@gmail.com","sentAt":"2012-06-07T01:40:45Z","receivedAt":"2012-06-07T01:40:45Z","isPatch":true,"sender":{"key":"crquan@gmail.com","avatar":"https://gravatar.com/avatar/8689a8a26f5d1c7515ca8226258710684dac5c5208b84a9e16a086377f2d3ded?d=mp&s=160"},"body":"Someone maybe like me is working in the way of following one central\ngit repository\nwhile sometimes need to fetch some code or tags from a 3rd git repo,\nbut unfortunately the 3rd repo may contain a lot of tags not all I want\nto fetch to mess up my local repo, at this time I want to fetch only one tag\nfrom the 3rd repo, but the syntax of\n  `git fetch 3rd-repo the-tag-name`\n\nreally fetched the code of the-tag-name from 3rd-repo, but forgot the\ntag itself;\nthis patch enhanced the above syntax to create the tag itself;\n\n\n builtin/fetch.c |    8 ++++++++\n 1 file changed, 8 insertions(+)\n\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex bb9a074..9a3ec4a 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -439,6 +439,14 @@ static int store_updated_refs(const char\n*raw_url, const char *remote_name,\n \t\t\telse if (!prefixcmp(rm->name, \"refs/tags/\")) {\n \t\t\t\tkind = \"tag\";\n \t\t\t\twhat = rm->name + 10;\n+\t\t\t\tif (!ref) {\n+\t\t\t\t\tunsigned char sha1[20];\n+\t\t\t\t\tref = alloc_ref(rm->name);\n+\t\t\t\t\thashcpy(ref->new_sha1, rm->old_sha1);\n+\t\t\t\t\tif (!get_sha1(rm->name, sha1))\n+\t\t\t\t\t\thashcpy(ref->old_sha1, sha1);\n+\t\t\t\t}\n \t\t\t}\n \t\t\telse if (!prefixcmp(rm->name, \"refs/remotes/\")) {\n \t\t\t\tkind = \"remote-tracking branch\";\n\n-- \ncheng renquan (程任全)\n"},{"id":"193028","messageId":"CAPc5daVwOuP_dPiHh5zcjV6kTvdb2FNhzXz_capEDhHgE5ZUKw@mail.gmail.com","threadId":"30732","inReplyTo":"CAH5vBdK_M+7Hjk=juVeP7Phqvs2+npknFD-=45OVR032k5S-0A@mail.gmail.com","subject":"Re: [PATCH] git fetch one tag only","fromName":"Junio C Hamano","fromEmail":"gitster-vger@pobox.com","sentAt":"2012-06-07T04:37:55Z","receivedAt":"2012-06-07T04:37:55Z","isPatch":true,"sender":{"key":"gitster-vger@pobox.com","avatar":null},"body":"On Wed, Jun 6, 2012 at 6:40 PM, cheng renquan <crquan@gmail.com> wrote:\n>\n> Someone maybe like me is working in the way of following one central\n> git repository\n> while sometimes need to fetch some code or tags from a 3rd git repo,\n> but unfortunately the 3rd repo may contain a lot of tags not all I want\n> to fetch to mess up my local repo, at this time I want to fetch only one tag\n> from the 3rd repo, but the syntax of\n>  `git fetch 3rd-repo the-tag-name`\n>\n> really fetched the code of the-tag-name from 3rd-repo, but forgot the\n> tag itself;\n\n\nThe subject of \"forgot\" in that sentence is you, not \"git fetch\".\nYou told \"git fetch\" to grab it but not store it locally in your\nrefs/tags namespace.\n\nThere is a convenience short-hand \"tag <tagname>\", i.e.\n\n  git fetch 3rd-repo tag the-tag-name\n\nthat is equivalent to\n\n  git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name\n\nSo I do not think your patch is necessary for your use case, and\nobviously it will\nbreak other people's use case where they just want to fetch (and inspect what is\nleft in FETCH_HEAD) but do not want to store.\n"},{"id":"193029","messageId":"CAH5vBdKPH_-cn=r-zxQKCOi5PB5D6vuSXrZxPeZJ+HYg-K9Yqw@mail.gmail.com","threadId":"30732","inReplyTo":"CAPc5daVwOuP_dPiHh5zcjV6kTvdb2FNhzXz_capEDhHgE5ZUKw@mail.gmail.com","subject":"Re: [PATCH] git fetch one tag only","fromName":"cheng renquan","fromEmail":"crquan@gmail.com","sentAt":"2012-06-07T05:17:46Z","receivedAt":"2012-06-07T05:17:46Z","isPatch":true,"sender":{"key":"crquan@gmail.com","avatar":"https://gravatar.com/avatar/8689a8a26f5d1c7515ca8226258710684dac5c5208b84a9e16a086377f2d3ded?d=mp&s=160"},"body":"On Wed, Jun 6, 2012 at 9:37 PM, Junio C Hamano <gitster-vger@pobox.com> wrote:\n> On Wed, Jun 6, 2012 at 6:40 PM, cheng renquan <crquan@gmail.com> wrote:\n>>\n>> Someone maybe like me is working in the way of following one central\n>> git repository\n>> while sometimes need to fetch some code or tags from a 3rd git repo,\n>> but unfortunately the 3rd repo may contain a lot of tags not all I want\n>> to fetch to mess up my local repo, at this time I want to fetch only one tag\n>> from the 3rd repo, but the syntax of\n>>  `git fetch 3rd-repo the-tag-name`\n>>\n>> really fetched the code of the-tag-name from 3rd-repo, but forgot the\n>> tag itself;\n>\n>\n> The subject of \"forgot\" in that sentence is you, not \"git fetch\".\n> You told \"git fetch\" to grab it but not store it locally in your\n> refs/tags namespace.\n>\n> There is a convenience short-hand \"tag <tagname>\", i.e.\n>\n>   git fetch 3rd-repo tag the-tag-name\n>\n> that is equivalent to\n>\n>   git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name\n>\n> So I do not think your patch is necessary for your use case, and\n> obviously it will\n> break other people's use case where they just want to fetch (and inspect what is\n> left in FETCH_HEAD) but do not want to store.\n\nNo, I tried what you said but it doesn't work as expected:\n\n  git fetch linux-stable tag v3.4.1\n\nMy [linus-git] is following torvalds' tree and now I want to fetch\njust one tag v3.4.1 from\nlinux-stable tree, but the above command would fetch all tags from linux-stable\n\nlinus-git\tgit://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git\n(fetch)\nlinux-stable\tgit://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git\n(fetch)\n\n\n[linus-git] $ git fetch -v --dry-run linux-stable tag v3.4.1 |& head\nFrom git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable\n = [up to date]      v3.4.1     -> v3.4.1\n * [new tag]         latest     -> latest\n * [new tag]         v2.6.12.1  -> v2.6.12.1\n * [new tag]         v2.6.12.2  -> v2.6.12.2\n[...]\n\n\nI didn't know this syntax before, but Yes, this syntax should serve\nthe one-tag-only goal better,\n  `git fetch 3rd-repo tag the-tag-name`\nmaybe I'd better to fix that?\n"},{"id":"193031","messageId":"7vpq9bk7o5.fsf@alter.siamese.dyndns.org","threadId":"30732","inReplyTo":"CAH5vBdKPH_-cn=r-zxQKCOi5PB5D6vuSXrZxPeZJ+HYg-K9Yqw@mail.gmail.com","subject":"Re: [PATCH] git fetch one tag only","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-07T05:33:30Z","receivedAt":"2012-06-07T05:33:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"cheng renquan <crquan@gmail.com> writes:\n\n>> There is a convenience short-hand \"tag <tagname>\", i.e.\n>>\n>>  git fetch 3rd-repo tag the-tag-name\n>>\n>> that is equivalent to\n>>\n>>  git fetch 3rd-repo refs/tags/the-tag-name:refs/tags/the-tag-name\n>>\n>> So I do not think your patch is necessary for your use case, and\n>> obviously it will break other people's use case where they just\n>> want to fetch (and inspect what is left in FETCH_HEAD) but do not\n>> want to store.\n>\n> No, I tried what you said but it doesn't work as expected:\n> ...\n> [linus-git] $ git fetch -v --dry-run linux-stable tag v3.4.1 |& head\n> From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable\n>  = [up to date]      v3.4.1     -> v3.4.1\n>  * [new tag]         latest     -> latest\n>  * [new tag]         v2.6.12.1  -> v2.6.12.1\n>  * [new tag]         v2.6.12.2  -> v2.6.12.2\n> [...]\n> maybe I'd better to fix that?\n\nAhh, that is auto-following of tags.  Read up on that in \"git fetch\"\nmanual page, and there is an option to decline auto-following also\ndescribed.\n\nThe (current) rule is to grab all tags that reference commits you\nare fetching *IF* you are storing any refs resulting from the fetch\nin your refs/ namespace, and \"tag v3.4.1\" obviously asks for storing\nthat tag at refs/tags/v3.4.1 in your repository, so it is expected\nthat the auto-following kicks in.\n\nIt is a separate matter if we should add some special case to further\nreduce the cases where auto-following happens. I personally do not\nthink any change is needed.\n"},{"id":"193032","messageId":"CAH5vBdKXaOV3hC0E0s=j3Hc2jZ9otxhXLMhCCKiU4=Rn4Y4COA@mail.gmail.com","threadId":"30732","inReplyTo":"7vpq9bk7o5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git fetch one tag only","fromName":"cheng renquan","fromEmail":"crquan@gmail.com","sentAt":"2012-06-07T05:47:15Z","receivedAt":"2012-06-07T05:47:15Z","isPatch":true,"sender":{"key":"crquan@gmail.com","avatar":"https://gravatar.com/avatar/8689a8a26f5d1c7515ca8226258710684dac5c5208b84a9e16a086377f2d3ded?d=mp&s=160"},"body":"ok, got it:\n\n$ git fetch -v --no-tags linux-stable tag v3.4.1\nFrom git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable\n = [up to date]      v3.4.1     -> v3.4.1\n"},{"id":"193071","messageId":"CAH5vBdKHOg=PTsFPgcsd3iNEuTTY_dD2gPNXkmzjRmE8NpBrXw@mail.gmail.com","threadId":"30732","inReplyTo":"CAH5vBdKXaOV3hC0E0s=j3Hc2jZ9otxhXLMhCCKiU4=Rn4Y4COA@mail.gmail.com","subject":"Re: [PATCH] git fetch one tag only","fromName":"cheng renquan","fromEmail":"crquan@gmail.com","sentAt":"2012-06-07T16:11:00Z","receivedAt":"2012-06-07T16:11:00Z","isPatch":true,"sender":{"key":"crquan@gmail.com","avatar":"https://gravatar.com/avatar/8689a8a26f5d1c7515ca8226258710684dac5c5208b84a9e16a086377f2d3ded?d=mp&s=160"},"body":"On Wed, Jun 6, 2012 at 10:47 PM, cheng renquan <crquan@gmail.com> wrote:\n> ok, got it:\n>\n> $ git fetch -v --no-tags linux-stable tag v3.4.1\n> From git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable\n>  = [up to date]      v3.4.1     -> v3.4.1\n\nHere I still think the logic is wrong:\n\n$ git fetch linux-stable tag\nfatal: You need to specify a tag name.\n\n$ git fetch linux-stable tag v3.4.1\n[this would actually fetch all tags]\n\n\nfrom `git help fetch`:\n\n           Some short-cut notations are also supported.\n\n           ·    tag <tag> means the same as\nrefs/tags/<tag>:refs/tags/<tag>; it requests fetching everything up to\nthe given tag.\n\n\nHere the documentation is saying \"everything up to the given tag.\",\nbut other tags can never be all belonging to that path, for above\nexample, in the path up to given tag v3.4.1, I'm sure other tags like\nv3.3.1 are not in the path;\n\nSo the `git fetch linux-stable tag v3.4.1` fetched other tags is a\nWRONG behavior,\nand why can't we fix that by disabling auto-following automatically if\nuse tag syntax? Why to the user \"--no-tags\" is explicitly required?\n"},{"id":"193080","messageId":"7v8vfzjbhi.fsf@alter.siamese.dyndns.org","threadId":"30732","inReplyTo":"7vpq9bk7o5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git fetch one tag only","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-07T17:08:41Z","receivedAt":"2012-06-07T17:08:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> It is a separate matter if we should add some special case to further\n> reduce the cases where auto-following happens. I personally do not\n> think any change is needed.\n\nI do not care too deeply either way, but after doing\n\n\t$ git init blank && cd blank\n\nand in an empty repository:\n\n        $ git fetch $over_there v1.0.0\n\nwill grab the named tag and drop it in FETCH_HEAD, without adding\nanything to your local refs, while\n\n\t$ git fetch $over_there tag v1.0.0\n\nwill grab the named tag and copy it to your refs/tags/v1.0.0, and\nauto-follow all the tags that point at commits that are reachable.\n\nTo grab and store _only_ v1.0.0 in the local refs, you need to say\n\"do not auto-follow\" with\n\n\t$ git fetch $over_there --no-tags tag v1.0.0\n\nWhile it may be workable, the user experience could be better in a\ncouple of different ways.\n\n * It is not fair to expect anybody to guess that \"--no-tags\" means\n   \"--no-auto-follow-tags\" without reading documentation.\n\n\t$ git fetch $over_there --no-auto-follow-tags tag v1.0.0\n\n   might be an improvement, but of course, it is a bit longer to\n   spell ;-).\n\n * The auto-follow kicks in whenever you tell \"fetch\" to update some\n   refs locally.  Maybe if we tweak the rule and auto-follow kick in\n   only when you tell \"fetch\" to update some refs outside refs/tags\n   locally,\n\n\t$ git fetch $over_there tag v1.0.0\n\n   will fetch and store _only_ the v1.0.0 tag.\n\n   Of course, any behaviour change is a regression, and if done\n   without an escape hatch, such a change robs people one useful\n   feature: grab tag v1.0.0 and others older than that tag in one\n   go.\n\nI won't be coding any of the above; just thinking aloud. \n"},{"id":"193192","messageId":"CAH5vBdLGHpFCH3mWgNANTw4frzqSz=AO+kB12DSx55wn1hYJag@mail.gmail.com","threadId":"30732","inReplyTo":"7v8vfzjbhi.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] git fetch one tag only","fromName":"cheng renquan","fromEmail":"crquan@gmail.com","sentAt":"2012-06-08T21:46:06Z","receivedAt":"2012-06-08T21:46:06Z","isPatch":true,"sender":{"key":"crquan@gmail.com","avatar":"https://gravatar.com/avatar/8689a8a26f5d1c7515ca8226258710684dac5c5208b84a9e16a086377f2d3ded?d=mp&s=160"},"body":"On Thu, Jun 7, 2012 at 10:08 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>  * The auto-follow kicks in whenever you tell \"fetch\" to update some\n>   refs locally.  Maybe if we tweak the rule and auto-follow kick in\n>   only when you tell \"fetch\" to update some refs outside refs/tags\n>   locally,\n>\n>        $ git fetch $over_there tag v1.0.0\n>\n>   will fetch and store _only_ the v1.0.0 tag.\n>\n>   Of course, any behaviour change is a regression, and if done\n>   without an escape hatch, such a change robs people one useful\n>   feature: grab tag v1.0.0 and others older than that tag in one\n>   go.\n>\n> I won't be coding any of the above; just thinking aloud.\n\nHere is the code to implement your 2nd approach,\nand I don't think this behaviour change is a regression,\nbecause if someone is really relying this fetch one tag actually fetch\nall tags feature\nhe is relying on a broken feature, and should be corrected:\nif one really need to fetch all tags, that's what explicit \"--tags\"\ndesigned and documented for\n\n\ndiff --git a/builtin/fetch.c b/builtin/fetch.c\nindex bb9a074..b6d7ef3 100644\n--- a/builtin/fetch.c\n+++ b/builtin/fetch.c\n@@ -158,7 +158,8 @@ static struct ref *get_ref_map(struct transport *transport,\n \tif (ref_count || tags == TAGS_SET) {\n \t\tfor (i = 0; i < ref_count; i++) {\n \t\t\tget_fetch_map(remote_refs, &refs[i], &tail, 0);\n-\t\t\tif (refs[i].dst && refs[i].dst[0])\n+\t\t\tif (refs[i].dst && refs[i].dst[0]\n+\t\t\t    && prefixcmp(refs[i].dst, \"refs/tags/\"))\n \t\t\t\t*autotags = 1;\n \t\t}\n \t\t/* Merge everything on the command line, but not --tags */\n\n-- \ncheng renquan (程任全)\n"},{"id":"193194","messageId":"7vmx4dbg18.fsf@alter.siamese.dyndns.org","threadId":"30732","inReplyTo":"CAH5vBdLGHpFCH3mWgNANTw4frzqSz=AO+kB12DSx55wn1hYJag@mail.gmail.com","subject":"Re: [PATCH] git fetch one tag only","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-08T22:22:11Z","receivedAt":"2012-06-08T22:22:11Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"cheng renquan <crquan@gmail.com> writes:\n\n> On Thu, Jun 7, 2012 at 10:08 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>  * The auto-follow kicks in whenever you tell \"fetch\" to update some\n>>   refs locally.  Maybe if we tweak the rule and auto-follow kick in\n>>   only when you tell \"fetch\" to update some refs outside refs/tags\n>>   locally,\n>>\n>>        $ git fetch $over_there tag v1.0.0\n>>\n>>   will fetch and store _only_ the v1.0.0 tag.\n>>\n>>   Of course, any behaviour change is a regression, and if done\n>>   without an escape hatch, such a change robs people one useful\n>>   feature: grab tag v1.0.0 and others older than that tag in one\n>>   go.\n>>\n>> I won't be coding any of the above; just thinking aloud.\n>\n> Here is the code to implement your 2nd approach,\n\nThe patch is obviously and trivially correct ;-)\n\n> and I don't think this behaviour change is a regression,\n> because if someone is really relying this fetch one tag actually fetch\n> all tags feature\n> he is relying on a broken feature,\n\nI do not think the old behaviour is broken. \"tag v1.0.0\" asks for\nrefs/tags/v1.0.0 at the remote and store it at refs/tags/v1.0.0\nlocally.  And when you ask \"git fetch\" to store something in refs/\nhierarchy like that, without --no-tags, you are also asking tags on\ncommits reachable from v1.0.0 (e.g. v0.99, but not v1.1.0).\n\n\tSide note: I just double-checked this.\n\n\t$ git init junk && cd junk\n        $ git fetch ../git.git tag v1.0.0\n\n\tOf course, I get v1.0.0, many tags in v0.99 series and\n\tv1.0rc tags, but nothing newer.\n\nI would grant you that \"asking for only tags v1.0.0 and everything\nbefore\" is not a very common thing to do, but I do not think it is a\nwrong feature in any way.\n\nIn any case, when we discuss regression, \"I think the old behaviour\nis broken\" does not matter.  Change in behaviour is change in\nbehaviour, even if the new one is superiour than the old one (and I\ntend to think that if I were doing Git from scratch, I probably\nwould have coded the auto-follow part to ignore refs/tags hierarchy).\n\nThe problem of introducing such a change _today_ is that it robs a\nway to ask for tags v1.0.0 and all tags before it, which people can\ndo with Git without the patch.  A new --auto-follow-tags option that\nundoes what the patch does could remedy it, but without such an\nescape hatch, the change will be a true regression as it not just\nchanges behaviour but it loses capability.\n"}]}