[PATCH] show-ref: make --head always show the HEAD ref
The docs seem to say that doing git show-ref --head --tags would show both the HEAD ref and all the tag refs. However, doing both --head and either of --tags or --heads would filter out the HEAD ref. Also update the documentation to describe the new behavior and add tests for the show-ref command. Signed-off-by: Doug Bell Tested-by: Junio C Hamano --- Documentation/git-show-ref.txt | 10 ++- builtin/show-ref.c | 8 +- t/t1403-show-ref.sh| 167 + 3 files changed, 179 insertions(+), 6 deletions(-) create mode 100755 t/t1403-show-ref.sh diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index de4d352..b0a309b 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -21,6 +21,8 @@ commit IDs. Results can be filtered using a pattern and tags can be dereferenced into object IDs. Additionally, it can be used to test whether a particular ref exists. +By default, shows the tags, heads, and remote refs. + The --exclude-existing form is a filter that does the inverse, it shows the refs from stdin that don't exist in the local repository. @@ -32,14 +34,14 @@ OPTIONS --head:: - Show the HEAD reference. + Show the HEAD reference, even if it would normally be filtered out. --tags:: --heads:: - Limit to only "refs/heads" and "refs/tags", respectively. These - options are not mutually exclusive; when given both, references stored - in "refs/heads" and "refs/tags" are displayed. + Limit to "refs/heads" and "refs/tags", respectively. These options + are not mutually exclusive; when given both, references stored in + "refs/heads" and "refs/tags" are displayed. -d:: --dereference:: diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 4a0310d..87806ad 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo const char *hex; unsigned char peeled[20]; + if (show_head && !strcmp(refname, "HEAD")) + goto match; + if (tags_only || heads_only) { int match; @@ -167,9 +170,10 @@ static const struct option show_ref_options[] = { OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), { OPTION_BOOLEAN, 'h', NULL, &show_head, NULL, - N_("show the HEAD reference"), + N_("show the HEAD reference, even if it would be filtered out"), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, - OPT_BOOLEAN(0, "head", &show_head, N_("show the HEAD reference")), + OPT_BOOLEAN(0, "head", &show_head, + N_("show the HEAD reference, even if it would be filtered out")), OPT_BOOLEAN('d', "dereference", &deref_tags, N_("dereference tags into object IDs")), { OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"), diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh new file mode 100755 index 000..3e500ed --- /dev/null +++ b/t/t1403-show-ref.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +test_description='show-ref' +. ./test-lib.sh + +test_expect_success setup ' + test_commit A && + git tag -f -a -m "annotated A" A && + git checkout -b side && + test_commit B && + git tag -f -a -m "annotated B" B && + git checkout master && + test_commit C && + git branch B A^0 +' + +test_expect_success 'show-ref' ' + echo $(git rev-parse refs/tags/A) refs/tags/A >expect && + + git show-ref A >actual && + test_cmp expect actual && + + git show-ref tags/A >actual && + test_cmp expect actual && + + git show-ref refs/tags/A >actual && + test_cmp expect actual && + + >expect && + + test_must_fail git show-ref D >actual + test_cmp expect actual +' + +test_expect_success 'show-ref -q' ' + >expect && + + git show-ref -q A >actual && + test_cmp expect actual && + + git show-ref -q tags/A >actual && + test_cmp expect actual && + + git show-ref -q refs/tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref -q D >actual && + test_cmp expect actual +' + +test_expect_success 'show-ref --verify' ' + echo $(git rev-parse refs/tags/A) refs/tags/A >expect && + + git show-ref --verify refs/tags/A >actual && + test_cmp expect actual && + + >expect && + + test_must_fail git show-ref --verify A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify D >actual + test_cmp expect actual +' + +test_expect_success 'show-ref --verify -q' ' + >expect && + + git show-ref --verify -q refs/tags/A >actual && + test_cmp expect actual && +
Re: [PATCH] show-ref: make --head always show the HEAD ref
Doug Bell writes: > diff --git a/builtin/show-ref.c b/builtin/show-ref.c > index 4a0310d..4b069e7 100644 > --- a/builtin/show-ref.c > +++ b/builtin/show-ref.c > @@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned > char *sha1, int flag, vo > const char *hex; > unsigned char peeled[20]; > > + if (show_head && !strncmp(refname, "HEAD\0", 5)) > + goto match; > + > if (tags_only || heads_only) { > int match; I think !strcmp(refname, "HEAD") is better up there. Also we would want some basic test, which so far seems to be lacking for the command. How about this squashed in? builtin/show-ref.c | 2 +- t/t1403-show-ref.txt | 167 +++ 2 files changed, 168 insertions(+), 1 deletion(-) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 497ad66..099c2a4 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -31,7 +31,7 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo const char *hex; unsigned char peeled[20]; - if (show_head && !strncmp(refname, "HEAD\0", 5)) + if (show_head && !strcmp(refname, "HEAD")) goto match; if (tags_only || heads_only) { diff --git a/t/t1403-show-ref.txt b/t/t1403-show-ref.txt new file mode 100755 index 000..3e500ed --- /dev/null +++ b/t/t1403-show-ref.txt @@ -0,0 +1,167 @@ +#!/bin/sh + +test_description='show-ref' +. ./test-lib.sh + +test_expect_success setup ' + test_commit A && + git tag -f -a -m "annotated A" A && + git checkout -b side && + test_commit B && + git tag -f -a -m "annotated B" B && + git checkout master && + test_commit C && + git branch B A^0 +' + +test_expect_success 'show-ref' ' + echo $(git rev-parse refs/tags/A) refs/tags/A >expect && + + git show-ref A >actual && + test_cmp expect actual && + + git show-ref tags/A >actual && + test_cmp expect actual && + + git show-ref refs/tags/A >actual && + test_cmp expect actual && + + >expect && + + test_must_fail git show-ref D >actual + test_cmp expect actual +' + +test_expect_success 'show-ref -q' ' + >expect && + + git show-ref -q A >actual && + test_cmp expect actual && + + git show-ref -q tags/A >actual && + test_cmp expect actual && + + git show-ref -q refs/tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref -q D >actual && + test_cmp expect actual +' + +test_expect_success 'show-ref --verify' ' + echo $(git rev-parse refs/tags/A) refs/tags/A >expect && + + git show-ref --verify refs/tags/A >actual && + test_cmp expect actual && + + >expect && + + test_must_fail git show-ref --verify A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify D >actual + test_cmp expect actual +' + +test_expect_success 'show-ref --verify -q' ' + >expect && + + git show-ref --verify -q refs/tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify -q A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify -q tags/A >actual && + test_cmp expect actual && + + test_must_fail git show-ref --verify -q D >actual + test_cmp expect actual +' + +test_expect_success 'show-ref -d' ' + { + echo $(git rev-parse refs/tags/A) refs/tags/A && + echo $(git rev-parse refs/tags/A^0) "refs/tags/A^{}" + echo $(git rev-parse refs/tags/C) refs/tags/C + } >expect && + git show-ref -d A C >actual && + test_cmp expect actual && + + git show-ref -d tags/A tags/C >actual && + test_cmp expect actual && + + git show-ref -d refs/tags/A refs/tags/C >actual && + test_cmp expect actual && + + echo $(git rev-parse refs/heads/master) refs/heads/master >expect && + git show-ref -d master >actual && + test_cmp expect actual && + + git show-ref -d heads/master >actual && + test_cmp expect actual && + + git show-ref -d refs/heads/master >actual && + test_cmp expect actual + + git show-ref -d --verify refs/heads/master >actual && + test_cmp expect actual + + >expect && + + test_must_fail git show-ref -d --verify master >actual && + test_cmp expect actual && + + test_must_fail git show-ref -d --verify heads/master >actual && + test_cmp expect actual + +' + +test_expect_success 'show-ref --heads, --tags, --head, pattern' ' + for branch in B master side + do + echo $(git rev-parse refs/heads/$branch) refs/heads/$branch + done >expect.heads && + git show-ref --heads >actual && +
Re: [PATCH] show-ref: make --head always show the HEAD ref
On Jul 11, 2013, at 10:41 AM, Junio C Hamano wrote: > Doug Bell writes: > >> The docs seem to say that doing >> >> git show-ref --head --tags >> >> would show both the HEAD ref and all the tag refs. However, doing >> both --head and either of --tags or --heads would filter out the HEAD >> ref. >> >> Signed-off-by: Doug Bell >> --- > > I think this patch fell through the cracks, and looking at it, I am > somewhat torn. > > The command help for "--head" says "show the HEAD reference", which > may mean: > > (1) in addition to everything else the command would do if there > weren't this option specified, show HEAD; > > (2) show the HEAD and nothing else; or > > (3) add HEAD to the candidates to be shown, but apply the usual > filtering rule based on --heads, --tags and/or pattern > arguments. > > While the last interpretation is what we have used since the > beginning of the command at 358ddb62 (Add "git show-ref" builtin > command, 2006-09-15), I tend to agree with you that the first > interpretation may make more sense, at least from the end user's > point of view. > > But at a deeper level, it makes the command somewhat inconsistent. > > What happens in the command is > > - We iterate over "candidates to be shown", which is usually > "everything under refs/", but with "--head", HEAD is added to > this set. For each of these candidates: > > - if one or more parameters are given, reject the > candidate ref if it does not tail-match with any of the > patterns; > > - if either "--heads" or "--tags" is given, among the ones that > pass filter, check if they: > > - begin with "refs/heads/" (if "--heads" is given); or > - begin with "refs/tags/" (if "--tags" is given). > > and reject those that don't. > > - show it if it is still surviving after these two tests. > > And taht is why "git show-ref --tags master v1.3.0" shows only the > v1.3.0 tag without showing the master branch, and giving "--heads" > instead of "--tags" yields only the master branch without the tag. > > The semantics your patch wants, by changing the definition of > "--head" from (3) to (1), is: > > - If "--head" is given, show HEAD no matter what. > > - Iterate over everything under refs/, and for each of them, do the > same filter-and-show as we currently do (see above). > > While I think the new semantics is also understandable as the > current one, and personally I think it is a better behaviour than > the current one, it will require an update to the document to > highlight that "--head" is special-cased in a big way, to bypass all > the filtering that is applied to normal refs. > > A few additional observations (these are not complaints to this > patch and please do not take them as such): > > - The command help says "(can be combined with heads)" for "--tags" > and vice versa, but does not mention their interaction with > "--head". This is because we take interpretation (3) above and > do not treat "--head" as a mechanism to add to > parameter like these two. > > - The command help for "--heads" and "--tags" says "only show > heads/tags", which technically does not contradict with "can be > combined with" above, but a logical consequence of combining > ought to be showing nothing, as a ref cannot be a head (an old > nomenclature for a "branch") and a tag at the same time. > > I think we should find a word better than "only" to use here, but I > am not sure what would be a good phrase to use. > The 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. For 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.-- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] show-ref: make --head always show the HEAD ref
The docs seem to say that doing git show-ref --head --tags would show both the HEAD ref and all the tag refs. However, doing both --head and either of --tags or --heads would filter out the HEAD ref. Also update the documentation to describe the new behavior. Signed-off-by: Doug Bell --- Documentation/git-show-ref.txt | 10 ++ builtin/show-ref.c | 8 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Documentation/git-show-ref.txt b/Documentation/git-show-ref.txt index de4d352..b0a309b 100644 --- a/Documentation/git-show-ref.txt +++ b/Documentation/git-show-ref.txt @@ -21,6 +21,8 @@ commit IDs. Results can be filtered using a pattern and tags can be dereferenced into object IDs. Additionally, it can be used to test whether a particular ref exists. +By default, shows the tags, heads, and remote refs. + The --exclude-existing form is a filter that does the inverse, it shows the refs from stdin that don't exist in the local repository. @@ -32,14 +34,14 @@ OPTIONS --head:: - Show the HEAD reference. + Show the HEAD reference, even if it would normally be filtered out. --tags:: --heads:: - Limit to only "refs/heads" and "refs/tags", respectively. These - options are not mutually exclusive; when given both, references stored - in "refs/heads" and "refs/tags" are displayed. + Limit to "refs/heads" and "refs/tags", respectively. These options + are not mutually exclusive; when given both, references stored in + "refs/heads" and "refs/tags" are displayed. -d:: --dereference:: diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 4a0310d..4b069e7 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo const char *hex; unsigned char peeled[20]; + if (show_head && !strncmp(refname, "HEAD\0", 5)) + goto match; + if (tags_only || heads_only) { int match; @@ -167,9 +170,10 @@ static const struct option show_ref_options[] = { OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, " "requires exact ref path")), { OPTION_BOOLEAN, 'h', NULL, &show_head, NULL, - N_("show the HEAD reference"), + N_("show the HEAD reference, even if it would be filtered out"), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, - OPT_BOOLEAN(0, "head", &show_head, N_("show the HEAD reference")), + OPT_BOOLEAN(0, "head", &show_head, + N_("show the HEAD reference, even if it would be filtered out")), OPT_BOOLEAN('d', "dereference", &deref_tags, N_("dereference tags into object IDs")), { OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"), -- 1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] show-ref: make --head always show the HEAD ref
Doug Bell writes: > The docs seem to say that doing > > git show-ref --head --tags > > would show both the HEAD ref and all the tag refs. However, doing > both --head and either of --tags or --heads would filter out the HEAD > ref. > > Signed-off-by: Doug Bell > --- I think this patch fell through the cracks, and looking at it, I am somewhat torn. The command help for "--head" says "show the HEAD reference", which may mean: (1) in addition to everything else the command would do if there weren't this option specified, show HEAD; (2) show the HEAD and nothing else; or (3) add HEAD to the candidates to be shown, but apply the usual filtering rule based on --heads, --tags and/or pattern arguments. While the last interpretation is what we have used since the beginning of the command at 358ddb62 (Add "git show-ref" builtin command, 2006-09-15), I tend to agree with you that the first interpretation may make more sense, at least from the end user's point of view. But at a deeper level, it makes the command somewhat inconsistent. What happens in the command is - We iterate over "candidates to be shown", which is usually "everything under refs/", but with "--head", HEAD is added to this set. For each of these candidates: - if one or more parameters are given, reject the candidate ref if it does not tail-match with any of the patterns; - if either "--heads" or "--tags" is given, among the ones that pass filter, check if they: - begin with "refs/heads/" (if "--heads" is given); or - begin with "refs/tags/" (if "--tags" is given). and reject those that don't. - show it if it is still surviving after these two tests. And taht is why "git show-ref --tags master v1.3.0" shows only the v1.3.0 tag without showing the master branch, and giving "--heads" instead of "--tags" yields only the master branch without the tag. The semantics your patch wants, by changing the definition of "--head" from (3) to (1), is: - If "--head" is given, show HEAD no matter what. - Iterate over everything under refs/, and for each of them, do the same filter-and-show as we currently do (see above). While I think the new semantics is also understandable as the current one, and personally I think it is a better behaviour than the current one, it will require an update to the document to highlight that "--head" is special-cased in a big way, to bypass all the filtering that is applied to normal refs. A few additional observations (these are not complaints to this patch and please do not take them as such): - The command help says "(can be combined with heads)" for "--tags" and vice versa, but does not mention their interaction with "--head". This is because we take interpretation (3) above and do not treat "--head" as a mechanism to add to parameter like these two. - The command help for "--heads" and "--tags" says "only show heads/tags", which technically does not contradict with "can be combined with" above, but a logical consequence of combining ought to be showing nothing, as a ref cannot be a head (an old nomenclature for a "branch") and a tag at the same time. I think we should find a word better than "only" to use here, but I am not sure what would be a good phrase to use. -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] show-ref: make --head always show the HEAD ref
The docs seem to say that doing git show-ref --head --tags would show both the HEAD ref and all the tag refs. However, doing both --head and either of --tags or --heads would filter out the HEAD ref. Signed-off-by: Doug Bell --- I think this patch could be done better if I refactor the show_ref() sub a bit... This commit passes the current test suite. Where would I put new tests for this? I can't find an existing show-ref test to append to. I would be happy to write show-ref tests if there aren't any already. builtin/show-ref.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 8d9b76a..5954e9b 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo const char *hex; unsigned char peeled[20]; + if (show_head && !strncmp(refname, "HEAD\0", 5)) + goto match; + if (tags_only || heads_only) { int match; -- 1.8.3.101.g727a46b.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html