Raw
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Johannes Schindelin
4 #
5
6 test_description='Test git config in different settings'
7
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 . ./test-lib.sh
12 . "$TEST_DIRECTORY"/lib-terminal.sh
13
14 # test-lib.sh may have added global config (e.g. safe.bareRepository)
15 # that would appear in "git config --list" output and break tests
16 # that expect exact config contents.
17 test_expect_success 'remove global config from test-lib.sh' '
18 test_might_fail git config --global --unset-all safe.bareRepository
19 '
20
21 for mode in legacy subcommands
22 do
23
24 case "$mode" in
25 legacy)
26 mode_prefix="--"
27 mode_get=""
28 mode_get_all="--get-all"
29 mode_get_regexp="--get-regexp"
30 mode_set=""
31 mode_replace_all="--replace-all"
32 mode_unset="--unset"
33 mode_unset_all="--unset-all"
34 ;;
35 subcommands)
36 mode_prefix=""
37 mode_get="get"
38 mode_get_all="get --all"
39 mode_get_regexp="get --regexp --all --show-names"
40 mode_set="set"
41 mode_replace_all="set --all"
42 mode_unset="unset"
43 mode_unset_all="unset --all"
44 ;;
45 *)
46 BUG "unknown mode $mode";;
47 esac
48
49 test_expect_success 'setup whitespace config' '
50 sed -e "s/^|//" \
51 -e "s/[$]$//" \
52 -e "s/X/ /g" >.git/config <<-\EOF
53 [section]
54 | solid = rock
55 | sparse = big XX blue
56 | sparseAndTail = big XX blue $
57 | sparseAndTailQuoted = "big XX blue "
58 | sparseAndBiggerTail = big XX blue X X
59 | sparseAndBiggerTailQuoted = "big XX blue X X"
60 | sparseAndBiggerTailQuotedPlus = "big XX blue X X"X $
61 | headAndTail = Xbig blue $
62 | headAndTailQuoted = "Xbig blue "
63 | headAndTailQuotedPlus = "Xbig blue " $
64 | annotated = big blueX# to be discarded
65 | annotatedQuoted = "big blue"X# to be discarded
66 EOF
67 '
68
69 test_expect_success 'no internal whitespace' '
70 echo "rock" >expect &&
71 git config --get section.solid >actual &&
72 test_cmp expect actual
73 '
74
75 test_expect_success 'internal whitespace' '
76 echo "big QQ blue" | q_to_tab >expect &&
77 git config --get section.sparse >actual &&
78 test_cmp expect actual
79 '
80
81 test_expect_success 'internal and trailing whitespace' '
82 echo "big QQ blue" | q_to_tab >expect &&
83 git config --get section.sparseAndTail >actual &&
84 test_cmp expect actual
85 '
86
87 test_expect_success 'internal and trailing whitespace, all quoted' '
88 echo "big QQ blue " | q_to_tab >expect &&
89 git config --get section.sparseAndTailQuoted >actual &&
90 test_cmp expect actual
91 '
92
93 test_expect_success 'internal and more trailing whitespace' '
94 echo "big QQ blue" | q_to_tab >expect &&
95 git config --get section.sparseAndBiggerTail >actual &&
96 test_cmp expect actual
97 '
98
99 test_expect_success 'internal and more trailing whitespace, all quoted' '
100 echo "big QQ blue Q Q" | q_to_tab >expect &&
101 git config --get section.sparseAndBiggerTailQuoted >actual &&
102 test_cmp expect actual
103 '
104
105 test_expect_success 'internal and more trailing whitespace, not all quoted' '
106 echo "big QQ blue Q Q" | q_to_tab >expect &&
107 git config --get section.sparseAndBiggerTailQuotedPlus >actual &&
108 test_cmp expect actual
109 '
110
111 test_expect_success 'leading and trailing whitespace' '
112 echo "big blue" >expect &&
113 git config --get section.headAndTail >actual &&
114 test_cmp expect actual
115 '
116
117 test_expect_success 'leading and trailing whitespace, all quoted' '
118 echo "Qbig blue " | q_to_tab >expect &&
119 git config --get section.headAndTailQuoted >actual &&
120 test_cmp expect actual
121 '
122
123 test_expect_success 'leading and trailing whitespace, not all quoted' '
124 echo "Qbig blue " | q_to_tab >expect &&
125 git config --get section.headAndTailQuotedPlus >actual &&
126 test_cmp expect actual
127 '
128
129 test_expect_success 'inline comment' '
130 echo "big blue" >expect &&
131 git config --get section.annotated >actual &&
132 test_cmp expect actual
133 '
134
135 test_expect_success 'inline comment, quoted' '
136 echo "big blue" >expect &&
137 git config --get section.annotatedQuoted >actual &&
138 test_cmp expect actual
139 '
140
141 test_expect_success 'clear default config' '
142 rm -f .git/config
143 '
144
145 test_expect_success 'initial' '
146 cat >expect <<\EOF &&
147 [section]
148 penguin = little blue
149 EOF
150 git config ${mode_set} section.penguin "little blue" &&
151 test_cmp expect .git/config
152 '
153
154 test_expect_success 'mixed case' '
155 cat >expect <<\EOF &&
156 [section]
157 penguin = little blue
158 Movie = BadPhysics
159 EOF
160 git config ${mode_set} Section.Movie BadPhysics &&
161 test_cmp expect .git/config
162 '
163
164 test_expect_success 'similar section' '
165 cat >expect <<\EOF &&
166 [section]
167 penguin = little blue
168 Movie = BadPhysics
169 [Sections]
170 WhatEver = Second
171 EOF
172 git config ${mode_set} Sections.WhatEver Second &&
173 test_cmp expect .git/config
174 '
175
176 test_expect_success 'uppercase section' '
177 cat >expect <<\EOF &&
178 [section]
179 penguin = little blue
180 Movie = BadPhysics
181 UPPERCASE = true
182 [Sections]
183 WhatEver = Second
184 EOF
185 git config ${mode_set} SECTION.UPPERCASE true &&
186 test_cmp expect .git/config
187 '
188
189 test_expect_success 'replace with non-match' '
190 git config section.penguin kingpin !blue
191 '
192
193 test_expect_success 'replace with non-match (actually matching)' '
194 git config section.penguin "very blue" !kingpin
195 '
196
197 test_expect_success 'append comments' '
198 cat >expect <<\EOF &&
199 [section]
200 Movie = BadPhysics
201 UPPERCASE = true
202 penguin = gentoo # Pygoscelis papua
203 disposition = peckish # find fish
204 foo = bar #abc
205 spsp = value # and comment
206 htsp = value # and comment
207 [Sections]
208 WhatEver = Second
209 EOF
210 git config --replace-all --comment="Pygoscelis papua" section.penguin gentoo &&
211 git config ${mode_set} --comment="find fish" section.disposition peckish &&
212 git config ${mode_set} --comment="#abc" section.foo bar &&
213
214 git config --comment="and comment" section.spsp value &&
215 git config --comment=" # and comment" section.htsp value &&
216
217 test_cmp expect .git/config
218 '
219
220 test_expect_success 'Prohibited LF in comment' '
221 test_must_fail git config ${mode_set} --comment="a${LF}b" section.k v
222 '
223
224 test_expect_success 'non-match result' '
225 test_cmp expect .git/config
226 '
227
228 test_expect_success 'find mixed-case key by canonical name' '
229 test_cmp_config Second sections.whatever
230 '
231
232 test_expect_success 'find mixed-case key by non-canonical name' '
233 test_cmp_config Second SeCtIoNs.WhAtEvEr
234 '
235
236 test_expect_success 'subsections are not canonicalized by git-config' '
237 cat >>.git/config <<-\EOF &&
238 [section.SubSection]
239 key = one
240 [section "SubSection"]
241 key = two
242 EOF
243 test_cmp_config one section.subsection.key &&
244 test_cmp_config two section.SubSection.key
245 '
246
247 test_missing_key () {
248 local key="$1" &&
249 local title="$2" &&
250 test_expect_success "value for $title is not printed" '
251 test_must_fail git config "$key" >out 2>err &&
252 test_must_be_empty out &&
253 test_must_be_empty err
254 '
255 }
256
257 test_missing_key 'missingsection.missingkey' 'missing section and missing key'
258 test_missing_key 'missingsection.penguin' 'missing section and existing key'
259 test_missing_key 'section.missingkey' 'existing section and missing key'
260 test_missing_key 'section.MissingSubSection.missingkey' 'missing subsection and missing key'
261 test_missing_key 'section.SubSection.missingkey' 'existing subsection and missing key'
262 test_missing_key 'section.MissingSubSection.key' 'missing subsection and existing key'
263
264 cat > .git/config <<\EOF
265 [alpha]
266 bar = foo
267 [beta]
268 baz = multiple \
269 lines
270 foo = bar
271 EOF
272
273 test_expect_success 'unset with cont. lines' '
274 git config ${mode_unset} beta.baz
275 '
276
277 test_expect_success 'unset with cont. lines is correct' '
278 cat >expect <<-\EOF &&
279 [alpha]
280 bar = foo
281 [beta]
282 foo = bar
283 EOF
284 test_cmp expect .git/config
285 '
286
287 cat > .git/config << EOF
288 [beta] ; silly comment # another comment
289 noIndent= sillyValue ; 'nother silly comment
290
291 # empty line
292 ; comment
293 haha ="beta" # last silly comment
294 haha = hello
295 haha = bello
296 [nextSection] noNewline = ouch
297 EOF
298
299 cp .git/config .git/config2
300
301 test_expect_success 'multiple unset' '
302 git config ${mode_unset_all} beta.haha
303 '
304
305 test_expect_success 'multiple unset is correct' '
306 cat >expect <<EOF &&
307 [beta] ; silly comment # another comment
308 noIndent= sillyValue ; ${SQ}nother silly comment
309
310 # empty line
311 ; comment
312 [nextSection] noNewline = ouch
313 EOF
314 test_cmp expect .git/config
315 '
316
317 cp .git/config2 .git/config
318
319 test_expect_success '--replace-all missing value' '
320 test_must_fail git config ${mode_replace_all} beta.haha &&
321 test_cmp .git/config2 .git/config
322 '
323
324 rm .git/config2
325
326 test_expect_success '--replace-all' '
327 git config ${mode_replace_all} beta.haha gamma
328 '
329
330 test_expect_success 'all replaced' '
331 cat >expect <<EOF &&
332 [beta] ; silly comment # another comment
333 noIndent= sillyValue ; ${SQ}nother silly comment
334
335 # empty line
336 ; comment
337 haha = gamma
338 [nextSection] noNewline = ouch
339 EOF
340 test_cmp expect .git/config
341 '
342
343 test_expect_success 'really mean test' '
344 cat >expect <<EOF &&
345 [beta] ; silly comment # another comment
346 noIndent= sillyValue ; ${SQ}nother silly comment
347
348 # empty line
349 ; comment
350 haha = alpha
351 [nextSection] noNewline = ouch
352 EOF
353 git config ${mode_set} beta.haha alpha &&
354 test_cmp expect .git/config
355 '
356
357 test_expect_success 'really really mean test' '
358 cat >expect <<EOF &&
359 [beta] ; silly comment # another comment
360 noIndent= sillyValue ; ${SQ}nother silly comment
361
362 # empty line
363 ; comment
364 haha = alpha
365 [nextSection]
366 nonewline = wow
367 EOF
368 git config ${mode_set} nextsection.nonewline wow &&
369 test_cmp expect .git/config
370 '
371
372 test_expect_success 'get value' '
373 test_cmp_config alpha beta.haha
374 '
375
376 test_expect_success 'unset' '
377 cat >expect <<EOF &&
378 [beta] ; silly comment # another comment
379 noIndent= sillyValue ; ${SQ}nother silly comment
380
381 # empty line
382 ; comment
383 [nextSection]
384 nonewline = wow
385 EOF
386 git config ${mode_unset} beta.haha &&
387 test_cmp expect .git/config
388 '
389
390 test_expect_success 'multivar' '
391 cat >expect <<EOF &&
392 [beta] ; silly comment # another comment
393 noIndent= sillyValue ; ${SQ}nother silly comment
394
395 # empty line
396 ; comment
397 [nextSection]
398 nonewline = wow
399 NoNewLine = wow2 for me
400 EOF
401 git config nextsection.NoNewLine "wow2 for me" "for me$" &&
402 test_cmp expect .git/config
403 '
404
405 test_expect_success 'non-match' '
406 git config --get nextsection.nonewline !for
407 '
408
409 test_expect_success 'non-match value' '
410 test_cmp_config wow --get nextsection.nonewline !for
411 '
412
413 test_expect_success 'multi-valued get returns final one' '
414 test_cmp_config "wow2 for me" --get nextsection.nonewline
415 '
416
417 test_expect_success 'multi-valued get-all returns all' '
418 cat >expect <<-\EOF &&
419 wow
420 wow2 for me
421 EOF
422 git config ${mode_get_all} nextsection.nonewline >actual &&
423 test_cmp expect actual
424 '
425
426 test_expect_success 'multivar replace' '
427 cat >expect <<EOF &&
428 [beta] ; silly comment # another comment
429 noIndent= sillyValue ; ${SQ}nother silly comment
430
431 # empty line
432 ; comment
433 [nextSection]
434 nonewline = wow3
435 NoNewLine = wow2 for me
436 EOF
437 git config nextsection.nonewline "wow3" "wow$" &&
438 test_cmp expect .git/config
439 '
440
441 test_expect_success 'ambiguous unset' '
442 test_must_fail git config ${mode_unset} nextsection.nonewline
443 '
444
445 test_expect_success 'invalid unset' '
446 test_must_fail git config ${mode_unset} somesection.nonewline
447 '
448
449 test_expect_success 'multivar unset' '
450 cat >expect <<EOF &&
451 [beta] ; silly comment # another comment
452 noIndent= sillyValue ; ${SQ}nother silly comment
453
454 # empty line
455 ; comment
456 [nextSection]
457 NoNewLine = wow2 for me
458 EOF
459 case "$mode" in
460 legacy)
461 git config --unset nextsection.nonewline "wow3$";;
462 subcommands)
463 git config unset --value="wow3$" nextsection.nonewline;;
464 esac &&
465 test_cmp expect .git/config
466 '
467
468 test_expect_success 'invalid key' '
469 test_must_fail git config inval.2key blabla
470 '
471
472 test_expect_success 'set with 1 arg of "key=value": valid key suggests split form' '
473 test_must_fail git config set pull.rebase=false 2>err &&
474 test_grep "missing value to set to the variable .pull\\.rebase=false." err &&
475 test_grep "did you mean .git config set pull\\.rebase false." err
476 '
477
478 test_expect_success 'set with 1 arg of "key=value": implicit form suggests split form' '
479 test_must_fail git config pull.rebase=false 2>err &&
480 test_grep "missing value to set to the variable .pull\\.rebase=false." err &&
481 test_grep "did you mean .git config set pull\\.rebase false." err
482 '
483
484 test_expect_success 'set with 1 arg of "key=value": invalid key does not suggest split form' '
485 test_must_fail git config set foo=bar 2>err &&
486 test_grep "missing value to set to a variable with an invalid name .foo=bar." err &&
487 test_grep ! "did you mean" err
488 '
489
490 test_expect_success 'set with 1 arg: variable name starting with digit is invalid' '
491 test_must_fail git config set foo.1bar=baz 2>err &&
492 test_grep "missing value to set to a variable with an invalid name .foo\\.1bar=baz." err &&
493 test_grep ! "did you mean" err
494 '
495
496 test_expect_success 'set with 1 arg: digit-led section name is valid' '
497 test_must_fail git config set 1foo.bar=baz 2>err &&
498 test_grep "missing value to set to the variable .1foo\\.bar=baz." err &&
499 test_grep "did you mean .git config set 1foo\\.bar baz." err
500 '
501
502 test_expect_success 'set with 1 arg: subsection plus invalid variable name' '
503 test_must_fail git config set foo.some.b_r=baz 2>err &&
504 test_grep "missing value to set to a variable with an invalid name .foo\\.some\\.b_r=baz." err &&
505 test_grep ! "did you mean" err
506 '
507
508 test_expect_success 'set with 1 arg of valid key reports missing value' '
509 test_must_fail git config set pull.rebase 2>err &&
510 test_grep "missing value to set to the variable .pull\\.rebase." err &&
511 test_grep ! "did you mean" err
512 '
513
514 test_expect_success 'set with 2 args including "=" in invalid key does not suggest' '
515 test_must_fail git config set pull.rebase=false true 2>err &&
516 test_grep "invalid key: pull\\.rebase=false" err &&
517 test_grep ! "did you mean" err
518 '
519
520 test_expect_success '"=" inside subsection is valid' '
521 test_when_finished "rm -f subsection.cfg" &&
522 git config set -f subsection.cfg foo.bar=baz.boo qux &&
523 echo qux >expect &&
524 git config get -f subsection.cfg foo.bar=baz.boo >actual &&
525 test_cmp expect actual
526 '
527
528 test_expect_success 'correct key' '
529 git config 123456.a123 987
530 '
531
532 test_expect_success 'hierarchical section' '
533 git config Version.1.2.3eX.Alpha beta
534 '
535
536 test_expect_success 'hierarchical section value' '
537 cat >expect <<EOF &&
538 [beta] ; silly comment # another comment
539 noIndent= sillyValue ; ${SQ}nother silly comment
540
541 # empty line
542 ; comment
543 [nextSection]
544 NoNewLine = wow2 for me
545 [123456]
546 a123 = 987
547 [Version "1.2.3eX"]
548 Alpha = beta
549 EOF
550 test_cmp expect .git/config
551 '
552
553 test_expect_success 'working --list' '
554 cat >expect <<-\EOF &&
555 beta.noindent=sillyValue
556 nextsection.nonewline=wow2 for me
557 123456.a123=987
558 version.1.2.3eX.alpha=beta
559 EOF
560 git config ${mode_prefix}list > output &&
561 test_cmp expect output
562 '
563
564 test_expect_success '--list without repo produces empty output' '
565 git --git-dir=nonexistent config ${mode_prefix}list >output &&
566 test_must_be_empty output
567 '
568
569 test_expect_success '--name-only --list' '
570 cat >expect <<-\EOF &&
571 beta.noindent
572 nextsection.nonewline
573 123456.a123
574 version.1.2.3eX.alpha
575 EOF
576 git config ${mode_prefix}list --name-only >output &&
577 test_cmp expect output
578 '
579
580 test_expect_success '--get-regexp' '
581 cat >expect <<-\EOF &&
582 beta.noindent sillyValue
583 nextsection.nonewline wow2 for me
584 EOF
585 git config ${mode_get_regexp} in >output &&
586 test_cmp expect output
587 '
588
589 test_expect_success '--name-only --get-regexp' '
590 cat >expect <<-\EOF &&
591 beta.noindent
592 nextsection.nonewline
593 EOF
594 git config ${mode_get_regexp} --name-only in >output &&
595 test_cmp expect output
596 '
597
598 test_expect_success '--add' '
599 cat >expect <<-\EOF &&
600 wow2 for me
601 wow4 for you
602 EOF
603 git config --add nextsection.nonewline "wow4 for you" &&
604 git config ${mode_get_all} nextsection.nonewline > output &&
605 test_cmp expect output
606 '
607
608 cat > .git/config << EOF
609 [novalue]
610 variable
611 [emptyvalue]
612 variable =
613 EOF
614
615 test_expect_success 'get variable with no value' '
616 git config --get novalue.variable ^$
617 '
618
619 test_expect_success 'get variable with empty value' '
620 git config --get emptyvalue.variable ^$
621 '
622
623 test_expect_success 'get-regexp variable with no value' '
624 echo novalue.variable >expect &&
625 git config ${mode_get_regexp} novalue > output &&
626 test_cmp expect output
627 '
628
629 test_expect_success 'get-regexp --bool variable with no value' '
630 echo "novalue.variable true" >expect &&
631 git config ${mode_get_regexp} --bool novalue > output &&
632 test_cmp expect output
633 '
634
635 test_expect_success 'get-regexp variable with empty value' '
636 echo "emptyvalue.variable " >expect &&
637 git config ${mode_get_regexp} emptyvalue > output &&
638 test_cmp expect output
639 '
640
641 test_expect_success 'get bool variable with no value' '
642 echo true >expect &&
643 git config --bool novalue.variable > output &&
644 test_cmp expect output
645 '
646
647 test_expect_success 'get bool variable with empty value' '
648 echo false >expect &&
649 git config --bool emptyvalue.variable > output &&
650 test_cmp expect output
651 '
652
653 test_expect_success 'no arguments, but no crash' '
654 test_must_fail git config >output 2>&1 &&
655 echo "error: no action specified" >expect &&
656 test_cmp expect output
657 '
658
659 cat > .git/config << EOF
660 [a.b]
661 c = d
662 EOF
663
664 test_expect_success 'new section is partial match of another' '
665 cat >expect <<\EOF &&
666 [a.b]
667 c = d
668 [a]
669 x = y
670 EOF
671 git config a.x y &&
672 test_cmp expect .git/config
673 '
674
675 test_expect_success 'new variable inserts into proper section' '
676 cat >expect <<\EOF &&
677 [a.b]
678 c = d
679 [a]
680 x = y
681 b = c
682 [b]
683 x = y
684 EOF
685 git config b.x y &&
686 git config a.b c &&
687 test_cmp expect .git/config
688 '
689
690 test_expect_success 'alternative --file (non-existing file should fail)' '
691 test_must_fail git config --file non-existing-config -l &&
692 test_must_fail git config --file non-existing-config test.xyzzy
693 '
694
695 cat > other-config << EOF
696 [ein]
697 bahn = strasse
698 EOF
699
700 test_expect_success 'alternative GIT_CONFIG' '
701 cat >expect <<-\EOF &&
702 ein.bahn=strasse
703 EOF
704 GIT_CONFIG=other-config git config ${mode_prefix}list >output &&
705 test_cmp expect output
706 '
707
708 test_expect_success 'alternative GIT_CONFIG (--file)' '
709 git config ${mode_prefix}list --file other-config >output &&
710 test_cmp expect output
711 '
712
713 test_expect_success 'alternative GIT_CONFIG (--file=-)' '
714 git config ${mode_prefix}list --file - <other-config >output &&
715 test_cmp expect output
716 '
717
718 test_expect_success 'setting a value in stdin is an error' '
719 test_must_fail git config --file - some.value foo
720 '
721
722 test_expect_success 'editing stdin is an error' '
723 test_must_fail git config ${mode_prefix}edit --file -
724 '
725
726 test_expect_success 'refer config from subdirectory' '
727 test_when_finished "rm -r x" &&
728 mkdir x &&
729 test_cmp_config -C x strasse --file=../other-config --get ein.bahn
730 '
731
732 test_expect_success '--set in alternative file' '
733 cat >expect <<\EOF &&
734 [ein]
735 bahn = strasse
736 [anwohner]
737 park = ausweis
738 EOF
739 git config --file=other-config anwohner.park ausweis &&
740 test_cmp expect other-config
741 '
742
743 cat > .git/config << EOF
744 # Hallo
745 #Bello
746 [branch "eins"]
747 x = 1
748 [branch.eins]
749 y = 1
750 [branch "1 234 blabl/a"]
751 weird
752 EOF
753
754 test_expect_success 'rename section' '
755 git config ${mode_prefix}rename-section branch.eins branch.zwei
756 '
757
758 cat > expect << EOF
759 # Hallo
760 #Bello
761 [branch "zwei"]
762 x = 1
763 [branch "zwei"]
764 y = 1
765 [branch "1 234 blabl/a"]
766 weird
767 EOF
768
769 test_expect_success 'rename succeeded' '
770 test_cmp expect .git/config
771 '
772
773 test_expect_success 'rename non-existing section' '
774 test_must_fail git config ${mode_prefix}rename-section \
775 branch."world domination" branch.drei
776 '
777
778 test_expect_success 'rename succeeded' '
779 test_cmp expect .git/config
780 '
781
782 test_expect_success 'rename another section' '
783 git config ${mode_prefix}rename-section branch."1 234 blabl/a" branch.drei
784 '
785
786 test_expect_success 'rename succeeded' '
787 cat >expect <<\EOF &&
788 # Hallo
789 #Bello
790 [branch "zwei"]
791 x = 1
792 [branch "zwei"]
793 y = 1
794 [branch "drei"]
795 weird
796 EOF
797 test_cmp expect .git/config
798 '
799
800 cat >> .git/config << EOF
801 [branch "vier"] z = 1
802 EOF
803
804 test_expect_success 'rename a section with a var on the same line' '
805 git config ${mode_prefix}rename-section branch.vier branch.zwei
806 '
807
808 test_expect_success 'rename succeeded' '
809 cat >expect <<\EOF &&
810 # Hallo
811 #Bello
812 [branch "zwei"]
813 x = 1
814 [branch "zwei"]
815 y = 1
816 [branch "drei"]
817 weird
818 [branch "zwei"]
819 z = 1
820 EOF
821 test_cmp expect .git/config
822 '
823
824 test_expect_success 'renaming empty section name is rejected' '
825 test_must_fail git config ${mode_prefix}rename-section branch.zwei ""
826 '
827
828 test_expect_success 'renaming to bogus section is rejected' '
829 test_must_fail git config ${mode_prefix}rename-section branch.zwei "bogus name"
830 '
831
832 test_expect_success 'renaming a section with a long line' '
833 {
834 printf "[b]\\n" &&
835 printf " c = d %1024s [a] e = f\\n" " " &&
836 printf "[a] g = h\\n"
837 } >y &&
838 git config ${mode_prefix}rename-section -f y a xyz &&
839 test_must_fail git config -f y b.e
840 '
841
842 test_expect_success 'renaming an embedded section with a long line' '
843 {
844 printf "[b]\\n" &&
845 printf " c = d %1024s [a] [foo] e = f\\n" " " &&
846 printf "[a] g = h\\n"
847 } >y &&
848 git config ${mode_prefix}rename-section -f y a xyz &&
849 test_must_fail git config -f y foo.e
850 '
851
852 test_expect_success 'renaming a section with an overly-long line' '
853 {
854 printf "[b]\\n" &&
855 printf " c = d %525000s e" " " &&
856 printf "[a] g = h\\n"
857 } >y &&
858 test_must_fail git config ${mode_prefix}rename-section -f y a xyz 2>err &&
859 test_grep "refusing to work with overly long line in .y. on line 2" err
860 '
861
862 cat >> .git/config << EOF
863 [branch "zwei"] a = 1 [branch "vier"]
864 EOF
865
866 test_expect_success 'remove section' '
867 git config ${mode_prefix}remove-section branch.zwei
868 '
869
870 test_expect_success 'section was removed properly' '
871 cat >expect <<\EOF &&
872 # Hallo
873 #Bello
874 [branch "drei"]
875 weird
876 EOF
877 test_cmp expect .git/config
878 '
879
880 test_expect_success 'section ending' '
881 cat >expect <<\EOF &&
882 [gitcvs]
883 enabled = true
884 dbname = %Ggitcvs2.%a.%m.sqlite
885 [gitcvs "ext"]
886 dbname = %Ggitcvs1.%a.%m.sqlite
887 EOF
888 rm -f .git/config &&
889 git config ${mode_set} gitcvs.enabled true &&
890 git config ${mode_set} gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
891 git config ${mode_set} gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&
892 test_cmp expect .git/config
893 '
894
895 test_expect_success numbers '
896 git config ${mode_set} kilo.gram 1k &&
897 git config ${mode_set} mega.ton 1m &&
898 echo 1024 >expect &&
899 echo 1048576 >>expect &&
900 git config --int --get kilo.gram >actual &&
901 git config --int --get mega.ton >>actual &&
902 test_cmp expect actual
903 '
904
905 test_expect_success '--int is at least 64 bits' '
906 git config ${mode_set} giga.watts 121g &&
907 echo >expect &&
908 test_cmp_config 129922760704 --int --get giga.watts
909 '
910
911 test_expect_success 'invalid unit' '
912 git config ${mode_set} aninvalid.unit "1auto" &&
913 test_cmp_config 1auto aninvalid.unit &&
914 test_must_fail git config --int --get aninvalid.unit 2>actual &&
915 test_grep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
916 '
917
918 test_expect_success 'invalid unit boolean' '
919 git config ${mode_set} commit.gpgsign "1true" &&
920 test_cmp_config 1true commit.gpgsign &&
921 test_must_fail git config --bool --get commit.gpgsign 2>actual &&
922 test_grep "bad boolean config value .1true. for .commit.gpgsign." actual
923 '
924
925 test_expect_success 'line number is reported correctly' '
926 printf "[bool]\n\tvar\n" >invalid &&
927 test_must_fail git config -f invalid --path bool.var 2>actual &&
928 test_grep "line 2" actual
929 '
930
931 test_expect_success 'invalid stdin config' '
932 echo "[broken" | test_must_fail git config ${mode_prefix}list --file - >output 2>&1 &&
933 test_grep "bad config line 1 in standard input" output
934 '
935
936 test_expect_success bool '
937 cat >expect <<-\EOF &&
938 true
939 false
940 true
941 false
942 true
943 false
944 true
945 false
946 EOF
947 git config ${mode_set} bool.true1 01 &&
948 git config ${mode_set} bool.true2 -1 &&
949 git config ${mode_set} bool.true3 YeS &&
950 git config ${mode_set} bool.true4 true &&
951 git config ${mode_set} bool.false1 000 &&
952 git config ${mode_set} bool.false2 "" &&
953 git config ${mode_set} bool.false3 nO &&
954 git config ${mode_set} bool.false4 FALSE &&
955 rm -f result &&
956 for i in 1 2 3 4
957 do
958 git config --bool --get bool.true$i >>result &&
959 git config --bool --get bool.false$i >>result || return 1
960 done &&
961 test_cmp expect result
962 '
963
964 test_expect_success 'invalid bool (--get)' '
965 git config ${mode_set} bool.nobool foobar &&
966 test_must_fail git config --bool --get bool.nobool
967 '
968
969 test_expect_success 'invalid bool (set)' '
970 test_must_fail git config --bool bool.nobool foobar
971 '
972
973 test_expect_success 'set --bool' '
974 cat >expect <<\EOF &&
975 [bool]
976 true1 = true
977 true2 = true
978 true3 = true
979 true4 = true
980 false1 = false
981 false2 = false
982 false3 = false
983 false4 = false
984 EOF
985 rm -f .git/config &&
986 git config --bool bool.true1 01 &&
987 git config --bool bool.true2 -1 &&
988 git config --bool bool.true3 YeS &&
989 git config --bool bool.true4 true &&
990 git config --bool bool.false1 000 &&
991 git config --bool bool.false2 "" &&
992 git config --bool bool.false3 nO &&
993 git config --bool bool.false4 FALSE &&
994 test_cmp expect .git/config'
995
996 test_expect_success 'set --int' '
997 cat >expect <<\EOF &&
998 [int]
999 val1 = 1
1000 val2 = -1
1001 val3 = 5242880
1002 EOF
1003 rm -f .git/config &&
1004 git config --int int.val1 01 &&
1005 git config --int int.val2 -1 &&
1006 git config --int int.val3 5m &&
1007 test_cmp expect .git/config
1008 '
1009
1010 test_expect_success 'get --bool-or-int' '
1011 cat >.git/config <<-\EOF &&
1012 [bool]
1013 true1
1014 true2 = true
1015 false = false
1016 [int]
1017 int1 = 0
1018 int2 = 1
1019 int3 = -1
1020 EOF
1021 cat >expect <<-\EOF &&
1022 true
1023 true
1024 false
1025 0
1026 1
1027 -1
1028 EOF
1029 {
1030 git config --bool-or-int bool.true1 &&
1031 git config --bool-or-int bool.true2 &&
1032 git config --bool-or-int bool.false &&
1033 git config --bool-or-int int.int1 &&
1034 git config --bool-or-int int.int2 &&
1035 git config --bool-or-int int.int3
1036 } >actual &&
1037 test_cmp expect actual
1038 '
1039
1040 test_expect_success 'set --bool-or-int' '
1041 cat >expect <<\EOF &&
1042 [bool]
1043 true1 = true
1044 false1 = false
1045 true2 = true
1046 false2 = false
1047 [int]
1048 int1 = 0
1049 int2 = 1
1050 int3 = -1
1051 EOF
1052 rm -f .git/config &&
1053 git config --bool-or-int bool.true1 true &&
1054 git config --bool-or-int bool.false1 false &&
1055 git config --bool-or-int bool.true2 yes &&
1056 git config --bool-or-int bool.false2 no &&
1057 git config --bool-or-int int.int1 0 &&
1058 git config --bool-or-int int.int2 1 &&
1059 git config --bool-or-int int.int3 -1 &&
1060 test_cmp expect .git/config
1061 '
1062
1063 test_expect_success !MINGW 'set --path' '
1064 cat >expect <<\EOF &&
1065 [path]
1066 home = ~/
1067 normal = /dev/null
1068 trailingtilde = foo~
1069 EOF
1070 rm -f .git/config &&
1071 git config --path path.home "~/" &&
1072 git config --path path.normal "/dev/null" &&
1073 git config --path path.trailingtilde "foo~" &&
1074 test_cmp expect .git/config
1075 '
1076
1077 if test_have_prereq !MINGW && test "${HOME+set}"
1078 then
1079 test_set_prereq HOMEVAR
1080 fi
1081
1082 test_expect_success HOMEVAR 'get --path' '
1083 cat >expect <<-EOF &&
1084 $HOME/
1085 /dev/null
1086 foo~
1087 EOF
1088 git config --get --path path.home > result &&
1089 git config --get --path path.normal >> result &&
1090 git config --get --path path.trailingtilde >> result &&
1091 test_cmp expect result
1092 '
1093
1094 test_expect_success !MINGW 'get --path copes with unset $HOME' '
1095 cat >expect <<-\EOF &&
1096 /dev/null
1097 foo~
1098 EOF
1099 (
1100 sane_unset HOME &&
1101 test_must_fail git config --get --path path.home \
1102 >result 2>msg &&
1103 git config --get --path path.normal >>result &&
1104 git config --get --path path.trailingtilde >>result
1105 ) &&
1106 test_grep "[Ff]ailed to expand.*~/" msg &&
1107 test_cmp expect result
1108 '
1109
1110 test_expect_success 'get --path barfs on boolean variable' '
1111 echo "[path]bool" >.git/config &&
1112 test_must_fail git config --get --path path.bool
1113 '
1114
1115 test_expect_success 'get --expiry-date' '
1116 rel="3.weeks.5.days.00:00" &&
1117 rel_out="$rel ->" &&
1118 cat >.git/config <<-\EOF &&
1119 [date]
1120 valid1 = "3.weeks.5.days 00:00"
1121 valid2 = "Fri Jun 4 15:46:55 2010"
1122 valid3 = "2017/11/11 11:11:11PM"
1123 valid4 = "2017/11/10 09:08:07 PM"
1124 valid5 = "never"
1125 invalid1 = "abc"
1126 EOF
1127 cat >expect <<-EOF &&
1128 $(test-tool date timestamp $rel)
1129 1275666415
1130 1510441871
1131 1510348087
1132 0
1133 EOF
1134 : "work around heredoc parsing bug fixed in dash 0.5.7 (in ec2c84d)" &&
1135 {
1136 echo "$rel_out $(git config --expiry-date date.valid1)" &&
1137 git config --expiry-date date.valid2 &&
1138 git config --expiry-date date.valid3 &&
1139 git config --expiry-date date.valid4 &&
1140 git config --expiry-date date.valid5
1141 } >actual &&
1142 test_cmp expect actual &&
1143 test_must_fail git config --expiry-date date.invalid1
1144 '
1145
1146 test_expect_success 'get --type=color' '
1147 rm .git/config &&
1148 git config ${mode_set} foo.color "red" &&
1149 git config --get --type=color foo.color >actual.raw &&
1150 git config get --type=color foo.color >actual-subcommand.raw &&
1151 test_cmp actual.raw actual-subcommand.raw &&
1152 test_decode_color <actual.raw >actual &&
1153 echo "<RED>" >expect &&
1154 test_cmp expect actual
1155 '
1156
1157 test_expect_success 'get --type=color with default value only' '
1158 git config --get-color "" "red" >actual.raw &&
1159 test_decode_color <actual.raw >actual &&
1160 echo "<RED>" >expect &&
1161 test_cmp expect actual &&
1162 git config get --type=color --default="red" "" >actual-subcommand.raw &&
1163 test_cmp actual.raw actual-subcommand.raw
1164 '
1165
1166 test_expect_success TTY 'get --type=color does not use a pager' '
1167 test_config core.pager "echo foobar" &&
1168 test_terminal git config get --type=color --default="red" "" >actual.raw &&
1169 test_decode_color <actual.raw >actual &&
1170 echo "<RED>" >expect &&
1171 test_cmp expect actual
1172 '
1173
1174 test_expect_success 'set --type=color' '
1175 cat >expect <<\EOF &&
1176 [foo]
1177 color = red
1178 EOF
1179 rm .git/config &&
1180 git config --type=color foo.color "red" &&
1181 test_cmp expect .git/config
1182 '
1183
1184 test_expect_success 'get --type=color barfs on non-color' '
1185 echo "[foo]bar=not-a-color" >.git/config &&
1186 test_must_fail git config --get --type=color foo.bar
1187 '
1188
1189 test_expect_success 'set --type=color barfs on non-color' '
1190 test_must_fail git config --type=color foo.color "not-a-color" 2>error &&
1191 test_grep "cannot parse color" error
1192 '
1193
1194 test_expect_success 'quoting' '
1195 cat >expect <<\EOF &&
1196 [quote]
1197 leading = " test"
1198 ending = "test "
1199 semicolon = "test;test"
1200 hash = "test#test"
1201 EOF
1202 rm -f .git/config &&
1203 git config ${mode_set} quote.leading " test" &&
1204 git config ${mode_set} quote.ending "test " &&
1205 git config ${mode_set} quote.semicolon "test;test" &&
1206 git config ${mode_set} quote.hash "test#test" &&
1207 test_cmp expect .git/config
1208 '
1209
1210 test_expect_success 'key with newline' '
1211 test_must_fail git config ${mode_get} "key.with
1212 newline" 123
1213 '
1214
1215 test_expect_success 'value with newline' '
1216 git config ${mode_set} key.sub value.with\\\
1217 newline
1218 '
1219
1220 cat > .git/config <<\EOF
1221 [section]
1222 ; comment \
1223 continued = cont\
1224 inued
1225 noncont = not continued ; \
1226 quotecont = "cont;\
1227 inued"
1228 EOF
1229
1230 test_expect_success 'value continued on next line' '
1231 cat >expect <<-\EOF &&
1232 section.continued=continued
1233 section.noncont=not continued
1234 section.quotecont=cont;inued
1235 EOF
1236 git config ${mode_prefix}list > result &&
1237 test_cmp expect result
1238 '
1239
1240 cat > .git/config <<\EOF
1241 [section "sub=section"]
1242 val1 = foo=bar
1243 val2 = foo\nbar
1244 val3 = \n\n
1245 val4 =
1246 val5
1247 EOF
1248
1249 cat > expect <<\EOF
1250 section.sub=section.val1
1251 foo=barQsection.sub=section.val2
1252 foo
1253 barQsection.sub=section.val3
1254
1255
1256 Qsection.sub=section.val4
1257 Qsection.sub=section.val5Q
1258 EOF
1259 test_expect_success '--null --list' '
1260 git config ${mode_prefix}list --null >result.raw &&
1261 nul_to_q <result.raw >result &&
1262 echo >>result &&
1263 test_cmp expect result
1264 '
1265
1266 test_expect_success '--null --get-regexp' '
1267 git config ${mode_get_regexp} --null "val[0-9]" >result.raw &&
1268 nul_to_q <result.raw >result &&
1269 echo >>result &&
1270 test_cmp expect result
1271 '
1272
1273 test_expect_success 'inner whitespace kept verbatim, spaces only' '
1274 echo "foo bar" >expect &&
1275 git config ${mode_set} section.val "foo bar" &&
1276 git config ${mode_get} section.val >actual &&
1277 test_cmp expect actual
1278 '
1279
1280 test_expect_success 'inner whitespace kept verbatim, horizontal tabs only' '
1281 echo "fooQQbar" | q_to_tab >expect &&
1282 git config ${mode_set} section.val "$(cat expect)" &&
1283 git config ${mode_get} section.val >actual &&
1284 test_cmp expect actual
1285 '
1286
1287 test_expect_success 'inner whitespace kept verbatim, horizontal tabs and spaces' '
1288 echo "foo Q bar" | q_to_tab >expect &&
1289 git config ${mode_set} section.val "$(cat expect)" &&
1290 git config ${mode_get} section.val >actual &&
1291 test_cmp expect actual
1292 '
1293
1294 test_expect_success SYMLINKS 'symlinked configuration' '
1295 test_when_finished "rm myconfig" &&
1296 ln -s notyet myconfig &&
1297 git config --file=myconfig test.frotz nitfol &&
1298 test_path_is_symlink myconfig &&
1299 test_path_is_file notyet &&
1300 test "z$(git config --file=notyet test.frotz)" = znitfol &&
1301 git config --file=myconfig test.xyzzy rezrov &&
1302 test_path_is_symlink myconfig &&
1303 test_path_is_file notyet &&
1304 cat >expect <<-\EOF &&
1305 nitfol
1306 rezrov
1307 EOF
1308 {
1309 git config --file=notyet test.frotz &&
1310 git config --file=notyet test.xyzzy
1311 } >actual &&
1312 test_cmp expect actual
1313 '
1314
1315 test_expect_success SYMLINKS 'symlink to nonexistent configuration' '
1316 test_when_finished "rm linktonada linktolinktonada" &&
1317 ln -s doesnotexist linktonada &&
1318 ln -s linktonada linktolinktonada &&
1319 test_must_fail git config ${mode_prefix}list --file=linktonada &&
1320 test_must_fail git config ${mode_prefix}list --file=linktolinktonada
1321 '
1322
1323 test_expect_success 'check split_cmdline return' '
1324 test_when_finished "rm -rf repo" &&
1325 git init repo &&
1326 (
1327 cd repo &&
1328 git config ${mode_set} alias.split-cmdline-fix "echo \"" &&
1329 test_must_fail git split-cmdline-fix &&
1330 echo foo >foo &&
1331 git add foo &&
1332 git commit -m "initial commit" &&
1333 git config ${mode_set} branch.main.mergeoptions "echo \"" &&
1334 test_must_fail git merge main
1335 )
1336 '
1337
1338 test_expect_success 'git -c "key=value" support' '
1339 cat >expect <<-\EOF &&
1340 value
1341 value
1342 true
1343 EOF
1344 {
1345 git -c section.name=value config section.name &&
1346 git -c foo.CamelCase=value config foo.camelcase &&
1347 git -c foo.flag config --bool foo.flag
1348 } >actual &&
1349 test_cmp expect actual &&
1350 test_must_fail git -c name=value config section.name
1351 '
1352
1353 # We just need a type-specifier here that cares about the
1354 # distinction internally between a NULL boolean and a real
1355 # string (because most of git's internal parsers do care).
1356 # Using "--path" works, but we do not otherwise care about
1357 # its semantics.
1358 test_expect_success 'git -c can represent empty string' '
1359 echo >expect &&
1360 git -c foo.empty= config --path foo.empty >actual &&
1361 test_cmp expect actual
1362 '
1363
1364 test_expect_success 'key sanity-checking' '
1365 test_must_fail git config ${mode_get} foo=bar &&
1366 test_must_fail git config ${mode_get} foo=.bar &&
1367 test_must_fail git config ${mode_get} foo.ba=r &&
1368 test_must_fail git config ${mode_get} foo.1bar &&
1369 test_must_fail git config ${mode_get} foo."ba
1370 z".bar &&
1371 test_must_fail git config ${mode_set} . false &&
1372 test_must_fail git config ${mode_set} .foo false &&
1373 test_must_fail git config ${mode_set} foo. false &&
1374 test_must_fail git config ${mode_set} .foo. false &&
1375 git config ${mode_set} foo.bar true &&
1376 git config ${mode_set} foo."ba =z".bar false
1377 '
1378
1379 test_expect_success 'git -c works with aliases of builtins' '
1380 git config alias.checkconfig "-c foo.check=bar config foo.check" &&
1381 echo bar >expect &&
1382 git checkconfig >actual &&
1383 test_cmp expect actual
1384 '
1385
1386 test_expect_success 'aliases can be CamelCased' '
1387 test_when_finished "rm -rf repo" &&
1388 git init repo &&
1389 (
1390 cd repo &&
1391 test_commit A &&
1392 git config alias.CamelCased "rev-parse HEAD" &&
1393 git CamelCased >out &&
1394 git rev-parse HEAD >expect &&
1395 test_cmp expect out
1396 )
1397 '
1398
1399 test_expect_success 'git -c does not split values on equals' '
1400 echo "value with = in it" >expect &&
1401 git -c section.foo="value with = in it" config section.foo >actual &&
1402 test_cmp expect actual
1403 '
1404
1405 test_expect_success 'git -c dies on bogus config' '
1406 test_must_fail git -c core.bare=foo rev-parse
1407 '
1408
1409 test_expect_success 'git -c complains about empty key' '
1410 test_must_fail git -c "=foo" rev-parse
1411 '
1412
1413 test_expect_success 'git -c complains about empty key and value' '
1414 test_must_fail git -c "" rev-parse
1415 '
1416
1417 test_expect_success 'multiple git -c appends config' '
1418 test_config alias.x "!git -c x.two=2 config ${mode_get_regexp} ^x\.*" &&
1419 cat >expect <<-\EOF &&
1420 x.one 1
1421 x.two 2
1422 EOF
1423 git -c x.one=1 x >actual &&
1424 test_cmp expect actual
1425 '
1426
1427 test_expect_success 'last one wins: two level vars' '
1428 # sec.var and sec.VAR are the same variable, as the first
1429 # and the last level of a configuration variable name is
1430 # case insensitive.
1431
1432 echo VAL >expect &&
1433
1434 git -c sec.var=val -c sec.VAR=VAL config --get sec.var >actual &&
1435 test_cmp expect actual &&
1436 git -c SEC.var=val -c sec.var=VAL config --get sec.var >actual &&
1437 test_cmp expect actual &&
1438
1439 git -c sec.var=val -c sec.VAR=VAL config --get SEC.var >actual &&
1440 test_cmp expect actual &&
1441 git -c SEC.var=val -c sec.var=VAL config --get sec.VAR >actual &&
1442 test_cmp expect actual
1443 '
1444
1445 test_expect_success 'last one wins: three level vars' '
1446 # v.a.r and v.A.r are not the same variable, as the middle
1447 # level of a three-level configuration variable name is
1448 # case sensitive.
1449
1450 echo val >expect &&
1451 git -c v.a.r=val -c v.A.r=VAL config --get v.a.r >actual &&
1452 test_cmp expect actual &&
1453 git -c v.a.r=val -c v.A.r=VAL config --get V.a.R >actual &&
1454 test_cmp expect actual &&
1455
1456 # v.a.r and V.a.R are the same variable, as the first
1457 # and the last level of a configuration variable name is
1458 # case insensitive.
1459
1460 echo VAL >expect &&
1461 git -c v.a.r=val -c v.a.R=VAL config --get v.a.r >actual &&
1462 test_cmp expect actual &&
1463 git -c v.a.r=val -c V.a.r=VAL config --get v.a.r >actual &&
1464 test_cmp expect actual &&
1465 git -c v.a.r=val -c v.a.R=VAL config --get V.a.R >actual &&
1466 test_cmp expect actual &&
1467 git -c v.a.r=val -c V.a.r=VAL config --get V.a.R >actual &&
1468 test_cmp expect actual
1469 '
1470
1471 test_expect_success 'old-fashioned settings are case insensitive' '
1472 test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1473
1474 cat >testConfig_actual <<-EOF &&
1475 [V.A]
1476 r = value1
1477 EOF
1478 q_to_tab >testConfig_expect <<-EOF &&
1479 [V.A]
1480 Qr = value2
1481 EOF
1482 git config -f testConfig_actual "v.a.r" value2 &&
1483 test_cmp testConfig_expect testConfig_actual &&
1484
1485 cat >testConfig_actual <<-EOF &&
1486 [V.A]
1487 r = value1
1488 EOF
1489 q_to_tab >testConfig_expect <<-EOF &&
1490 [V.A]
1491 QR = value2
1492 EOF
1493 git config -f testConfig_actual "V.a.R" value2 &&
1494 test_cmp testConfig_expect testConfig_actual &&
1495
1496 cat >testConfig_actual <<-EOF &&
1497 [V.A]
1498 r = value1
1499 EOF
1500 q_to_tab >testConfig_expect <<-EOF &&
1501 [V.A]
1502 r = value1
1503 Qr = value2
1504 EOF
1505 git config -f testConfig_actual "V.A.r" value2 &&
1506 test_cmp testConfig_expect testConfig_actual &&
1507
1508 cat >testConfig_actual <<-EOF &&
1509 [V.A]
1510 r = value1
1511 EOF
1512 q_to_tab >testConfig_expect <<-EOF &&
1513 [V.A]
1514 r = value1
1515 Qr = value2
1516 EOF
1517 git config -f testConfig_actual "v.A.r" value2 &&
1518 test_cmp testConfig_expect testConfig_actual
1519 '
1520
1521 test_expect_success 'setting different case sensitive subsections ' '
1522 test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1523
1524 cat >testConfig_actual <<-EOF &&
1525 [V "A"]
1526 R = v1
1527 [K "E"]
1528 Y = v1
1529 [a "b"]
1530 c = v1
1531 [d "e"]
1532 f = v1
1533 EOF
1534 q_to_tab >testConfig_expect <<-EOF &&
1535 [V "A"]
1536 Qr = v2
1537 [K "E"]
1538 Qy = v2
1539 [a "b"]
1540 Qc = v2
1541 [d "e"]
1542 f = v1
1543 [d "E"]
1544 Qf = v2
1545 EOF
1546 # exact match
1547 git config -f testConfig_actual a.b.c v2 &&
1548 # match section and subsection, key is cased differently.
1549 git config -f testConfig_actual K.E.y v2 &&
1550 # section and key are matched case insensitive, but subsection needs
1551 # to match; When writing out new values only the key is adjusted
1552 git config -f testConfig_actual v.A.r v2 &&
1553 # subsection is not matched:
1554 git config -f testConfig_actual d.E.f v2 &&
1555 test_cmp testConfig_expect testConfig_actual
1556 '
1557
1558 for VAR in a .a a. a.0b a."b c". a."b c".0d
1559 do
1560 test_expect_success "git -c $VAR=VAL rejects invalid '$VAR'" '
1561 test_must_fail git -c "$VAR=VAL" config -l
1562 '
1563 done
1564
1565 for VAR in a.b a."b c".d
1566 do
1567 test_expect_success "git -c $VAR=VAL works with valid '$VAR'" '
1568 echo VAL >expect &&
1569 git -c "$VAR=VAL" config --get "$VAR" >actual &&
1570 test_cmp expect actual
1571 '
1572 done
1573
1574 test_expect_success 'git -c is not confused by empty environment' '
1575 GIT_CONFIG_PARAMETERS="" git -c x.one=1 config ${mode_prefix}list
1576 '
1577
1578 test_expect_success 'GIT_CONFIG_PARAMETERS handles old-style entries' '
1579 v="${SQ}key.one=foo${SQ}" &&
1580 v="$v ${SQ}key.two=bar${SQ}" &&
1581 v="$v ${SQ}key.ambiguous=section.whatever=value${SQ}" &&
1582 GIT_CONFIG_PARAMETERS=$v git config ${mode_get_regexp} "key.*" >actual &&
1583 cat >expect <<-EOF &&
1584 key.one foo
1585 key.two bar
1586 key.ambiguous section.whatever=value
1587 EOF
1588 test_cmp expect actual
1589 '
1590
1591 test_expect_success 'GIT_CONFIG_PARAMETERS handles new-style entries' '
1592 v="${SQ}key.one${SQ}=${SQ}foo${SQ}" &&
1593 v="$v ${SQ}key.two${SQ}=${SQ}bar${SQ}" &&
1594 v="$v ${SQ}key.ambiguous=section.whatever${SQ}=${SQ}value${SQ}" &&
1595 GIT_CONFIG_PARAMETERS=$v git config ${mode_get_regexp} "key.*" >actual &&
1596 cat >expect <<-EOF &&
1597 key.one foo
1598 key.two bar
1599 key.ambiguous=section.whatever value
1600 EOF
1601 test_cmp expect actual
1602 '
1603
1604 test_expect_success 'old and new-style entries can mix' '
1605 v="${SQ}key.oldone=oldfoo${SQ}" &&
1606 v="$v ${SQ}key.newone${SQ}=${SQ}newfoo${SQ}" &&
1607 v="$v ${SQ}key.oldtwo=oldbar${SQ}" &&
1608 v="$v ${SQ}key.newtwo${SQ}=${SQ}newbar${SQ}" &&
1609 GIT_CONFIG_PARAMETERS=$v git config ${mode_get_regexp} "key.*" >actual &&
1610 cat >expect <<-EOF &&
1611 key.oldone oldfoo
1612 key.newone newfoo
1613 key.oldtwo oldbar
1614 key.newtwo newbar
1615 EOF
1616 test_cmp expect actual
1617 '
1618
1619 test_expect_success 'old and new bools with ambiguous subsection' '
1620 v="${SQ}key.with=equals.oldbool${SQ}" &&
1621 v="$v ${SQ}key.with=equals.newbool${SQ}=" &&
1622 GIT_CONFIG_PARAMETERS=$v git config ${mode_get_regexp} "key.*" >actual &&
1623 cat >expect <<-EOF &&
1624 key.with equals.oldbool
1625 key.with=equals.newbool
1626 EOF
1627 test_cmp expect actual
1628 '
1629
1630 test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' '
1631 cat >expect <<-\EOF &&
1632 env.one one
1633 env.two two
1634 EOF
1635 GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ} ${SQ}env.two=two${SQ}" \
1636 git config ${mode_get_regexp} "env.*" >actual &&
1637 test_cmp expect actual &&
1638
1639 cat >expect <<-EOF &&
1640 env.one one${SQ}
1641 env.two two
1642 EOF
1643 GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ$SQ$SQ ${SQ}env.two=two${SQ}" \
1644 git config ${mode_get_regexp} "env.*" >actual &&
1645 test_cmp expect actual &&
1646
1647 test_must_fail env \
1648 GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ ${SQ}env.two=two${SQ}" \
1649 git config ${mode_get_regexp} "env.*"
1650 '
1651
1652 test_expect_success 'git --config-env=key=envvar support' '
1653 cat >expect <<-\EOF &&
1654 value
1655 value
1656 value
1657 value
1658 false
1659 false
1660 EOF
1661 {
1662 ENVVAR=value git --config-env=core.name=ENVVAR config core.name &&
1663 ENVVAR=value git --config-env core.name=ENVVAR config core.name &&
1664 ENVVAR=value git --config-env=foo.CamelCase=ENVVAR config foo.camelcase &&
1665 ENVVAR=value git --config-env foo.CamelCase=ENVVAR config foo.camelcase &&
1666 ENVVAR= git --config-env=foo.flag=ENVVAR config --bool foo.flag &&
1667 ENVVAR= git --config-env foo.flag=ENVVAR config --bool foo.flag
1668 } >actual &&
1669 test_cmp expect actual
1670 '
1671
1672 test_expect_success 'git --config-env with missing value' '
1673 test_must_fail env ENVVAR=value git --config-env 2>error &&
1674 test_grep "no config key given for --config-env" error &&
1675 test_must_fail env ENVVAR=value git --config-env config core.name 2>error &&
1676 test_grep "invalid config format: config" error
1677 '
1678
1679 test_expect_success 'git --config-env fails with invalid parameters' '
1680 test_must_fail git --config-env=foo.flag config --bool foo.flag 2>error &&
1681 test_grep "invalid config format: foo.flag" error &&
1682 test_must_fail git --config-env=foo.flag= config --bool foo.flag 2>error &&
1683 test_grep "missing environment variable name for configuration ${SQ}foo.flag${SQ}" error &&
1684 sane_unset NONEXISTENT &&
1685 test_must_fail git --config-env=foo.flag=NONEXISTENT config --bool foo.flag 2>error &&
1686 test_grep "missing environment variable ${SQ}NONEXISTENT${SQ} for configuration ${SQ}foo.flag${SQ}" error
1687 '
1688
1689 test_expect_success 'git -c and --config-env work together' '
1690 cat >expect <<-\EOF &&
1691 bar.cmd cmd-value
1692 bar.env env-value
1693 EOF
1694 ENVVAR=env-value git \
1695 -c bar.cmd=cmd-value \
1696 --config-env=bar.env=ENVVAR \
1697 config ${mode_get_regexp} "^bar.*" >actual &&
1698 test_cmp expect actual
1699 '
1700
1701 test_expect_success 'git -c and --config-env override each other' '
1702 cat >expect <<-\EOF &&
1703 env
1704 cmd
1705 EOF
1706 {
1707 ENVVAR=env git -c bar.bar=cmd --config-env=bar.bar=ENVVAR config bar.bar &&
1708 ENVVAR=env git --config-env=bar.bar=ENVVAR -c bar.bar=cmd config bar.bar
1709 } >actual &&
1710 test_cmp expect actual
1711 '
1712
1713 test_expect_success '--config-env handles keys with equals' '
1714 echo value=with=equals >expect &&
1715 ENVVAR=value=with=equals git \
1716 --config-env=section.subsection=with=equals.key=ENVVAR \
1717 config section.subsection=with=equals.key >actual &&
1718 test_cmp expect actual
1719 '
1720
1721 test_expect_success 'git config handles environment config pairs' '
1722 GIT_CONFIG_COUNT=2 \
1723 GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="foo" \
1724 GIT_CONFIG_KEY_1="pair.two" GIT_CONFIG_VALUE_1="bar" \
1725 git config ${mode_get_regexp} "pair.*" >actual &&
1726 cat >expect <<-EOF &&
1727 pair.one foo
1728 pair.two bar
1729 EOF
1730 test_cmp expect actual
1731 '
1732
1733 test_expect_success 'git config ignores pairs without count' '
1734 test_must_fail env GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \
1735 git config ${mode_get} pair.one 2>error &&
1736 test_must_be_empty error
1737 '
1738
1739 test_expect_success 'git config ignores pairs exceeding count' '
1740 GIT_CONFIG_COUNT=1 \
1741 GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \
1742 GIT_CONFIG_KEY_1="pair.two" GIT_CONFIG_VALUE_1="value" \
1743 git config ${mode_get_regexp} "pair.*" >actual 2>error &&
1744 cat >expect <<-EOF &&
1745 pair.one value
1746 EOF
1747 test_cmp expect actual &&
1748 test_must_be_empty error
1749 '
1750
1751 test_expect_success 'git config ignores pairs with zero count' '
1752 test_must_fail env \
1753 GIT_CONFIG_COUNT=0 GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \
1754 git config ${mode_get} pair.one 2>error &&
1755 test_must_be_empty error
1756 '
1757
1758 test_expect_success 'git config ignores pairs with empty count' '
1759 test_must_fail env \
1760 GIT_CONFIG_COUNT= GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \
1761 git config ${mode_get} pair.one 2>error &&
1762 test_must_be_empty error
1763 '
1764
1765 test_expect_success 'git config fails with invalid count' '
1766 test_must_fail env GIT_CONFIG_COUNT=10a git config ${mode_prefix}list 2>error &&
1767 test_grep "bogus count" error &&
1768 test_must_fail env GIT_CONFIG_COUNT=9999999999999999 git config ${mode_prefix}list 2>error &&
1769 test_grep "too many entries" error
1770 '
1771
1772 test_expect_success 'git config fails with missing config key' '
1773 test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_VALUE_0="value" \
1774 git config ${mode_prefix}list 2>error &&
1775 test_grep "missing config key" error
1776 '
1777
1778 test_expect_success 'git config fails with missing config value' '
1779 test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0="pair.one" \
1780 git config ${mode_prefix}list 2>error &&
1781 test_grep "missing config value" error
1782 '
1783
1784 test_expect_success 'git config fails with invalid config pair key' '
1785 test_must_fail env GIT_CONFIG_COUNT=1 \
1786 GIT_CONFIG_KEY_0= GIT_CONFIG_VALUE_0=value \
1787 git config ${mode_prefix}list &&
1788 test_must_fail env GIT_CONFIG_COUNT=1 \
1789 GIT_CONFIG_KEY_0=missing-section GIT_CONFIG_VALUE_0=value \
1790 git config ${mode_prefix}list
1791 '
1792
1793 test_expect_success 'environment overrides config file' '
1794 test_when_finished "rm -f .git/config" &&
1795 cat >.git/config <<-EOF &&
1796 [pair]
1797 one = value
1798 EOF
1799 GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=override \
1800 git config ${mode_get} pair.one >actual &&
1801 cat >expect <<-EOF &&
1802 override
1803 EOF
1804 test_cmp expect actual
1805 '
1806
1807 test_expect_success 'GIT_CONFIG_PARAMETERS overrides environment config' '
1808 GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=value \
1809 GIT_CONFIG_PARAMETERS="${SQ}pair.one=override${SQ}" \
1810 git config ${mode_get} pair.one >actual &&
1811 cat >expect <<-EOF &&
1812 override
1813 EOF
1814 test_cmp expect actual
1815 '
1816
1817 test_expect_success 'command line overrides environment config' '
1818 GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=value \
1819 git -c pair.one=override config pair.one >actual &&
1820 cat >expect <<-EOF &&
1821 override
1822 EOF
1823 test_cmp expect actual
1824 '
1825
1826 test_expect_success 'git config --edit works' '
1827 git config -f tmp test.value no &&
1828 echo test.value=yes >expect &&
1829 GIT_EDITOR="echo [test]value=yes >" git config ${mode_prefix}edit -f tmp &&
1830 git config ${mode_prefix}list -f tmp >actual &&
1831 test_cmp expect actual
1832 '
1833
1834 test_expect_success 'git config --edit respects core.editor' '
1835 git config -f tmp test.value no &&
1836 echo test.value=yes >expect &&
1837 test_config core.editor "echo [test]value=yes >" &&
1838 git config ${mode_prefix}edit -f tmp &&
1839 git config ${mode_prefix}list -f tmp >actual &&
1840 test_cmp expect actual
1841 '
1842
1843 # malformed configuration files
1844 test_expect_success 'barf on syntax error' '
1845 cat >.git/config <<-\EOF &&
1846 # broken key=value
1847 [section]
1848 key garbage
1849 EOF
1850 test_must_fail git config --get section.key 2>error &&
1851 test_grep " line 3 " error
1852 '
1853
1854 test_expect_success 'barf on incomplete section header' '
1855 cat >.git/config <<-\EOF &&
1856 # broken section line
1857 [section
1858 key = value
1859 EOF
1860 test_must_fail git config --get section.key 2>error &&
1861 test_grep " line 2 " error
1862 '
1863
1864 test_expect_success 'barf on incomplete string' '
1865 cat >.git/config <<-\EOF &&
1866 # broken value string
1867 [section]
1868 key = "value string
1869 EOF
1870 test_must_fail git config --get section.key 2>error &&
1871 test_grep " line 3 " error
1872 '
1873
1874 test_expect_success 'urlmatch' '
1875 cat >.git/config <<-\EOF &&
1876 [http]
1877 sslVerify
1878 [http "https://weak.example.com"]
1879 sslVerify = false
1880 cookieFile = /tmp/cookie.txt
1881 EOF
1882
1883 test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
1884 test_must_be_empty actual &&
1885 test_expect_code 1 git config get --url=https://good.example.com --bool doesnt.exist >actual &&
1886 test_must_be_empty actual &&
1887
1888 echo true >expect &&
1889 git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
1890 test_cmp expect actual &&
1891 git config get --bool --url=https://good.example.com http.SSLverify >actual &&
1892 test_cmp expect actual &&
1893
1894 echo false >expect &&
1895 git config --bool --get-urlmatch http.sslverify https://weak.example.com >actual &&
1896 test_cmp expect actual &&
1897 git config get --bool --url=https://weak.example.com http.sslverify >actual &&
1898 test_cmp expect actual &&
1899
1900 {
1901 echo http.cookiefile /tmp/cookie.txt &&
1902 echo http.sslverify false
1903 } >expect &&
1904 git config --get-urlmatch HTTP https://weak.example.com >actual &&
1905 test_cmp expect actual &&
1906 git config get --url=https://weak.example.com HTTP >actual &&
1907 test_cmp expect actual
1908 '
1909
1910 test_expect_success 'urlmatch with --show-scope' '
1911 cat >.git/config <<-\EOF &&
1912 [http "https://weak.example.com"]
1913 sslVerify = false
1914 cookieFile = /tmp/cookie.txt
1915 EOF
1916
1917 cat >expect <<-EOF &&
1918 local http.cookiefile /tmp/cookie.txt
1919 local http.sslverify false
1920 EOF
1921 git config --get-urlmatch --show-scope HTTP https://weak.example.com >actual &&
1922 test_cmp expect actual &&
1923 git config get --url=https://weak.example.com --show-scope HTTP >actual &&
1924 test_cmp expect actual
1925 '
1926
1927 test_expect_success 'urlmatch favors more specific URLs' '
1928 cat >.git/config <<-\EOF &&
1929 [http "https://example.com/"]
1930 cookieFile = /tmp/root.txt
1931 [http "https://example.com/subdirectory"]
1932 cookieFile = /tmp/subdirectory.txt
1933 [http "https://user@example.com/"]
1934 cookieFile = /tmp/user.txt
1935 [http "https://averylonguser@example.com/"]
1936 cookieFile = /tmp/averylonguser.txt
1937 [http "https://preceding.example.com"]
1938 cookieFile = /tmp/preceding.txt
1939 [http "https://*.example.com"]
1940 cookieFile = /tmp/wildcard.txt
1941 [http "https://*.example.com/wildcardwithsubdomain"]
1942 cookieFile = /tmp/wildcardwithsubdomain.txt
1943 [http "https://*.example.*"]
1944 cookieFile = /tmp/multiwildcard.txt
1945 [http "https://trailing.example.com"]
1946 cookieFile = /tmp/trailing.txt
1947 [http "https://user@*.example.com/"]
1948 cookieFile = /tmp/wildcardwithuser.txt
1949 [http "https://sub.example.com/"]
1950 cookieFile = /tmp/sub.txt
1951 EOF
1952
1953 echo http.cookiefile /tmp/root.txt >expect &&
1954 git config --get-urlmatch HTTP https://example.com >actual &&
1955 test_cmp expect actual &&
1956 git config get --url=https://example.com HTTP >actual &&
1957 test_cmp expect actual &&
1958
1959 echo http.cookiefile /tmp/subdirectory.txt >expect &&
1960 git config --get-urlmatch HTTP https://example.com/subdirectory >actual &&
1961 test_cmp expect actual &&
1962 git config get --url=https://example.com/subdirectory HTTP >actual &&
1963 test_cmp expect actual &&
1964
1965 echo http.cookiefile /tmp/subdirectory.txt >expect &&
1966 git config --get-urlmatch HTTP https://example.com/subdirectory/nested >actual &&
1967 test_cmp expect actual &&
1968 git config get --url=https://example.com/subdirectory/nested HTTP >actual &&
1969 test_cmp expect actual &&
1970
1971 echo http.cookiefile /tmp/user.txt >expect &&
1972 git config --get-urlmatch HTTP https://user@example.com/ >actual &&
1973 test_cmp expect actual &&
1974 git config get --url=https://user@example.com/ HTTP >actual &&
1975 test_cmp expect actual &&
1976
1977 echo http.cookiefile /tmp/subdirectory.txt >expect &&
1978 git config --get-urlmatch HTTP https://averylonguser@example.com/subdirectory >actual &&
1979 test_cmp expect actual &&
1980 git config get --url=https://averylonguser@example.com/subdirectory HTTP >actual &&
1981 test_cmp expect actual &&
1982
1983 echo http.cookiefile /tmp/preceding.txt >expect &&
1984 git config --get-urlmatch HTTP https://preceding.example.com >actual &&
1985 test_cmp expect actual &&
1986 git config get --url=https://preceding.example.com HTTP >actual &&
1987 test_cmp expect actual &&
1988
1989 echo http.cookiefile /tmp/wildcard.txt >expect &&
1990 git config --get-urlmatch HTTP https://wildcard.example.com >actual &&
1991 test_cmp expect actual &&
1992 git config get --url=https://wildcard.example.com HTTP >actual &&
1993 test_cmp expect actual &&
1994
1995 echo http.cookiefile /tmp/sub.txt >expect &&
1996 git config --get-urlmatch HTTP https://sub.example.com/wildcardwithsubdomain >actual &&
1997 test_cmp expect actual &&
1998 git config get --url=https://sub.example.com/wildcardwithsubdomain HTTP >actual &&
1999 test_cmp expect actual &&
2000
2001 echo http.cookiefile /tmp/trailing.txt >expect &&
2002 git config --get-urlmatch HTTP https://trailing.example.com >actual &&
2003 test_cmp expect actual &&
2004 git config get --url=https://trailing.example.com HTTP >actual &&
2005 test_cmp expect actual &&
2006
2007 echo http.cookiefile /tmp/sub.txt >expect &&
2008 git config --get-urlmatch HTTP https://user@sub.example.com >actual &&
2009 test_cmp expect actual &&
2010 git config get --url=https://user@sub.example.com HTTP >actual &&
2011 test_cmp expect actual &&
2012
2013 echo http.cookiefile /tmp/multiwildcard.txt >expect &&
2014 git config --get-urlmatch HTTP https://wildcard.example.org >actual &&
2015 test_cmp expect actual &&
2016 git config get --url=https://wildcard.example.org HTTP >actual &&
2017 test_cmp expect actual
2018 '
2019
2020 test_expect_success 'urlmatch with wildcard' '
2021 cat >.git/config <<-\EOF &&
2022 [http]
2023 sslVerify
2024 [http "https://*.example.com"]
2025 sslVerify = false
2026 cookieFile = /tmp/cookie.txt
2027 EOF
2028
2029 test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
2030 test_must_be_empty actual &&
2031
2032 echo true >expect &&
2033 git config --bool --get-urlmatch http.SSLverify https://example.com >actual &&
2034 test_cmp expect actual &&
2035
2036 echo true >expect &&
2037 git config --bool --get-urlmatch http.SSLverify https://good-example.com >actual &&
2038 test_cmp expect actual &&
2039
2040 echo true >expect &&
2041 git config --bool --get-urlmatch http.sslverify https://deep.nested.example.com >actual &&
2042 test_cmp expect actual &&
2043
2044 echo false >expect &&
2045 git config --bool --get-urlmatch http.sslverify https://good.example.com >actual &&
2046 test_cmp expect actual &&
2047
2048 {
2049 echo http.cookiefile /tmp/cookie.txt &&
2050 echo http.sslverify false
2051 } >expect &&
2052 git config --get-urlmatch HTTP https://good.example.com >actual &&
2053 test_cmp expect actual &&
2054
2055 echo http.sslverify >expect &&
2056 git config --get-urlmatch HTTP https://more.example.com.au >actual &&
2057 test_cmp expect actual
2058 '
2059
2060 # good section hygiene
2061 test_expect_success '--unset last key removes section (except if commented)' '
2062 cat >.git/config <<-\EOF &&
2063 # some generic comment on the configuration file itself
2064 # a comment specific to this "section" section.
2065 [section]
2066 # some intervening lines
2067 # that should also be dropped
2068
2069 key = value
2070 # please be careful when you update the above variable
2071 EOF
2072
2073 cat >expect <<-\EOF &&
2074 # some generic comment on the configuration file itself
2075 # a comment specific to this "section" section.
2076 [section]
2077 # some intervening lines
2078 # that should also be dropped
2079
2080 # please be careful when you update the above variable
2081 EOF
2082
2083 git config ${mode_unset} section.key &&
2084 test_cmp expect .git/config &&
2085
2086 cat >.git/config <<-\EOF &&
2087 [section]
2088 key = value
2089 [next-section]
2090 EOF
2091
2092 cat >expect <<-\EOF &&
2093 [next-section]
2094 EOF
2095
2096 git config ${mode_unset} section.key &&
2097 test_cmp expect .git/config &&
2098
2099 q_to_tab >.git/config <<-\EOF &&
2100 [one]
2101 Qkey = "multiline \
2102 QQ# with comment"
2103 [two]
2104 key = true
2105 EOF
2106 git config ${mode_unset} two.key &&
2107 test_grep ! two .git/config &&
2108
2109 q_to_tab >.git/config <<-\EOF &&
2110 [one]
2111 Qkey = "multiline \
2112 QQ# with comment"
2113 [one]
2114 key = true
2115 EOF
2116 git config ${mode_unset_all} one.key &&
2117 test_line_count = 0 .git/config &&
2118
2119 q_to_tab >.git/config <<-\EOF &&
2120 [one]
2121 Qkey = true
2122 Q# a comment not at the start
2123 [two]
2124 Qkey = true
2125 EOF
2126 git config ${mode_unset} two.key &&
2127 test_grep two .git/config &&
2128
2129 q_to_tab >.git/config <<-\EOF &&
2130 [one]
2131 Qkey = not [two "subsection"]
2132 [two "subsection"]
2133 [two "subsection"]
2134 Qkey = true
2135 [TWO "subsection"]
2136 [one]
2137 EOF
2138 git config ${mode_unset} two.subsection.key &&
2139 test "not [two subsection]" = "$(git config ${mode_get} one.key)" &&
2140 test_line_count = 3 .git/config
2141 '
2142
2143 test_expect_success '--unset-all removes section if empty & uncommented' '
2144 cat >.git/config <<-\EOF &&
2145 [section]
2146 key = value1
2147 key = value2
2148 EOF
2149
2150 git config ${mode_unset_all} section.key &&
2151 test_line_count = 0 .git/config
2152 '
2153
2154 test_expect_success 'adding a key into an empty section reuses header' '
2155 cat >.git/config <<-\EOF &&
2156 [section]
2157 EOF
2158
2159 q_to_tab >expect <<-\EOF &&
2160 [section]
2161 Qkey = value
2162 EOF
2163
2164 git config section.key value &&
2165 test_cmp expect .git/config
2166 '
2167
2168 test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
2169 chmod 0600 .git/config &&
2170 git config imap.pass Hunter2 &&
2171 perl -e \
2172 "die q(badset) if ((stat(q(.git/config)))[2] & 07777) != 0600" &&
2173 git config ${mode_prefix}rename-section imap pop &&
2174 perl -e \
2175 "die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
2176 '
2177
2178 ! test_have_prereq MINGW ||
2179 HOME="$(pwd)" # convert to Windows path
2180
2181 test_expect_success 'set up --show-origin tests' '
2182 INCLUDE_DIR="$HOME/include" &&
2183 mkdir -p "$INCLUDE_DIR" &&
2184 cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
2185 [user]
2186 absolute = include
2187 EOF
2188 cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
2189 [user]
2190 relative = include
2191 EOF
2192 cat >"$HOME"/.gitconfig <<-EOF &&
2193 [user]
2194 global = true
2195 override = global
2196 [include]
2197 path = "$INCLUDE_DIR/absolute.include"
2198 EOF
2199 cat >.git/config <<-\EOF
2200 [user]
2201 local = true
2202 override = local
2203 [include]
2204 path = ../include/relative.include
2205 EOF
2206 '
2207
2208 test_expect_success '--show-origin with --list' '
2209 cat >expect <<-EOF &&
2210 file:$HOME/.gitconfig user.global=true
2211 file:$HOME/.gitconfig user.override=global
2212 file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
2213 file:$INCLUDE_DIR/absolute.include user.absolute=include
2214 file:.git/config user.local=true
2215 file:.git/config user.override=local
2216 file:.git/config include.path=../include/relative.include
2217 file:.git/../include/relative.include user.relative=include
2218 command line: user.environ=true
2219 command line: user.cmdline=true
2220 EOF
2221 GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.environ GIT_CONFIG_VALUE_0=true\
2222 git -c user.cmdline=true config ${mode_prefix}list --show-origin >output &&
2223 test_cmp expect output
2224 '
2225
2226 test_expect_success '--show-origin with --list --null' '
2227 cat >expect <<-EOF &&
2228 file:$HOME/.gitconfigQuser.global
2229 trueQfile:$HOME/.gitconfigQuser.override
2230 globalQfile:$HOME/.gitconfigQinclude.path
2231 $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
2232 includeQfile:.git/configQuser.local
2233 trueQfile:.git/configQuser.override
2234 localQfile:.git/configQinclude.path
2235 ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
2236 includeQcommand line:Quser.cmdline
2237 trueQ
2238 EOF
2239 git -c user.cmdline=true config ${mode_prefix}list --null --show-origin >output.raw &&
2240 nul_to_q <output.raw >output &&
2241 # The here-doc above adds a newline that the --null output would not
2242 # include. Add it here to make the two comparable.
2243 echo >>output &&
2244 test_cmp expect output
2245 '
2246
2247 test_expect_success '--show-origin with single file' '
2248 cat >expect <<-\EOF &&
2249 file:.git/config user.local=true
2250 file:.git/config user.override=local
2251 file:.git/config include.path=../include/relative.include
2252 EOF
2253 git config ${mode_prefix}list --local --show-origin >output &&
2254 test_cmp expect output
2255 '
2256
2257 test_expect_success '--show-origin with --get-regexp' '
2258 cat >expect <<-EOF &&
2259 file:$HOME/.gitconfig user.global true
2260 file:.git/config user.local true
2261 EOF
2262 git config ${mode_get_regexp} --show-origin "user\.[g|l].*" >output &&
2263 test_cmp expect output
2264 '
2265
2266 test_expect_success '--show-origin getting a single key' '
2267 cat >expect <<-\EOF &&
2268 file:.git/config local
2269 EOF
2270 git config ${mode_get} --show-origin user.override >output &&
2271 test_cmp expect output
2272 '
2273
2274 test_expect_success 'set up custom config file' '
2275 cat >"custom.conf" <<-\EOF &&
2276 [user]
2277 custom = true
2278 EOF
2279 CUSTOM_CONFIG_FILE="$(test-tool path-utils real_path custom.conf)"
2280 '
2281
2282 test_expect_success !MINGW 'set up custom config file with special name characters' '
2283 WEIRDLY_NAMED_FILE="file\" (dq) and spaces.conf" &&
2284 cp "$CUSTOM_CONFIG_FILE" "$WEIRDLY_NAMED_FILE"
2285 '
2286
2287 test_expect_success !MINGW '--show-origin escape special file name characters' '
2288 cat >expect <<-\EOF &&
2289 file:"file\" (dq) and spaces.conf" user.custom=true
2290 EOF
2291 git config ${mode_prefix}list --file "$WEIRDLY_NAMED_FILE" --show-origin >output &&
2292 test_cmp expect output
2293 '
2294
2295 test_expect_success '--show-origin stdin' '
2296 cat >expect <<-\EOF &&
2297 standard input: user.custom=true
2298 EOF
2299 git config ${mode_prefix}list --file - --show-origin <"$CUSTOM_CONFIG_FILE" >output &&
2300 test_cmp expect output
2301 '
2302
2303 test_expect_success '--show-origin stdin with file include' '
2304 cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
2305 [user]
2306 stdin = include
2307 EOF
2308 cat >expect <<-EOF &&
2309 file:$INCLUDE_DIR/stdin.include include
2310 EOF
2311 echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
2312 git config --show-origin --includes --file - user.stdin >output &&
2313
2314 test_cmp expect output
2315 '
2316
2317 test_expect_success '--show-origin blob' '
2318 test_when_finished "rm -rf repo" &&
2319 git init repo &&
2320 (
2321 cd repo &&
2322 blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
2323 cat >expect <<-EOF &&
2324 blob:$blob user.custom=true
2325 EOF
2326 git config ${mode_prefix}list --blob=$blob --show-origin >output &&
2327 test_cmp expect output
2328 )
2329 '
2330
2331 test_expect_success '--show-origin blob ref' '
2332 test_when_finished "rm -rf repo" &&
2333 git init repo &&
2334 (
2335 cd repo &&
2336 cat >expect <<-\EOF &&
2337 blob:main:custom.conf user.custom=true
2338 EOF
2339 cp "$CUSTOM_CONFIG_FILE" custom.conf &&
2340 git add custom.conf &&
2341 git commit -m "new config file" &&
2342 git config ${mode_prefix}list --blob=main:custom.conf --show-origin >output &&
2343 test_cmp expect output
2344 )
2345 '
2346
2347 test_expect_success '--show-origin with --default' '
2348 git config --show-origin --default foo some.key >actual &&
2349 echo "command line: foo" >expect &&
2350 test_cmp expect actual
2351 '
2352
2353 test_expect_success '--show-scope with --list' '
2354 cat >expect <<-EOF &&
2355 global user.global=true
2356 global user.override=global
2357 global include.path=$INCLUDE_DIR/absolute.include
2358 global user.absolute=include
2359 local user.local=true
2360 local user.override=local
2361 local include.path=../include/relative.include
2362 local user.relative=include
2363 local core.repositoryformatversion=1
2364 local extensions.worktreeconfig=true
2365 worktree user.worktree=true
2366 command user.cmdline=true
2367 EOF
2368 test_when_finished "git worktree remove wt1" &&
2369 git worktree add wt1 &&
2370 # We need these to test for worktree scope, but outside of this
2371 # test, this is just noise
2372 test_config core.repositoryformatversion 1 &&
2373 test_config extensions.worktreeConfig true &&
2374 git config --worktree user.worktree true &&
2375 git -c user.cmdline=true config ${mode_prefix}list --show-scope >output &&
2376 test_cmp expect output
2377 '
2378
2379 test_expect_success !MINGW '--show-scope with --blob' '
2380 blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
2381 cat >expect <<-EOF &&
2382 command user.custom=true
2383 EOF
2384 git config ${mode_prefix}list --blob=$blob --show-scope >output &&
2385 test_cmp expect output
2386 '
2387
2388 test_expect_success '--show-scope with --local' '
2389 cat >expect <<-\EOF &&
2390 local user.local=true
2391 local user.override=local
2392 local include.path=../include/relative.include
2393 EOF
2394 git config ${mode_prefix}list --local --show-scope >output &&
2395 test_cmp expect output
2396 '
2397
2398 test_expect_success '--show-scope getting a single value' '
2399 cat >expect <<-\EOF &&
2400 local true
2401 EOF
2402 git config ${mode_get} --show-scope user.local >output &&
2403 test_cmp expect output
2404 '
2405
2406 test_expect_success '--show-scope with --show-origin' '
2407 cat >expect <<-EOF &&
2408 global file:$HOME/.gitconfig user.global=true
2409 global file:$HOME/.gitconfig user.override=global
2410 global file:$HOME/.gitconfig include.path=$INCLUDE_DIR/absolute.include
2411 global file:$INCLUDE_DIR/absolute.include user.absolute=include
2412 local file:.git/config user.local=true
2413 local file:.git/config user.override=local
2414 local file:.git/config include.path=../include/relative.include
2415 local file:.git/../include/relative.include user.relative=include
2416 command command line: user.cmdline=true
2417 EOF
2418 git -c user.cmdline=true config ${mode_prefix}list --show-origin --show-scope >output &&
2419 test_cmp expect output
2420 '
2421
2422 test_expect_success '--show-scope with --default' '
2423 git config --show-scope --default foo some.key >actual &&
2424 echo "command foo" >expect &&
2425 test_cmp expect actual
2426 '
2427
2428 test_expect_success 'override global and system config' '
2429 test_when_finished rm -f \"\$HOME\"/.gitconfig &&
2430 cat >"$HOME"/.gitconfig <<-EOF &&
2431 [home]
2432 config = true
2433 EOF
2434
2435 test_when_finished rm -rf \"\$HOME\"/.config/git &&
2436 mkdir -p "$HOME"/.config/git &&
2437 cat >"$HOME"/.config/git/config <<-EOF &&
2438 [xdg]
2439 config = true
2440 EOF
2441 cat >.git/config <<-EOF &&
2442 [local]
2443 config = true
2444 EOF
2445 cat >custom-global-config <<-EOF &&
2446 [global]
2447 config = true
2448 EOF
2449 cat >custom-system-config <<-EOF &&
2450 [system]
2451 config = true
2452 EOF
2453
2454 cat >expect <<-EOF &&
2455 global xdg.config=true
2456 global home.config=true
2457 local local.config=true
2458 EOF
2459 git config ${mode_prefix}list --show-scope >output &&
2460 test_cmp expect output &&
2461
2462 cat >expect <<-EOF &&
2463 system system.config=true
2464 global global.config=true
2465 local local.config=true
2466 EOF
2467 GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=custom-system-config GIT_CONFIG_GLOBAL=custom-global-config \
2468 git config ${mode_prefix}list --show-scope >output &&
2469 test_cmp expect output &&
2470
2471 cat >expect <<-EOF &&
2472 local local.config=true
2473 EOF
2474 GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=/dev/null GIT_CONFIG_GLOBAL=/dev/null \
2475 git config ${mode_prefix}list --show-scope >output &&
2476 test_cmp expect output
2477 '
2478
2479 test_expect_success 'override global and system config with missing file' '
2480 test_must_fail env GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=/dev/null git config ${mode_prefix}list --global &&
2481 test_must_fail env GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=does-not-exist git config ${mode_prefix}list --system &&
2482 GIT_CONFIG_GLOBAL=does-not-exist GIT_CONFIG_SYSTEM=does-not-exist git version
2483 '
2484
2485 test_expect_success 'system override has no effect with GIT_CONFIG_NOSYSTEM' '
2486 # `git config --system` has different semantics compared to other
2487 # commands as it ignores GIT_CONFIG_NOSYSTEM. We thus test whether the
2488 # variable has an effect via a different proxy.
2489 cat >alias-config <<-EOF &&
2490 [alias]
2491 hello-world = !echo "hello world"
2492 EOF
2493 test_must_fail env GIT_CONFIG_NOSYSTEM=true GIT_CONFIG_SYSTEM=alias-config \
2494 git hello-world &&
2495 GIT_CONFIG_NOSYSTEM=false GIT_CONFIG_SYSTEM=alias-config \
2496 git hello-world >actual &&
2497 echo "hello world" >expect &&
2498 test_cmp expect actual
2499 '
2500
2501 test_expect_success 'write to overridden global and system config' '
2502 cat >expect <<EOF &&
2503 [config]
2504 key = value
2505 EOF
2506
2507 GIT_CONFIG_GLOBAL=write-to-global git config --global config.key value &&
2508 test_cmp expect write-to-global &&
2509
2510 GIT_CONFIG_SYSTEM=write-to-system git config --system config.key value &&
2511 test_cmp expect write-to-system
2512 '
2513
2514 for opt in --local --worktree
2515 do
2516 test_expect_success "$opt requires a repo" '
2517 # we expect 128 to ensure that we do not simply
2518 # fail to find anything and return code "1"
2519 test_expect_code 128 nongit git config $opt foo.bar
2520 '
2521 done
2522
2523 cat >.git/config <<-\EOF &&
2524 [section]
2525 foo = True
2526 number = 10
2527 big = 1M
2528 path = ~/dir
2529 red = red
2530 blue = Blue
2531 date = Fri Jun 4 15:46:55 2010
2532 missing=:(optional)no-such-path
2533 exists=:(optional)expect
2534 EOF
2535
2536 test_expect_success 'identical modern --type specifiers are allowed' '
2537 test_cmp_config 1048576 --type=int --type=int section.big
2538 '
2539
2540 test_expect_success 'identical legacy --type specifiers are allowed' '
2541 test_cmp_config 1048576 --int --int section.big
2542 '
2543
2544 test_expect_success 'identical mixed --type specifiers are allowed' '
2545 test_cmp_config 1048576 --int --type=int section.big
2546 '
2547
2548 test_expect_success 'non-identical modern --type specifiers are not allowed' '
2549 test_must_fail git config --type=int --type=bool section.big 2>error &&
2550 test_grep "only one type at a time" error
2551 '
2552
2553 test_expect_success 'non-identical legacy --type specifiers are not allowed' '
2554 test_must_fail git config --int --bool section.big 2>error &&
2555 test_grep "only one type at a time" error
2556 '
2557
2558 test_expect_success 'non-identical mixed --type specifiers are not allowed' '
2559 test_must_fail git config --type=int --bool section.big 2>error &&
2560 test_grep "only one type at a time" error
2561 '
2562
2563 test_expect_success '--type allows valid type specifiers' '
2564 test_cmp_config true --type=bool section.foo
2565 '
2566
2567 test_expect_success '--no-type unsets type specifiers' '
2568 test_cmp_config 10 --type=bool --no-type section.number
2569 '
2570
2571 test_expect_success 'unset type specifiers may be reset to conflicting ones' '
2572 test_cmp_config 1048576 --type=bool --no-type --type=int section.big
2573 '
2574
2575 test_expect_success 'list --type=int shows only canonicalizable int values' '
2576 cat >expect <<-EOF &&
2577 section.number=10
2578 section.big=1048576
2579 EOF
2580
2581 git config ${mode_prefix}list --type=int >actual 2>err &&
2582 test_cmp expect actual &&
2583 test_must_be_empty err
2584 '
2585
2586 test_expect_success 'list --type=bool shows only canonicalizable bool values' '
2587 cat >expect <<-EOF &&
2588 section.foo=true
2589 section.number=true
2590 section.big=true
2591 EOF
2592
2593 git config ${mode_prefix}list --type=bool >actual 2>err &&
2594 test_cmp expect actual &&
2595 test_must_be_empty err
2596 '
2597
2598 test_expect_success 'list --type=bool-or-int shows only canonicalizable values' '
2599 cat >expect <<-EOF &&
2600 section.foo=true
2601 section.number=10
2602 section.big=1048576
2603 EOF
2604
2605 git config ${mode_prefix}list --type=bool-or-int >actual 2>err &&
2606 test_cmp expect actual &&
2607 test_must_be_empty err
2608 '
2609
2610 test_expect_success 'list --type=path shows only canonicalizable path values' '
2611 cat >expect <<-EOF &&
2612 section.foo=True
2613 section.number=10
2614 section.big=1M
2615 section.path=$HOME/dir
2616 section.red=red
2617 section.blue=Blue
2618 section.date=Fri Jun 4 15:46:55 2010
2619 section.exists=expect
2620 EOF
2621
2622 git config ${mode_prefix}list --type=path >actual 2>err &&
2623 test_cmp expect actual &&
2624 test_must_be_empty err
2625 '
2626
2627 test_expect_success 'list --type=expiry-date shows only canonicalizable dates' '
2628 git config ${mode_prefix}list --type=expiry-date >actual 2>err &&
2629
2630 # section.number and section.big parse as relative dates that could
2631 # have clock skew in their results.
2632 test_grep section.big actual &&
2633 test_grep section.number actual &&
2634 test_grep "section.date=$(git config --type=expiry-date section.$key)" actual &&
2635 test_must_be_empty err
2636 '
2637
2638 test_expect_success 'list --type=color shows only canonicalizable color values' '
2639 cat >expect <<-EOF &&
2640 section.number=<>
2641 section.red=<RED>
2642 section.blue=<BLUE>
2643 EOF
2644
2645 git config ${mode_prefix}list --type=color >actual.raw 2>err &&
2646 test_decode_color <actual.raw >actual &&
2647 test_cmp expect actual &&
2648 test_must_be_empty err
2649 '
2650
2651 test_expect_success '--type rejects unknown specifiers' '
2652 test_must_fail git config --type=nonsense section.foo 2>error &&
2653 test_grep "unrecognized --type argument" error
2654 '
2655
2656 test_expect_success '--type=int requires at least one digit' '
2657 test_must_fail git config --type int --default m some.key >out 2>error &&
2658 test_grep "bad numeric config value" error &&
2659 test_must_be_empty out
2660 '
2661
2662 test_expect_success '--replace-all does not invent newlines' '
2663 q_to_tab >.git/config <<-\EOF &&
2664 [abc]key
2665 QkeepSection
2666 [xyz]
2667 Qkey = 1
2668 [abc]
2669 Qkey = a
2670 EOF
2671 q_to_tab >expect <<-\EOF &&
2672 [abc]
2673 QkeepSection
2674 [xyz]
2675 Qkey = 1
2676 [abc]
2677 Qkey = b
2678 EOF
2679 git config ${mode_replace_all} abc.key b &&
2680 test_cmp expect .git/config
2681 '
2682
2683 test_expect_success 'set all config with value-pattern' '
2684 test_when_finished rm -f config initial &&
2685 git config --file=initial abc.key one &&
2686
2687 # no match => add new entry
2688 cp initial config &&
2689 git config --file=config abc.key two a+ &&
2690 git config ${mode_prefix}list --file=config >actual &&
2691 cat >expect <<-\EOF &&
2692 abc.key=one
2693 abc.key=two
2694 EOF
2695 test_cmp expect actual &&
2696
2697 # multiple matches => failure
2698 test_must_fail git config --file=config abc.key three o+ 2>err &&
2699 test_grep "has multiple values" err &&
2700
2701 # multiple values, no match => add
2702 git config --file=config abc.key three a+ &&
2703 git config ${mode_prefix}list --file=config >actual &&
2704 cat >expect <<-\EOF &&
2705 abc.key=one
2706 abc.key=two
2707 abc.key=three
2708 EOF
2709 test_cmp expect actual &&
2710
2711 # single match => replace
2712 git config --file=config abc.key four h+ &&
2713 git config ${mode_prefix}list --file=config >actual &&
2714 cat >expect <<-\EOF &&
2715 abc.key=one
2716 abc.key=two
2717 abc.key=four
2718 EOF
2719 test_cmp expect actual
2720 '
2721
2722 test_expect_success '--replace-all and value-pattern' '
2723 test_when_finished rm -f config &&
2724 git config --file=config --add abc.key one &&
2725 git config --file=config --add abc.key two &&
2726 git config --file=config --add abc.key three &&
2727 git config --file=config --replace-all abc.key four "o+" &&
2728 git config ${mode_prefix}list --file=config >actual &&
2729 cat >expect <<-\EOF &&
2730 abc.key=four
2731 abc.key=three
2732 EOF
2733 test_cmp expect actual
2734 '
2735
2736 test_expect_success 'refuse --fixed-value for incompatible actions' '
2737 test_when_finished rm -f config &&
2738 git config --file=config dev.null bogus &&
2739
2740 # These modes do not allow --fixed-value at all
2741 test_must_fail git config --file=config --fixed-value --add dev.null bogus &&
2742 test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus &&
2743 test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus &&
2744 test_must_fail git config ${mode_prefix}rename-section --file=config --fixed-value dev null &&
2745 test_must_fail git config ${mode_prefix}remove-section --file=config --fixed-value dev &&
2746 test_must_fail git config ${mode_prefix}list --file=config --fixed-value &&
2747 test_must_fail git config --file=config --fixed-value --get-color dev.null &&
2748 test_must_fail git config --file=config --fixed-value --get-colorbool dev.null &&
2749
2750 # These modes complain when --fixed-value has no value-pattern
2751 test_must_fail git config ${mode_set} --file=config --fixed-value dev.null bogus &&
2752 test_must_fail git config ${mode_replace_all} --file=config --fixed-value dev.null bogus &&
2753 test_must_fail git config ${mode_prefix}get --file=config --fixed-value dev.null &&
2754 test_must_fail git config ${mode_get_all} --file=config --fixed-value dev.null &&
2755 test_must_fail git config ${mode_get_regexp} --file=config --fixed-value "dev.*" &&
2756 test_must_fail git config ${mode_unset} --file=config --fixed-value dev.null &&
2757 test_must_fail git config ${mode_unset_all} --file=config --fixed-value dev.null
2758 '
2759
2760 test_expect_success '--fixed-value uses exact string matching' '
2761 test_when_finished rm -f config initial &&
2762 META="a+b*c?d[e]f.g" &&
2763 git config --file=initial fixed.test "$META" &&
2764
2765 cp initial config &&
2766 git config --file=config fixed.test bogus "$META" &&
2767 git config ${mode_prefix}list --file=config >actual &&
2768 cat >expect <<-EOF &&
2769 fixed.test=$META
2770 fixed.test=bogus
2771 EOF
2772 test_cmp expect actual &&
2773
2774 cp initial config &&
2775 git config --file=config --fixed-value fixed.test bogus "$META" &&
2776 git config ${mode_prefix}list --file=config >actual &&
2777 cat >expect <<-\EOF &&
2778 fixed.test=bogus
2779 EOF
2780 test_cmp expect actual &&
2781
2782 cp initial config &&
2783 test_must_fail git config --file=config --unset fixed.test "$META" &&
2784 git config --file=config --fixed-value --unset fixed.test "$META" &&
2785 test_must_fail git config ${mode_get} --file=config fixed.test &&
2786
2787 cp initial config &&
2788 test_must_fail git config unset --file=config --value="$META" fixed.test &&
2789 git config unset --file=config --fixed-value --value="$META" fixed.test &&
2790 test_must_fail git config ${mode_get} --file=config fixed.test &&
2791
2792 cp initial config &&
2793 test_must_fail git config --file=config --unset-all fixed.test "$META" &&
2794 git config --file=config --fixed-value --unset-all fixed.test "$META" &&
2795 test_must_fail git config ${mode_get} --file=config fixed.test &&
2796
2797 cp initial config &&
2798 git config --file=config fixed.test bogus "$META" &&
2799 git config ${mode_prefix}list --file=config >actual &&
2800 cat >expect <<-EOF &&
2801 fixed.test=$META
2802 fixed.test=bogus
2803 EOF
2804 test_cmp expect actual &&
2805
2806 git config --file=config --fixed-value --replace-all fixed.test bogus "$META" &&
2807 git config ${mode_prefix}list --file=config >actual &&
2808 cat >expect <<-EOF &&
2809 fixed.test=bogus
2810 fixed.test=bogus
2811 EOF
2812 test_cmp expect actual
2813 '
2814
2815 test_expect_success '--get and --get-all with --fixed-value' '
2816 test_when_finished rm -f config &&
2817 META="a+b*c?d[e]f.g" &&
2818 git config --file=config fixed.test bogus &&
2819 git config --file=config --add fixed.test "$META" &&
2820
2821 git config --file=config --get fixed.test bogus &&
2822 git config get --file=config --value=bogus fixed.test &&
2823 test_must_fail git config --file=config --get fixed.test "$META" &&
2824 test_must_fail git config get --file=config --value="$META" fixed.test &&
2825 git config --file=config --get --fixed-value fixed.test "$META" &&
2826 git config get --file=config --fixed-value --value="$META" fixed.test &&
2827 test_must_fail git config --file=config --get --fixed-value fixed.test non-existent &&
2828
2829 git config --file=config --get-all fixed.test bogus &&
2830 git config get --all --file=config --value=bogus fixed.test &&
2831 test_must_fail git config --file=config --get-all fixed.test "$META" &&
2832 test_must_fail git config get --all --file=config --value="$META" fixed.test &&
2833 git config --file=config --get-all --fixed-value fixed.test "$META" &&
2834 git config get --all --file=config --value="$META" --fixed-value fixed.test &&
2835 test_must_fail git config --file=config --get-all --fixed-value fixed.test non-existent &&
2836
2837 git config --file=config --get-regexp fixed+ bogus &&
2838 git config get --regexp --file=config --value=bogus fixed+ &&
2839 test_must_fail git config --file=config --get-regexp fixed+ "$META" &&
2840 test_must_fail git config get --regexp --file=config --value="$META" fixed+ &&
2841 git config --file=config --get-regexp --fixed-value fixed+ "$META" &&
2842 git config get --regexp --file=config --fixed-value --value="$META" fixed+ &&
2843 test_must_fail git config --file=config --get-regexp --fixed-value fixed+ non-existent
2844 '
2845
2846 test_expect_success '--fixed-value with value-less configuration' '
2847 test_when_finished rm -f config &&
2848 cat >config <<-\EOF &&
2849 [section]
2850 key
2851 EOF
2852 git config --file=config --fixed-value section.key value pattern
2853 '
2854
2855 test_expect_success 'includeIf.hasconfig:remote.*.url' '
2856 git init hasremoteurlTest &&
2857 test_when_finished "rm -rf hasremoteurlTest" &&
2858
2859 cat >include-this <<-\EOF &&
2860 [user]
2861 this = this-is-included
2862 EOF
2863 cat >dont-include-that <<-\EOF &&
2864 [user]
2865 that = that-is-not-included
2866 EOF
2867 cat >>hasremoteurlTest/.git/config <<-EOF &&
2868 [includeIf "hasconfig:remote.*.url:foourl"]
2869 path = "$(pwd)/include-this"
2870 [includeIf "hasconfig:remote.*.url:barurl"]
2871 path = "$(pwd)/dont-include-that"
2872 [remote "foo"]
2873 url = foourl
2874 EOF
2875
2876 echo this-is-included >expect-this &&
2877 git -C hasremoteurlTest config --get user.this >actual-this &&
2878 test_cmp expect-this actual-this &&
2879
2880 test_must_fail git -C hasremoteurlTest config --get user.that
2881 '
2882
2883 test_expect_success 'includeIf.hasconfig:remote.*.url respects last-config-wins' '
2884 git init hasremoteurlTest &&
2885 test_when_finished "rm -rf hasremoteurlTest" &&
2886
2887 cat >include-two-three <<-\EOF &&
2888 [user]
2889 two = included-config
2890 three = included-config
2891 EOF
2892 cat >>hasremoteurlTest/.git/config <<-EOF &&
2893 [remote "foo"]
2894 url = foourl
2895 [user]
2896 one = main-config
2897 two = main-config
2898 [includeIf "hasconfig:remote.*.url:foourl"]
2899 path = "$(pwd)/include-two-three"
2900 [user]
2901 three = main-config
2902 EOF
2903
2904 echo main-config >expect-main-config &&
2905 echo included-config >expect-included-config &&
2906
2907 git -C hasremoteurlTest config --get user.one >actual &&
2908 test_cmp expect-main-config actual &&
2909
2910 git -C hasremoteurlTest config --get user.two >actual &&
2911 test_cmp expect-included-config actual &&
2912
2913 git -C hasremoteurlTest config --get user.three >actual &&
2914 test_cmp expect-main-config actual
2915 '
2916
2917 test_expect_success 'includeIf.hasconfig:remote.*.url globs' '
2918 git init hasremoteurlTest &&
2919 test_when_finished "rm -rf hasremoteurlTest" &&
2920
2921 printf "[user]\ndss = yes\n" >double-star-start &&
2922 printf "[user]\ndse = yes\n" >double-star-end &&
2923 printf "[user]\ndsm = yes\n" >double-star-middle &&
2924 printf "[user]\nssm = yes\n" >single-star-middle &&
2925 printf "[user]\nno = no\n" >no &&
2926
2927 cat >>hasremoteurlTest/.git/config <<-EOF &&
2928 [remote "foo"]
2929 url = https://foo/bar/baz
2930 [includeIf "hasconfig:remote.*.url:**/baz"]
2931 path = "$(pwd)/double-star-start"
2932 [includeIf "hasconfig:remote.*.url:**/nomatch"]
2933 path = "$(pwd)/no"
2934 [includeIf "hasconfig:remote.*.url:https:/**"]
2935 path = "$(pwd)/double-star-end"
2936 [includeIf "hasconfig:remote.*.url:nomatch:/**"]
2937 path = "$(pwd)/no"
2938 [includeIf "hasconfig:remote.*.url:https:/**/baz"]
2939 path = "$(pwd)/double-star-middle"
2940 [includeIf "hasconfig:remote.*.url:https:/**/nomatch"]
2941 path = "$(pwd)/no"
2942 [includeIf "hasconfig:remote.*.url:https://*/bar/baz"]
2943 path = "$(pwd)/single-star-middle"
2944 [includeIf "hasconfig:remote.*.url:https://*/baz"]
2945 path = "$(pwd)/no"
2946 EOF
2947
2948 git -C hasremoteurlTest config --get user.dss &&
2949 git -C hasremoteurlTest config --get user.dse &&
2950 git -C hasremoteurlTest config --get user.dsm &&
2951 git -C hasremoteurlTest config --get user.ssm &&
2952 test_must_fail git -C hasremoteurlTest config --get user.no
2953 '
2954
2955 test_expect_success 'includeIf.hasconfig:remote.*.url forbids remote url in such included files' '
2956 git init hasremoteurlTest &&
2957 test_when_finished "rm -rf hasremoteurlTest" &&
2958
2959 cat >include-with-url <<-\EOF &&
2960 [remote "bar"]
2961 url = barurl
2962 EOF
2963 cat >>hasremoteurlTest/.git/config <<-EOF &&
2964 [includeIf "hasconfig:remote.*.url:foourl"]
2965 path = "$(pwd)/include-with-url"
2966 EOF
2967
2968 # test with any Git command
2969 test_must_fail git -C hasremoteurlTest status 2>err &&
2970 test_grep "fatal: remote URLs cannot be configured in file directly or indirectly included by includeIf.hasconfig:remote.*.url" err
2971 '
2972
2973 test_expect_success 'negated mode causes failure' '
2974 test_must_fail git config --no-get 2>err &&
2975 test_grep "unknown option \`no-get${SQ}" err
2976 '
2977
2978 test_expect_success 'specifying multiple modes causes failure' '
2979 cat >expect <<-EOF &&
2980 error: options ${SQ}--get-all${SQ} and ${SQ}--get${SQ} cannot be used together
2981 EOF
2982 test_must_fail git config --get --get-all 2>err &&
2983 test_cmp expect err
2984 '
2985
2986 test_expect_success 'writing to stdin is rejected' '
2987 echo "fatal: writing to stdin is not supported" >expect &&
2988 test_must_fail git config ${mode_set} --file - foo.bar baz 2>err &&
2989 test_cmp expect err
2990 '
2991
2992 done
2993
2994 test_expect_success 'writing value with trailing CR not stripped on read' '
2995 test_when_finished "rm -rf cr-test" &&
2996
2997 printf "bar\r\n" >expect &&
2998 git init cr-test &&
2999 git -C cr-test config set core.foo $(printf "bar\r") &&
3000 git -C cr-test config get core.foo >actual &&
3001
3002 test_cmp expect actual
3003 '
3004
3005 test_expect_success 'writing config fails immediately with core.configLockTimeout=0' '
3006 test_when_finished "rm -f .git/config.lock" &&
3007 >.git/config.lock &&
3008 test_must_fail git -c core.configLockTimeout=0 config foo.bar baz 2>err &&
3009 test_grep "could not lock config file" err
3010 '
3011
3012 test_expect_success 'writing config retries until lock is released' '
3013 test_when_finished "rm -f .git/config.lock" &&
3014 >.git/config.lock &&
3015 {
3016 ( sleep 1 && rm -f .git/config.lock ) &
3017 } &&
3018 git -c core.configLockTimeout=5000 config retried.key value &&
3019 test "$(git config retried.key)" = value
3020 '
3021
3022 test_done