{"thread":{"id":"33982","subject":"[PATCH] show-ref: make --head always show the HEAD ref","startedAt":"2013-05-30T06:08:25Z","lastAt":"2013-07-17T00:05:14Z","messageCount":8,"participants":["Doug Bell","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"218939","messageId":"1369894105-48434-1-git-send-email-madcityzen@gmail.com","threadId":"33982","inReplyTo":null,"subject":"[PATCH] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-05-30T06:08:25Z","receivedAt":"2013-05-30T06:08:25Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"The docs seem to say that doing\n\n\tgit show-ref --head --tags\n\nwould show both the HEAD ref and all the tag refs. However, doing\nboth --head and either of --tags or --heads would filter out the HEAD\nref.\n\nSigned-off-by: Doug Bell <madcityzen@gmail.com>\n---\nI think this patch could be done better if I refactor the show_ref() sub\na bit...\n\nThis commit passes the current test suite. Where would I put new\ntests for this? I can't find an existing show-ref test to append to.\nI would be happy to write show-ref tests if there aren't any already.\n\n builtin/show-ref.c | 3 +++\n 1 file changed, 3 insertions(+)\n\ndiff --git a/builtin/show-ref.c b/builtin/show-ref.c\nindex 8d9b76a..5954e9b 100644\n--- a/builtin/show-ref.c\n+++ b/builtin/show-ref.c\n@@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \tconst char *hex;\n \tunsigned char peeled[20];\n \n+\tif (show_head && !strncmp(refname, \"HEAD\\0\", 5))\n+\t\tgoto match;\n+\n \tif (tags_only || heads_only) {\n \t\tint match;\n \n-- \n1.8.3.101.g727a46b.dirty\n"},{"id":"223074","messageId":"7v38rlt88j.fsf@alter.siamese.dyndns.org","threadId":"33982","inReplyTo":"1369894105-48434-1-git-send-email-madcityzen@gmail.com","subject":"Re: [PATCH] show-ref: make --head always show the HEAD ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-11T15:41:00Z","receivedAt":"2013-07-11T15:41:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Doug Bell <madcityzen@gmail.com> writes:\n\n> The docs seem to say that doing\n>\n> \tgit show-ref --head --tags\n>\n> would show both the HEAD ref and all the tag refs. However, doing\n> both --head and either of --tags or --heads would filter out the HEAD\n> ref.\n>\n> Signed-off-by: Doug Bell <madcityzen@gmail.com>\n> ---\n\nI think this patch fell through the cracks, and looking at it, I am\nsomewhat torn.\n\nThe command help for \"--head\" says \"show the HEAD reference\", which\nmay mean:\n\n (1) in addition to everything else the command would do if there\n     weren't this option specified, show HEAD;\n\n (2) show the HEAD and nothing else; or\n\n (3) add HEAD to the candidates to be shown, but apply the usual\n     filtering rule based on --heads, --tags and/or pattern\n     arguments.\n\nWhile the last interpretation is what we have used since the\nbeginning of the command at 358ddb62 (Add \"git show-ref\" builtin\ncommand, 2006-09-15), I tend to agree with you that the first\ninterpretation may make more sense, at least from the end user's\npoint of view.\n\nBut at a deeper level, it makes the command somewhat inconsistent.\n\nWhat happens in the command is\n\n - We iterate over \"candidates to be shown\", which is usually\n   \"everything under refs/\", but with \"--head\", HEAD is added to\n   this set.  For each of these candidates:\n\n   - if one or more <pattern> parameters are given, reject the\n     candidate ref if it does not tail-match with any of the\n     patterns;\n\n   - if either \"--heads\" or \"--tags\" is given, among the ones that\n     pass <pattern> filter, check if they:\n\n     - begin with \"refs/heads/\" (if \"--heads\" is given); or\n     - begin with \"refs/tags/\" (if \"--tags\" is given).\n\n     and reject those that don't.\n\n   - show it if it is still surviving after these two tests.\n\nAnd taht is why \"git show-ref --tags master v1.3.0\" shows only the\nv1.3.0 tag without showing the master branch, and giving \"--heads\"\ninstead of \"--tags\" yields only the master branch without the tag.\n\nThe semantics your patch wants, by changing the definition of\n\"--head\" from (3) to (1), is:\n\n - If \"--head\" is given, show HEAD no matter what.\n\n - Iterate over everything under refs/, and for each of them, do the\n   same filter-and-show as we currently do (see above).\n\nWhile I think the new semantics is also understandable as the\ncurrent one, and personally I think it is a better behaviour than\nthe current one, it will require an update to the document to\nhighlight that \"--head\" is special-cased in a big way, to bypass all\nthe filtering that is applied to normal refs.\n\nA few additional observations (these are not complaints to this\npatch and please do not take them as such):\n\n - The command help says \"(can be combined with heads)\" for \"--tags\"\n   and vice versa, but does not mention their interaction with\n   \"--head\".  This is because we take interpretation (3) above and\n   do not treat \"--head\" as a mechanism to add to <pattern>\n   parameter like these two.\n\n - The command help for \"--heads\" and \"--tags\" says \"only show\n   heads/tags\", which technically does not contradict with \"can be\n   combined with\" above, but a logical consequence of combining\n   ought to be showing nothing, as a ref cannot be a head (an old\n   nomenclature for a \"branch\") and a tag at the same time.  \n\nI think we should find a word better than \"only\" to use here, but I\nam not sure what would be a good phrase to use.\n"},{"id":"223239","messageId":"59D4F790-70BA-41DB-80A3-13AD397B3FCF@gmail.com","threadId":"33982","inReplyTo":"7v38rlt88j.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-07-13T02:01:50Z","receivedAt":"2013-07-13T02:01:50Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"On Jul 11, 2013, at 10:41 AM, Junio C Hamano <gitster@pobox.com> wrote:\n\n> Doug Bell <madcityzen@gmail.com> writes:\n> \n>> The docs seem to say that doing\n>> \n>> \tgit show-ref --head --tags\n>> \n>> would show both the HEAD ref and all the tag refs. However, doing\n>> both --head and either of --tags or --heads would filter out the HEAD\n>> ref.\n>> \n>> Signed-off-by: Doug Bell <madcityzen@gmail.com>\n>> ---\n> \n> I think this patch fell through the cracks, and looking at it, I am\n> somewhat torn.\n> \n> The command help for \"--head\" says \"show the HEAD reference\", which\n> may mean:\n> \n> (1) in addition to everything else the command would do if there\n>     weren't this option specified, show HEAD;\n> \n> (2) show the HEAD and nothing else; or\n> \n> (3) add HEAD to the candidates to be shown, but apply the usual\n>     filtering rule based on --heads, --tags and/or pattern\n>     arguments.\n> \n> While the last interpretation is what we have used since the\n> beginning of the command at 358ddb62 (Add \"git show-ref\" builtin\n> command, 2006-09-15), I tend to agree with you that the first\n> interpretation may make more sense, at least from the end user's\n> point of view.\n\n> \n> But at a deeper level, it makes the command somewhat inconsistent.\n> \n> What happens in the command is\n> \n> - We iterate over \"candidates to be shown\", which is usually\n>   \"everything under refs/\", but with \"--head\", HEAD is added to\n>   this set.  For each of these candidates:\n> \n>   - if one or more <pattern> parameters are given, reject the\n>     candidate ref if it does not tail-match with any of the\n>     patterns;\n> \n>   - if either \"--heads\" or \"--tags\" is given, among the ones that\n>     pass <pattern> filter, check if they:\n> \n>     - begin with \"refs/heads/\" (if \"--heads\" is given); or\n>     - begin with \"refs/tags/\" (if \"--tags\" is given).\n> \n>     and reject those that don't.\n> \n>   - show it if it is still surviving after these two tests.\n> \n> And taht is why \"git show-ref --tags master v1.3.0\" shows only the\n> v1.3.0 tag without showing the master branch, and giving \"--heads\"\n> instead of \"--tags\" yields only the master branch without the tag.\n> \n> The semantics your patch wants, by changing the definition of\n> \"--head\" from (3) to (1), is:\n> \n> - If \"--head\" is given, show HEAD no matter what.\n> \n> - Iterate over everything under refs/, and for each of them, do the\n>   same filter-and-show as we currently do (see above).\n> \n> While I think the new semantics is also understandable as the\n> current one, and personally I think it is a better behaviour than\n> the current one, it will require an update to the document to\n> highlight that \"--head\" is special-cased in a big way, to bypass all\n> the filtering that is applied to normal refs.\n> \n> A few additional observations (these are not complaints to this\n> patch and please do not take them as such):\n> \n> - The command help says \"(can be combined with heads)\" for \"--tags\"\n>   and vice versa, but does not mention their interaction with\n>   \"--head\".  This is because we take interpretation (3) above and\n>   do not treat \"--head\" as a mechanism to add to <pattern>\n>   parameter like these two.\n> \n> - The command help for \"--heads\" and \"--tags\" says \"only show\n>   heads/tags\", which technically does not contradict with \"can be\n>   combined with\" above, but a logical consequence of combining\n>   ought to be showing nothing, as a ref cannot be a head (an old\n>   nomenclature for a \"branch\") and a tag at the same time.  \n> \n> I think we should find a word better than \"only\" to use here, but I\n> am not sure what would be a good phrase to use.\n> \n\nThe reason I had initially wanted both --tags and --head was I wanted to compare HEAD against all the tags to see which one(s) I was on (if any). I was eventually pointed to `git describe`, but I ended up just using show-ref without any options and filtering the result using Perl (the entire application is in Perl, so this wasn't a big deal). Then, yeah, I figured it was confusing enough to either patch the code or the docs.\n\nFor the doc changes, I think if it's explained that by default it show-ref shows refs/{tags,heads,remotes}, it becomes easier to explain what the options will end up doing. I'll put together a second patch."},{"id":"223237","messageId":"1373680988-72804-1-git-send-email-madcityzen@gmail.com","threadId":"33982","inReplyTo":"7v38rlt88j.fsf@alter.siamese.dyndns.org","subject":"[PATCH v2] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-07-13T02:03:07Z","receivedAt":"2013-07-13T02:03:07Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"Updated the documentation to describe the new behavior.\n\nDoug Bell (1):\n  show-ref: make --head always show the HEAD ref\n\n Documentation/git-show-ref.txt | 10 ++++++----\n builtin/show-ref.c             |  8 ++++++--\n 2 files changed, 12 insertions(+), 6 deletions(-)\n\n-- \n1.7.12.4\n"},{"id":"223238","messageId":"1373680988-72804-2-git-send-email-madcityzen@gmail.com","threadId":"33982","inReplyTo":"1373680988-72804-1-git-send-email-madcityzen@gmail.com","subject":"[PATCH] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-07-13T02:03:08Z","receivedAt":"2013-07-13T02:03:08Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"The docs seem to say that doing\n\n\tgit show-ref --head --tags\n\nwould show both the HEAD ref and all the tag refs. However, doing\nboth --head and either of --tags or --heads would filter out the HEAD\nref.\n\nAlso update the documentation to describe the new behavior.\n\nSigned-off-by: Doug Bell <madcityzen@gmail.com>\n---\n Documentation/git-show-ref.txt | 10 ++++++----\n builtin/show-ref.c             |  8 ++++++--\n 2 files changed, 12 insertions(+), 6 deletions(-)\n\ndiff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt\nindex de4d352..b0a309b 100644\n--- a/Documentation/git-show-ref.txt\n+++ b/Documentation/git-show-ref.txt\n@@ -21,6 +21,8 @@ commit IDs. Results can be filtered using a pattern and tags can be\n dereferenced into object IDs. Additionally, it can be used to test whether a\n particular ref exists.\n \n+By default, shows the tags, heads, and remote refs.\n+\n The --exclude-existing form is a filter that does the inverse, it shows the\n refs from stdin that don't exist in the local repository.\n \n@@ -32,14 +34,14 @@ OPTIONS\n \n --head::\n \n-\tShow the HEAD reference.\n+\tShow the HEAD reference, even if it would normally be filtered out.\n \n --tags::\n --heads::\n \n-\tLimit to only \"refs/heads\" and \"refs/tags\", respectively.  These\n-\toptions are not mutually exclusive; when given both, references stored\n-\tin \"refs/heads\" and \"refs/tags\" are displayed.\n+\tLimit to \"refs/heads\" and \"refs/tags\", respectively.  These options\n+\tare not mutually exclusive; when given both, references stored in\n+\t\"refs/heads\" and \"refs/tags\" are displayed.\n \n -d::\n --dereference::\ndiff --git a/builtin/show-ref.c b/builtin/show-ref.c\nindex 4a0310d..4b069e7 100644\n--- a/builtin/show-ref.c\n+++ b/builtin/show-ref.c\n@@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \tconst char *hex;\n \tunsigned char peeled[20];\n \n+\tif (show_head && !strncmp(refname, \"HEAD\\0\", 5))\n+\t\tgoto match;\n+\n \tif (tags_only || heads_only) {\n \t\tint match;\n \n@@ -167,9 +170,10 @@ static const struct option show_ref_options[] = {\n \tOPT_BOOLEAN(0, \"verify\", &verify, N_(\"stricter reference checking, \"\n \t\t    \"requires exact ref path\")),\n \t{ OPTION_BOOLEAN, 'h', NULL, &show_head, NULL,\n-\t  N_(\"show the HEAD reference\"),\n+\t  N_(\"show the HEAD reference, even if it would be filtered out\"),\n \t  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },\n-\tOPT_BOOLEAN(0, \"head\", &show_head, N_(\"show the HEAD reference\")),\n+\tOPT_BOOLEAN(0, \"head\", &show_head,\n+\t  N_(\"show the HEAD reference, even if it would be filtered out\")),\n \tOPT_BOOLEAN('d', \"dereference\", &deref_tags,\n \t\t    N_(\"dereference tags into object IDs\")),\n \t{ OPTION_CALLBACK, 's', \"hash\", &abbrev, N_(\"n\"),\n-- \n1.7.12.4\n"},{"id":"223446","messageId":"7vtxjvbwyo.fsf@alter.siamese.dyndns.org","threadId":"33982","inReplyTo":"1373680988-72804-2-git-send-email-madcityzen@gmail.com","subject":"Re: [PATCH] show-ref: make --head always show the HEAD ref","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-07-15T16:37:51Z","receivedAt":"2013-07-15T16:37:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Doug Bell <madcityzen@gmail.com> writes:\n\n> diff --git a/builtin/show-ref.c b/builtin/show-ref.c\n> index 4a0310d..4b069e7 100644\n> --- a/builtin/show-ref.c\n> +++ b/builtin/show-ref.c\n> @@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo\n>  \tconst char *hex;\n>  \tunsigned char peeled[20];\n>  \n> +\tif (show_head && !strncmp(refname, \"HEAD\\0\", 5))\n> +\t\tgoto match;\n> +\n>  \tif (tags_only || heads_only) {\n>  \t\tint match;\n\nI think !strcmp(refname, \"HEAD\") is better up there.\n\nAlso we would want some basic test, which so far seems to be lacking\nfor the command.\n\nHow about this squashed in?\n\n builtin/show-ref.c   |   2 +-\n t/t1403-show-ref.txt | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 168 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/show-ref.c b/builtin/show-ref.c\nindex 497ad66..099c2a4 100644\n--- a/builtin/show-ref.c\n+++ b/builtin/show-ref.c\n@@ -31,7 +31,7 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \tconst char *hex;\n \tunsigned char peeled[20];\n \n-\tif (show_head && !strncmp(refname, \"HEAD\\0\", 5))\n+\tif (show_head && !strcmp(refname, \"HEAD\"))\n \t\tgoto match;\n \n \tif (tags_only || heads_only) {\ndiff --git a/t/t1403-show-ref.txt b/t/t1403-show-ref.txt\nnew file mode 100755\nindex 0000000..3e500ed\n--- /dev/null\n+++ b/t/t1403-show-ref.txt\n@@ -0,0 +1,167 @@\n+#!/bin/sh\n+\n+test_description='show-ref'\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\ttest_commit A &&\n+\tgit tag -f -a -m \"annotated A\" A &&\n+\tgit checkout -b side &&\n+\ttest_commit B &&\n+\tgit tag -f -a -m \"annotated B\" B &&\n+\tgit checkout master &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success 'show-ref' '\n+\techo $(git rev-parse refs/tags/A) refs/tags/A >expect &&\n+\n+\tgit show-ref A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref -q' '\n+\t>expect &&\n+\n+\tgit show-ref -q A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -q tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -q refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref -q D >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref --verify' '\n+\techo $(git rev-parse refs/tags/A) refs/tags/A >expect &&\n+\n+\tgit show-ref --verify refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref --verify A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref --verify -q' '\n+\t>expect &&\n+\n+\tgit show-ref --verify -q refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref -d' '\n+\t{\n+\t\techo $(git rev-parse refs/tags/A) refs/tags/A &&\n+\t\techo $(git rev-parse refs/tags/A^0) \"refs/tags/A^{}\"\n+\t\techo $(git rev-parse refs/tags/C) refs/tags/C\n+\t} >expect &&\n+\tgit show-ref -d A C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d tags/A tags/C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d refs/tags/A refs/tags/C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo $(git rev-parse refs/heads/master) refs/heads/master >expect &&\n+\tgit show-ref -d master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d heads/master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d refs/heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+\tgit show-ref -d --verify refs/heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref -d --verify master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref -d --verify heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+'\n+\n+test_expect_success 'show-ref --heads, --tags, --head, pattern' '\n+\tfor branch in B master side\n+\tdo\n+\t\techo $(git rev-parse refs/heads/$branch) refs/heads/$branch\n+\tdone >expect.heads &&\n+\tgit show-ref --heads >actual &&\n+\ttest_cmp expect.heads actual &&\n+\n+\tfor tag in A B C\n+\tdo\n+\t\techo $(git rev-parse refs/tags/$tag) refs/tags/$tag\n+\tdone >expect.tags &&\n+\tgit show-ref --tags >actual &&\n+\ttest_cmp expect.tags actual &&\n+\n+\tcat expect.heads expect.tags >expect &&\n+\tgit show-ref --heads --tags >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\tcat expect.heads expect.tags\n+\t} >expect &&\n+\tgit show-ref --heads --tags --head >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\techo $(git rev-parse refs/heads/B) refs/heads/B\n+\t\techo $(git rev-parse refs/tags/B) refs/tags/B\n+\t} >expect &&\n+\tgit show-ref --head B >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\techo $(git rev-parse refs/heads/B) refs/heads/B\n+\t\techo $(git rev-parse refs/tags/B) refs/tags/B\n+\t\techo $(git rev-parse refs/tags/B^0) \"refs/tags/B^{}\"\n+\t} >expect &&\n+\tgit show-ref --head -d B >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_done\n"},{"id":"223557","messageId":"1374019514-15309-1-git-send-email-madcityzen@gmail.com","threadId":"33982","inReplyTo":"7vtxjvbwyo.fsf@alter.siamese.dyndns.org","subject":"[PATCH v3] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-07-17T00:05:13Z","receivedAt":"2013-07-17T00:05:13Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"\nAdded the test that Junio wrote, just need to take some more time to\nunderstand it. Thanks for the tests!\n"},{"id":"223558","messageId":"1374019514-15309-2-git-send-email-madcityzen@gmail.com","threadId":"33982","inReplyTo":"1374019514-15309-1-git-send-email-madcityzen@gmail.com","subject":"[PATCH] show-ref: make --head always show the HEAD ref","fromName":"Doug Bell","fromEmail":"madcityzen@gmail.com","sentAt":"2013-07-17T00:05:14Z","receivedAt":"2013-07-17T00:05:14Z","isPatch":true,"sender":{"key":"madcityzen@gmail.com","avatar":"https://avatars.githubusercontent.com/u/53707?v=4"},"body":"The docs seem to say that doing\n\n\tgit show-ref --head --tags\n\nwould show both the HEAD ref and all the tag refs. However, doing\nboth --head and either of --tags or --heads would filter out the HEAD\nref.\n\nAlso update the documentation to describe the new behavior and add\ntests for the show-ref command.\n\nSigned-off-by: Doug Bell <madcityzen@gmail.com>\nTested-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-show-ref.txt |  10 ++-\n builtin/show-ref.c             |   8 +-\n t/t1403-show-ref.sh            | 167 +++++++++++++++++++++++++++++++++++++++++\n 3 files changed, 179 insertions(+), 6 deletions(-)\n create mode 100755 t/t1403-show-ref.sh\n\ndiff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt\nindex de4d352..b0a309b 100644\n--- a/Documentation/git-show-ref.txt\n+++ b/Documentation/git-show-ref.txt\n@@ -21,6 +21,8 @@ commit IDs. Results can be filtered using a pattern and tags can be\n dereferenced into object IDs. Additionally, it can be used to test whether a\n particular ref exists.\n \n+By default, shows the tags, heads, and remote refs.\n+\n The --exclude-existing form is a filter that does the inverse, it shows the\n refs from stdin that don't exist in the local repository.\n \n@@ -32,14 +34,14 @@ OPTIONS\n \n --head::\n \n-\tShow the HEAD reference.\n+\tShow the HEAD reference, even if it would normally be filtered out.\n \n --tags::\n --heads::\n \n-\tLimit to only \"refs/heads\" and \"refs/tags\", respectively.  These\n-\toptions are not mutually exclusive; when given both, references stored\n-\tin \"refs/heads\" and \"refs/tags\" are displayed.\n+\tLimit to \"refs/heads\" and \"refs/tags\", respectively.  These options\n+\tare not mutually exclusive; when given both, references stored in\n+\t\"refs/heads\" and \"refs/tags\" are displayed.\n \n -d::\n --dereference::\ndiff --git a/builtin/show-ref.c b/builtin/show-ref.c\nindex 4a0310d..87806ad 100644\n--- a/builtin/show-ref.c\n+++ b/builtin/show-ref.c\n@@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo\n \tconst char *hex;\n \tunsigned char peeled[20];\n \n+\tif (show_head && !strcmp(refname, \"HEAD\"))\n+\t\tgoto match;\n+\n \tif (tags_only || heads_only) {\n \t\tint match;\n \n@@ -167,9 +170,10 @@ static const struct option show_ref_options[] = {\n \tOPT_BOOLEAN(0, \"verify\", &verify, N_(\"stricter reference checking, \"\n \t\t    \"requires exact ref path\")),\n \t{ OPTION_BOOLEAN, 'h', NULL, &show_head, NULL,\n-\t  N_(\"show the HEAD reference\"),\n+\t  N_(\"show the HEAD reference, even if it would be filtered out\"),\n \t  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },\n-\tOPT_BOOLEAN(0, \"head\", &show_head, N_(\"show the HEAD reference\")),\n+\tOPT_BOOLEAN(0, \"head\", &show_head,\n+\t  N_(\"show the HEAD reference, even if it would be filtered out\")),\n \tOPT_BOOLEAN('d', \"dereference\", &deref_tags,\n \t\t    N_(\"dereference tags into object IDs\")),\n \t{ OPTION_CALLBACK, 's', \"hash\", &abbrev, N_(\"n\"),\ndiff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh\nnew file mode 100755\nindex 0000000..3e500ed\n--- /dev/null\n+++ b/t/t1403-show-ref.sh\n@@ -0,0 +1,167 @@\n+#!/bin/sh\n+\n+test_description='show-ref'\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\ttest_commit A &&\n+\tgit tag -f -a -m \"annotated A\" A &&\n+\tgit checkout -b side &&\n+\ttest_commit B &&\n+\tgit tag -f -a -m \"annotated B\" B &&\n+\tgit checkout master &&\n+\ttest_commit C &&\n+\tgit branch B A^0\n+'\n+\n+test_expect_success 'show-ref' '\n+\techo $(git rev-parse refs/tags/A) refs/tags/A >expect &&\n+\n+\tgit show-ref A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref -q' '\n+\t>expect &&\n+\n+\tgit show-ref -q A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -q tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -q refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref -q D >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref --verify' '\n+\techo $(git rev-parse refs/tags/A) refs/tags/A >expect &&\n+\n+\tgit show-ref --verify refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref --verify A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref --verify -q' '\n+\t>expect &&\n+\n+\tgit show-ref --verify -q refs/tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q tags/A >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref --verify -q D >actual\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'show-ref -d' '\n+\t{\n+\t\techo $(git rev-parse refs/tags/A) refs/tags/A &&\n+\t\techo $(git rev-parse refs/tags/A^0) \"refs/tags/A^{}\"\n+\t\techo $(git rev-parse refs/tags/C) refs/tags/C\n+\t} >expect &&\n+\tgit show-ref -d A C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d tags/A tags/C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d refs/tags/A refs/tags/C >actual &&\n+\ttest_cmp expect actual &&\n+\n+\techo $(git rev-parse refs/heads/master) refs/heads/master >expect &&\n+\tgit show-ref -d master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d heads/master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\tgit show-ref -d refs/heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+\tgit show-ref -d --verify refs/heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+\t>expect &&\n+\n+\ttest_must_fail git show-ref -d --verify master >actual &&\n+\ttest_cmp expect actual &&\n+\n+\ttest_must_fail git show-ref -d --verify heads/master >actual &&\n+\ttest_cmp expect actual\n+\n+'\n+\n+test_expect_success 'show-ref --heads, --tags, --head, pattern' '\n+\tfor branch in B master side\n+\tdo\n+\t\techo $(git rev-parse refs/heads/$branch) refs/heads/$branch\n+\tdone >expect.heads &&\n+\tgit show-ref --heads >actual &&\n+\ttest_cmp expect.heads actual &&\n+\n+\tfor tag in A B C\n+\tdo\n+\t\techo $(git rev-parse refs/tags/$tag) refs/tags/$tag\n+\tdone >expect.tags &&\n+\tgit show-ref --tags >actual &&\n+\ttest_cmp expect.tags actual &&\n+\n+\tcat expect.heads expect.tags >expect &&\n+\tgit show-ref --heads --tags >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\tcat expect.heads expect.tags\n+\t} >expect &&\n+\tgit show-ref --heads --tags --head >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\techo $(git rev-parse refs/heads/B) refs/heads/B\n+\t\techo $(git rev-parse refs/tags/B) refs/tags/B\n+\t} >expect &&\n+\tgit show-ref --head B >actual &&\n+\ttest_cmp expect actual &&\n+\n+\t{\n+\t\techo $(git rev-parse HEAD) HEAD &&\n+\t\techo $(git rev-parse refs/heads/B) refs/heads/B\n+\t\techo $(git rev-parse refs/tags/B) refs/tags/B\n+\t\techo $(git rev-parse refs/tags/B^0) \"refs/tags/B^{}\"\n+\t} >expect &&\n+\tgit show-ref --head -d B >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_done\n-- \n1.7.12.4\n"}]}