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. [jc: Doug did proofread the tests, but it was done by me and bugs in it are mine]. Signed-off-by: Doug Bell <madcityzen@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Doug Bell committed Jul 16, 2013 at 19:05 UTC 3f3d0cea61aba6ac2fef16736ef55e04bb735e02
3 files changed +179 -6
Documentation/git-show-ref.txt
+6 -4
@@ -21,6 +21,8 @@ commit IDs. Results can be filtered using a pattern and tags can be
21 dereferenced into object IDs. Additionally, it can be used to test whether a
22 particular ref exists.
23
24 +By default, shows the tags, heads, and remote refs.
25 +
26 The --exclude-existing form is a filter that does the inverse, it shows the
27 refs from stdin that don't exist in the local repository.
28
@@ -32,14 +34,14 @@ OPTIONS
34
35 --head::
36
35 - Show the HEAD reference.
37 + Show the HEAD reference, even if it would normally be filtered out.
38
39 --tags::
40 --heads::
41
40 - Limit to only "refs/heads" and "refs/tags", respectively. These
41 - options are not mutually exclusive; when given both, references stored
42 - in "refs/heads" and "refs/tags" are displayed.
42 + Limit to "refs/heads" and "refs/tags", respectively. These options
43 + are not mutually exclusive; when given both, references stored in
44 + "refs/heads" and "refs/tags" are displayed.
45
46 -d::
47 --dereference::
builtin/show-ref.c
+6 -2
@@ -31,6 +31,9 @@ static int show_ref(const char *refname, const unsigned char *sha1, int flag, vo
31 const char *hex;
32 unsigned char peeled[20];
33
34 + if (show_head && !strcmp(refname, "HEAD"))
35 + goto match;
36 +
37 if (tags_only || heads_only) {
38 int match;
39
@@ -167,9 +170,10 @@ static const struct option show_ref_options[] = {
170 OPT_BOOLEAN(0, "verify", &verify, N_("stricter reference checking, "
171 "requires exact ref path")),
172 { OPTION_BOOLEAN, 'h', NULL, &show_head, NULL,
170 - N_("show the HEAD reference"),
173 + N_("show the HEAD reference, even if it would be filtered out"),
174 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
172 - OPT_BOOLEAN(0, "head", &show_head, N_("show the HEAD reference")),
175 + OPT_BOOLEAN(0, "head", &show_head,
176 + N_("show the HEAD reference, even if it would be filtered out")),
177 OPT_BOOLEAN('d', "dereference", &deref_tags,
178 N_("dereference tags into object IDs")),
179 { OPTION_CALLBACK, 's', "hash", &abbrev, N_("n"),
t/t1403-show-ref.sh new
+167
@@ -0,0 +1,167 @@
1 +#!/bin/sh
2 +
3 +test_description='show-ref'
4 +. ./test-lib.sh
5 +
6 +test_expect_success setup '
7 + test_commit A &&
8 + git tag -f -a -m "annotated A" A &&
9 + git checkout -b side &&
10 + test_commit B &&
11 + git tag -f -a -m "annotated B" B &&
12 + git checkout master &&
13 + test_commit C &&
14 + git branch B A^0
15 +'
16 +
17 +test_expect_success 'show-ref' '
18 + echo $(git rev-parse refs/tags/A) refs/tags/A >expect &&
19 +
20 + git show-ref A >actual &&
21 + test_cmp expect actual &&
22 +
23 + git show-ref tags/A >actual &&
24 + test_cmp expect actual &&
25 +
26 + git show-ref refs/tags/A >actual &&
27 + test_cmp expect actual &&
28 +
29 + >expect &&
30 +
31 + test_must_fail git show-ref D >actual
32 + test_cmp expect actual
33 +'
34 +
35 +test_expect_success 'show-ref -q' '
36 + >expect &&
37 +
38 + git show-ref -q A >actual &&
39 + test_cmp expect actual &&
40 +
41 + git show-ref -q tags/A >actual &&
42 + test_cmp expect actual &&
43 +
44 + git show-ref -q refs/tags/A >actual &&
45 + test_cmp expect actual &&
46 +
47 + test_must_fail git show-ref -q D >actual &&
48 + test_cmp expect actual
49 +'
50 +
51 +test_expect_success 'show-ref --verify' '
52 + echo $(git rev-parse refs/tags/A) refs/tags/A >expect &&
53 +
54 + git show-ref --verify refs/tags/A >actual &&
55 + test_cmp expect actual &&
56 +
57 + >expect &&
58 +
59 + test_must_fail git show-ref --verify A >actual &&
60 + test_cmp expect actual &&
61 +
62 + test_must_fail git show-ref --verify tags/A >actual &&
63 + test_cmp expect actual &&
64 +
65 + test_must_fail git show-ref --verify D >actual
66 + test_cmp expect actual
67 +'
68 +
69 +test_expect_success 'show-ref --verify -q' '
70 + >expect &&
71 +
72 + git show-ref --verify -q refs/tags/A >actual &&
73 + test_cmp expect actual &&
74 +
75 + test_must_fail git show-ref --verify -q A >actual &&
76 + test_cmp expect actual &&
77 +
78 + test_must_fail git show-ref --verify -q tags/A >actual &&
79 + test_cmp expect actual &&
80 +
81 + test_must_fail git show-ref --verify -q D >actual
82 + test_cmp expect actual
83 +'
84 +
85 +test_expect_success 'show-ref -d' '
86 + {
87 + echo $(git rev-parse refs/tags/A) refs/tags/A &&
88 + echo $(git rev-parse refs/tags/A^0) "refs/tags/A^{}"
89 + echo $(git rev-parse refs/tags/C) refs/tags/C
90 + } >expect &&
91 + git show-ref -d A C >actual &&
92 + test_cmp expect actual &&
93 +
94 + git show-ref -d tags/A tags/C >actual &&
95 + test_cmp expect actual &&
96 +
97 + git show-ref -d refs/tags/A refs/tags/C >actual &&
98 + test_cmp expect actual &&
99 +
100 + echo $(git rev-parse refs/heads/master) refs/heads/master >expect &&
101 + git show-ref -d master >actual &&
102 + test_cmp expect actual &&
103 +
104 + git show-ref -d heads/master >actual &&
105 + test_cmp expect actual &&
106 +
107 + git show-ref -d refs/heads/master >actual &&
108 + test_cmp expect actual
109 +
110 + git show-ref -d --verify refs/heads/master >actual &&
111 + test_cmp expect actual
112 +
113 + >expect &&
114 +
115 + test_must_fail git show-ref -d --verify master >actual &&
116 + test_cmp expect actual &&
117 +
118 + test_must_fail git show-ref -d --verify heads/master >actual &&
119 + test_cmp expect actual
120 +
121 +'
122 +
123 +test_expect_success 'show-ref --heads, --tags, --head, pattern' '
124 + for branch in B master side
125 + do
126 + echo $(git rev-parse refs/heads/$branch) refs/heads/$branch
127 + done >expect.heads &&
128 + git show-ref --heads >actual &&
129 + test_cmp expect.heads actual &&
130 +
131 + for tag in A B C
132 + do
133 + echo $(git rev-parse refs/tags/$tag) refs/tags/$tag
134 + done >expect.tags &&
135 + git show-ref --tags >actual &&
136 + test_cmp expect.tags actual &&
137 +
138 + cat expect.heads expect.tags >expect &&
139 + git show-ref --heads --tags >actual &&
140 + test_cmp expect actual &&
141 +
142 + {
143 + echo $(git rev-parse HEAD) HEAD &&
144 + cat expect.heads expect.tags
145 + } >expect &&
146 + git show-ref --heads --tags --head >actual &&
147 + test_cmp expect actual &&
148 +
149 + {
150 + echo $(git rev-parse HEAD) HEAD &&
151 + echo $(git rev-parse refs/heads/B) refs/heads/B
152 + echo $(git rev-parse refs/tags/B) refs/tags/B
153 + } >expect &&
154 + git show-ref --head B >actual &&
155 + test_cmp expect actual &&
156 +
157 + {
158 + echo $(git rev-parse HEAD) HEAD &&
159 + echo $(git rev-parse refs/heads/B) refs/heads/B
160 + echo $(git rev-parse refs/tags/B) refs/tags/B
161 + echo $(git rev-parse refs/tags/B^0) "refs/tags/B^{}"
162 + } >expect &&
163 + git show-ref --head -d B >actual &&
164 + test_cmp expect actual
165 +'
166 +
167 +test_done