config: unify code paths to get global config paths
[git] / t / t1430-bad-ref-name.sh
1 #!/bin/sh
2
3 test_description='Test handling of ref names that check-ref-format rejects'
4 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
5 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
6
7 . ./test-lib.sh
8
9 test_expect_success setup '
10         test_commit one &&
11         test_commit two
12 '
13
14 test_expect_success 'fast-import: fail on invalid branch name ".badbranchname"' '
15         test_when_finished "rm -f .git/objects/pack_* .git/objects/index_*" &&
16         cat >input <<-INPUT_END &&
17                 commit .badbranchname
18                 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
19                 data <<COMMIT
20                 corrupt
21                 COMMIT
22
23                 from refs/heads/main
24
25         INPUT_END
26         test_must_fail git fast-import <input
27 '
28
29 test_expect_success 'fast-import: fail on invalid branch name "bad[branch]name"' '
30         test_when_finished "rm -f .git/objects/pack_* .git/objects/index_*" &&
31         cat >input <<-INPUT_END &&
32                 commit bad[branch]name
33                 committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
34                 data <<COMMIT
35                 corrupt
36                 COMMIT
37
38                 from refs/heads/main
39
40         INPUT_END
41         test_must_fail git fast-import <input
42 '
43
44 test_expect_success 'git branch shows badly named ref as warning' '
45         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
46         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
47         git branch >output 2>error &&
48         test_i18ngrep -e "ignoring ref with broken name refs/heads/broken\.\.\.ref" error &&
49         ! grep -e "broken\.\.\.ref" output
50 '
51
52 test_expect_success 'branch -d can delete badly named ref' '
53         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
54         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
55         git branch -d broken...ref &&
56         git branch >output 2>error &&
57         ! grep -e "broken\.\.\.ref" error &&
58         ! grep -e "broken\.\.\.ref" output
59 '
60
61 test_expect_success 'branch -D can delete badly named ref' '
62         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
63         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
64         git branch -D broken...ref &&
65         git branch >output 2>error &&
66         ! grep -e "broken\.\.\.ref" error &&
67         ! grep -e "broken\.\.\.ref" output
68 '
69
70 test_expect_success 'branch -D cannot delete non-ref in .git dir' '
71         echo precious >.git/my-private-file &&
72         echo precious >expect &&
73         test_must_fail git branch -D ../../my-private-file &&
74         test_cmp expect .git/my-private-file
75 '
76
77 test_expect_success 'branch -D cannot delete ref in .git dir' '
78         git rev-parse HEAD >.git/my-private-file &&
79         git rev-parse HEAD >expect &&
80         git branch foo/legit &&
81         test_must_fail git branch -D foo////./././../../../my-private-file &&
82         test_cmp expect .git/my-private-file
83 '
84
85 test_expect_success 'branch -D cannot delete absolute path' '
86         git branch -f extra &&
87         test_must_fail git branch -D "$(pwd)/.git/refs/heads/extra" &&
88         test_cmp_rev HEAD extra
89 '
90
91 test_expect_success 'git branch cannot create a badly named ref' '
92         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
93         test_must_fail git branch broken...ref &&
94         git branch >output 2>error &&
95         ! grep -e "broken\.\.\.ref" error &&
96         ! grep -e "broken\.\.\.ref" output
97 '
98
99 test_expect_success 'branch -m cannot rename to a bad ref name' '
100         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
101         test_might_fail git branch -D goodref &&
102         git branch goodref &&
103         test_must_fail git branch -m goodref broken...ref &&
104         test_cmp_rev main goodref &&
105         git branch >output 2>error &&
106         ! grep -e "broken\.\.\.ref" error &&
107         ! grep -e "broken\.\.\.ref" output
108 '
109
110 test_expect_failure 'branch -m can rename from a bad ref name' '
111         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
112         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
113         git branch -m broken...ref renamed &&
114         test_cmp_rev main renamed &&
115         git branch >output 2>error &&
116         ! grep -e "broken\.\.\.ref" error &&
117         ! grep -e "broken\.\.\.ref" output
118 '
119
120 test_expect_success 'push cannot create a badly named ref' '
121         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
122         test_must_fail git push "file://$(pwd)" HEAD:refs/heads/broken...ref &&
123         git branch >output 2>error &&
124         ! grep -e "broken\.\.\.ref" error &&
125         ! grep -e "broken\.\.\.ref" output
126 '
127
128 test_expect_failure 'push --mirror can delete badly named ref' '
129         top=$(pwd) &&
130         git init src &&
131         git init dest &&
132
133         (
134                 cd src &&
135                 test_commit one
136         ) &&
137         (
138                 cd dest &&
139                 test_commit two &&
140                 git checkout --detach &&
141                 cp .git/refs/heads/main .git/refs/heads/broken...ref
142         ) &&
143         git -C src push --mirror "file://$top/dest" &&
144         git -C dest branch >output 2>error &&
145         ! grep -e "broken\.\.\.ref" error &&
146         ! grep -e "broken\.\.\.ref" output
147 '
148
149 test_expect_success 'rev-parse skips symref pointing to broken name' '
150         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
151         git branch shadow one &&
152         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
153         printf "ref: refs/heads/broken...ref\n" >.git/refs/tags/shadow &&
154         test_when_finished "rm -f .git/refs/tags/shadow" &&
155         git rev-parse --verify one >expect &&
156         git rev-parse --verify shadow >actual 2>err &&
157         test_cmp expect actual &&
158         test_i18ngrep "ignoring dangling symref refs/tags/shadow" err
159 '
160
161 test_expect_success 'for-each-ref emits warnings for broken names' '
162         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
163         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
164         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
165         test_when_finished "rm -f .git/refs/heads/badname" &&
166         printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
167         test_when_finished "rm -f .git/refs/heads/broken...symref" &&
168         git for-each-ref >output 2>error &&
169         ! grep -e "broken\.\.\.ref" output &&
170         ! grep -e "badname" output &&
171         ! grep -e "broken\.\.\.symref" output &&
172         test_i18ngrep "ignoring ref with broken name refs/heads/broken\.\.\.ref" error &&
173         test_i18ngrep "ignoring broken ref refs/heads/badname" error &&
174         test_i18ngrep "ignoring ref with broken name refs/heads/broken\.\.\.symref" error
175 '
176
177 test_expect_success 'update-ref -d can delete broken name' '
178         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
179         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
180         git update-ref -d refs/heads/broken...ref >output 2>error &&
181         test_must_be_empty output &&
182         test_must_be_empty error &&
183         git branch >output 2>error &&
184         ! grep -e "broken\.\.\.ref" error &&
185         ! grep -e "broken\.\.\.ref" output
186 '
187
188 test_expect_success 'branch -d can delete broken name' '
189         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
190         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
191         git branch -d broken...ref >output 2>error &&
192         test_i18ngrep "Deleted branch broken...ref (was broken)" output &&
193         test_must_be_empty error &&
194         git branch >output 2>error &&
195         ! grep -e "broken\.\.\.ref" error &&
196         ! grep -e "broken\.\.\.ref" output
197 '
198
199 test_expect_success 'update-ref --no-deref -d can delete symref to broken name' '
200         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
201         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
202         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
203         test_when_finished "rm -f .git/refs/heads/badname" &&
204         git update-ref --no-deref -d refs/heads/badname >output 2>error &&
205         test_path_is_missing .git/refs/heads/badname &&
206         test_must_be_empty output &&
207         test_must_be_empty error
208 '
209
210 test_expect_success 'branch -d can delete symref to broken name' '
211         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
212         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
213         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
214         test_when_finished "rm -f .git/refs/heads/badname" &&
215         git branch -d badname >output 2>error &&
216         test_path_is_missing .git/refs/heads/badname &&
217         test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output &&
218         test_must_be_empty error
219 '
220
221 test_expect_success 'update-ref --no-deref -d can delete dangling symref to broken name' '
222         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
223         test_when_finished "rm -f .git/refs/heads/badname" &&
224         git update-ref --no-deref -d refs/heads/badname >output 2>error &&
225         test_path_is_missing .git/refs/heads/badname &&
226         test_must_be_empty output &&
227         test_must_be_empty error
228 '
229
230 test_expect_success 'branch -d can delete dangling symref to broken name' '
231         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
232         test_when_finished "rm -f .git/refs/heads/badname" &&
233         git branch -d badname >output 2>error &&
234         test_path_is_missing .git/refs/heads/badname &&
235         test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output &&
236         test_must_be_empty error
237 '
238
239 test_expect_success 'update-ref -d can delete broken name through symref' '
240         cp .git/refs/heads/main .git/refs/heads/broken...ref &&
241         test_when_finished "rm -f .git/refs/heads/broken...ref" &&
242         printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname &&
243         test_when_finished "rm -f .git/refs/heads/badname" &&
244         git update-ref -d refs/heads/badname >output 2>error &&
245         test_path_is_missing .git/refs/heads/broken...ref &&
246         test_must_be_empty output &&
247         test_must_be_empty error
248 '
249
250 test_expect_success 'update-ref --no-deref -d can delete symref with broken name' '
251         printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
252         test_when_finished "rm -f .git/refs/heads/broken...symref" &&
253         git update-ref --no-deref -d refs/heads/broken...symref >output 2>error &&
254         test_path_is_missing .git/refs/heads/broken...symref &&
255         test_must_be_empty output &&
256         test_must_be_empty error
257 '
258
259 test_expect_success 'branch -d can delete symref with broken name' '
260         printf "ref: refs/heads/main\n" >.git/refs/heads/broken...symref &&
261         test_when_finished "rm -f .git/refs/heads/broken...symref" &&
262         git branch -d broken...symref >output 2>error &&
263         test_path_is_missing .git/refs/heads/broken...symref &&
264         test_i18ngrep "Deleted branch broken...symref (was refs/heads/main)" output &&
265         test_must_be_empty error
266 '
267
268 test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' '
269         printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref &&
270         test_when_finished "rm -f .git/refs/heads/broken...symref" &&
271         git update-ref --no-deref -d refs/heads/broken...symref >output 2>error &&
272         test_path_is_missing .git/refs/heads/broken...symref &&
273         test_must_be_empty output &&
274         test_must_be_empty error
275 '
276
277 test_expect_success 'branch -d can delete dangling symref with broken name' '
278         printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref &&
279         test_when_finished "rm -f .git/refs/heads/broken...symref" &&
280         git branch -d broken...symref >output 2>error &&
281         test_path_is_missing .git/refs/heads/broken...symref &&
282         test_i18ngrep "Deleted branch broken...symref (was refs/heads/idonotexist)" output &&
283         test_must_be_empty error
284 '
285
286 test_expect_success 'update-ref -d cannot delete non-ref in .git dir' '
287         echo precious >.git/my-private-file &&
288         echo precious >expect &&
289         test_must_fail git update-ref -d my-private-file >output 2>error &&
290         test_must_be_empty output &&
291         test_i18ngrep -e "refusing to update ref with bad name" error &&
292         test_cmp expect .git/my-private-file
293 '
294
295 test_expect_success 'update-ref -d cannot delete absolute path' '
296         git branch -f extra &&
297         test_must_fail git update-ref -d "$(pwd)/.git/refs/heads/extra" &&
298         test_cmp_rev HEAD extra
299 '
300
301 test_expect_success 'update-ref --stdin fails create with bad ref name' '
302         echo "create ~a refs/heads/main" >stdin &&
303         test_must_fail git update-ref --stdin <stdin 2>err &&
304         grep "fatal: invalid ref format: ~a" err
305 '
306
307 test_expect_success 'update-ref --stdin fails update with bad ref name' '
308         echo "update ~a refs/heads/main" >stdin &&
309         test_must_fail git update-ref --stdin <stdin 2>err &&
310         grep "fatal: invalid ref format: ~a" err
311 '
312
313 test_expect_success 'update-ref --stdin fails delete with bad ref name' '
314         echo "delete ~a refs/heads/main" >stdin &&
315         test_must_fail git update-ref --stdin <stdin 2>err &&
316         grep "fatal: invalid ref format: ~a" err
317 '
318
319 test_expect_success 'update-ref --stdin -z fails create with bad ref name' '
320         printf "%s\0" "create ~a " refs/heads/main >stdin &&
321         test_must_fail git update-ref -z --stdin <stdin 2>err &&
322         grep "fatal: invalid ref format: ~a " err
323 '
324
325 test_expect_success 'update-ref --stdin -z fails update with bad ref name' '
326         printf "%s\0" "update ~a" refs/heads/main "" >stdin &&
327         test_must_fail git update-ref -z --stdin <stdin 2>err &&
328         grep "fatal: invalid ref format: ~a" err
329 '
330
331 test_expect_success 'update-ref --stdin -z fails delete with bad ref name' '
332         printf "%s\0" "delete ~a" refs/heads/main >stdin &&
333         test_must_fail git update-ref -z --stdin <stdin 2>err &&
334         grep "fatal: invalid ref format: ~a" err
335 '
336
337 test_expect_success 'branch rejects HEAD as a branch name' '
338         test_must_fail git branch HEAD HEAD^ &&
339         test_must_fail git show-ref refs/heads/HEAD
340 '
341
342 test_expect_success 'checkout -b rejects HEAD as a branch name' '
343         test_must_fail git checkout -B HEAD HEAD^ &&
344         test_must_fail git show-ref refs/heads/HEAD
345 '
346
347 test_expect_success 'update-ref can operate on refs/heads/HEAD' '
348         git update-ref refs/heads/HEAD HEAD^ &&
349         git show-ref refs/heads/HEAD &&
350         git update-ref -d refs/heads/HEAD &&
351         test_must_fail git show-ref refs/heads/HEAD
352 '
353
354 test_expect_success 'branch -d can remove refs/heads/HEAD' '
355         git update-ref refs/heads/HEAD HEAD^ &&
356         git branch -d HEAD &&
357         test_must_fail git show-ref refs/heads/HEAD
358 '
359
360 test_expect_success 'branch -m can rename refs/heads/HEAD' '
361         git update-ref refs/heads/HEAD HEAD^ &&
362         git branch -m HEAD tail &&
363         test_must_fail git show-ref refs/heads/HEAD &&
364         git show-ref refs/heads/tail
365 '
366
367 test_expect_success 'branch -d can remove refs/heads/-dash' '
368         git update-ref refs/heads/-dash HEAD^ &&
369         git branch -d -- -dash &&
370         test_must_fail git show-ref refs/heads/-dash
371 '
372
373 test_expect_success 'branch -m can rename refs/heads/-dash' '
374         git update-ref refs/heads/-dash HEAD^ &&
375         git branch -m -- -dash dash &&
376         test_must_fail git show-ref refs/heads/-dash &&
377         git show-ref refs/heads/dash
378 '
379
380 test_done