usage: trace2 BUG() invocations
[git] / t / t1300-config.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2005 Johannes Schindelin
4 #
5
6 test_description='Test git config in different settings'
7
8 . ./test-lib.sh
9
10 test_expect_success 'clear default config' '
11         rm -f .git/config
12 '
13
14 cat > expect << EOF
15 [section]
16         penguin = little blue
17 EOF
18 test_expect_success 'initial' '
19         git config section.penguin "little blue" &&
20         test_cmp expect .git/config
21 '
22
23 cat > expect << EOF
24 [section]
25         penguin = little blue
26         Movie = BadPhysics
27 EOF
28 test_expect_success 'mixed case' '
29         git config Section.Movie BadPhysics &&
30         test_cmp expect .git/config
31 '
32
33 cat > expect << EOF
34 [section]
35         penguin = little blue
36         Movie = BadPhysics
37 [Sections]
38         WhatEver = Second
39 EOF
40 test_expect_success 'similar section' '
41         git config Sections.WhatEver Second &&
42         test_cmp expect .git/config
43 '
44
45 cat > expect << EOF
46 [section]
47         penguin = little blue
48         Movie = BadPhysics
49         UPPERCASE = true
50 [Sections]
51         WhatEver = Second
52 EOF
53 test_expect_success 'uppercase section' '
54         git config SECTION.UPPERCASE true &&
55         test_cmp expect .git/config
56 '
57
58 test_expect_success 'replace with non-match' '
59         git config section.penguin kingpin !blue
60 '
61
62 test_expect_success 'replace with non-match (actually matching)' '
63         git config section.penguin "very blue" !kingpin
64 '
65
66 cat > expect << EOF
67 [section]
68         penguin = very blue
69         Movie = BadPhysics
70         UPPERCASE = true
71         penguin = kingpin
72 [Sections]
73         WhatEver = Second
74 EOF
75
76 test_expect_success 'non-match result' 'test_cmp expect .git/config'
77
78 test_expect_success 'find mixed-case key by canonical name' '
79         test_cmp_config Second sections.whatever
80 '
81
82 test_expect_success 'find mixed-case key by non-canonical name' '
83         test_cmp_config Second SeCtIoNs.WhAtEvEr
84 '
85
86 test_expect_success 'subsections are not canonicalized by git-config' '
87         cat >>.git/config <<-\EOF &&
88         [section.SubSection]
89         key = one
90         [section "SubSection"]
91         key = two
92         EOF
93         test_cmp_config one section.subsection.key &&
94         test_cmp_config two section.SubSection.key
95 '
96
97 cat > .git/config <<\EOF
98 [alpha]
99 bar = foo
100 [beta]
101 baz = multiple \
102 lines
103 foo = bar
104 EOF
105
106 test_expect_success 'unset with cont. lines' '
107         git config --unset beta.baz
108 '
109
110 cat > expect <<\EOF
111 [alpha]
112 bar = foo
113 [beta]
114 foo = bar
115 EOF
116
117 test_expect_success 'unset with cont. lines is correct' 'test_cmp expect .git/config'
118
119 cat > .git/config << EOF
120 [beta] ; silly comment # another comment
121 noIndent= sillyValue ; 'nother silly comment
122
123 # empty line
124                 ; comment
125                 haha   ="beta" # last silly comment
126 haha = hello
127         haha = bello
128 [nextSection] noNewline = ouch
129 EOF
130
131 cp .git/config .git/config2
132
133 test_expect_success 'multiple unset' '
134         git config --unset-all beta.haha
135 '
136
137 cat > expect << EOF
138 [beta] ; silly comment # another comment
139 noIndent= sillyValue ; 'nother silly comment
140
141 # empty line
142                 ; comment
143 [nextSection] noNewline = ouch
144 EOF
145
146 test_expect_success 'multiple unset is correct' '
147         test_cmp expect .git/config
148 '
149
150 cp .git/config2 .git/config
151
152 test_expect_success '--replace-all missing value' '
153         test_must_fail git config --replace-all beta.haha &&
154         test_cmp .git/config2 .git/config
155 '
156
157 rm .git/config2
158
159 test_expect_success '--replace-all' '
160         git config --replace-all beta.haha gamma
161 '
162
163 cat > expect << EOF
164 [beta] ; silly comment # another comment
165 noIndent= sillyValue ; 'nother silly comment
166
167 # empty line
168                 ; comment
169         haha = gamma
170 [nextSection] noNewline = ouch
171 EOF
172
173 test_expect_success 'all replaced' '
174         test_cmp expect .git/config
175 '
176
177 cat > expect << EOF
178 [beta] ; silly comment # another comment
179 noIndent= sillyValue ; 'nother silly comment
180
181 # empty line
182                 ; comment
183         haha = alpha
184 [nextSection] noNewline = ouch
185 EOF
186 test_expect_success 'really mean test' '
187         git config beta.haha alpha &&
188         test_cmp expect .git/config
189 '
190
191 cat > expect << EOF
192 [beta] ; silly comment # another comment
193 noIndent= sillyValue ; 'nother silly comment
194
195 # empty line
196                 ; comment
197         haha = alpha
198 [nextSection]
199         nonewline = wow
200 EOF
201 test_expect_success 'really really mean test' '
202         git config nextsection.nonewline wow &&
203         test_cmp expect .git/config
204 '
205
206 test_expect_success 'get value' '
207         test_cmp_config alpha beta.haha
208 '
209
210 cat > expect << EOF
211 [beta] ; silly comment # another comment
212 noIndent= sillyValue ; 'nother silly comment
213
214 # empty line
215                 ; comment
216 [nextSection]
217         nonewline = wow
218 EOF
219 test_expect_success 'unset' '
220         git config --unset beta.haha &&
221         test_cmp expect .git/config
222 '
223
224 cat > expect << EOF
225 [beta] ; silly comment # another comment
226 noIndent= sillyValue ; 'nother silly comment
227
228 # empty line
229                 ; comment
230 [nextSection]
231         nonewline = wow
232         NoNewLine = wow2 for me
233 EOF
234 test_expect_success 'multivar' '
235         git config nextsection.NoNewLine "wow2 for me" "for me$" &&
236         test_cmp expect .git/config
237 '
238
239 test_expect_success 'non-match' '
240         git config --get nextsection.nonewline !for
241 '
242
243 test_expect_success 'non-match value' '
244         test_cmp_config wow --get nextsection.nonewline !for
245 '
246
247 test_expect_success 'multi-valued get returns final one' '
248         test_cmp_config "wow2 for me" --get nextsection.nonewline
249 '
250
251 test_expect_success 'multi-valued get-all returns all' '
252         cat >expect <<-\EOF &&
253         wow
254         wow2 for me
255         EOF
256         git config --get-all nextsection.nonewline >actual &&
257         test_cmp expect actual
258 '
259
260 cat > expect << EOF
261 [beta] ; silly comment # another comment
262 noIndent= sillyValue ; 'nother silly comment
263
264 # empty line
265                 ; comment
266 [nextSection]
267         nonewline = wow3
268         NoNewLine = wow2 for me
269 EOF
270 test_expect_success 'multivar replace' '
271         git config nextsection.nonewline "wow3" "wow$" &&
272         test_cmp expect .git/config
273 '
274
275 test_expect_success 'ambiguous unset' '
276         test_must_fail git config --unset nextsection.nonewline
277 '
278
279 test_expect_success 'invalid unset' '
280         test_must_fail git config --unset somesection.nonewline
281 '
282
283 cat > expect << EOF
284 [beta] ; silly comment # another comment
285 noIndent= sillyValue ; 'nother silly comment
286
287 # empty line
288                 ; comment
289 [nextSection]
290         NoNewLine = wow2 for me
291 EOF
292
293 test_expect_success 'multivar unset' '
294         git config --unset nextsection.nonewline "wow3$" &&
295         test_cmp expect .git/config
296 '
297
298 test_expect_success 'invalid key' 'test_must_fail git config inval.2key blabla'
299
300 test_expect_success 'correct key' 'git config 123456.a123 987'
301
302 test_expect_success 'hierarchical section' '
303         git config Version.1.2.3eX.Alpha beta
304 '
305
306 cat > expect << EOF
307 [beta] ; silly comment # another comment
308 noIndent= sillyValue ; 'nother silly comment
309
310 # empty line
311                 ; comment
312 [nextSection]
313         NoNewLine = wow2 for me
314 [123456]
315         a123 = 987
316 [Version "1.2.3eX"]
317         Alpha = beta
318 EOF
319
320 test_expect_success 'hierarchical section value' '
321         test_cmp expect .git/config
322 '
323
324 cat > expect << EOF
325 beta.noindent=sillyValue
326 nextsection.nonewline=wow2 for me
327 123456.a123=987
328 version.1.2.3eX.alpha=beta
329 EOF
330
331 test_expect_success 'working --list' '
332         git config --list > output &&
333         test_cmp expect output
334 '
335 test_expect_success '--list without repo produces empty output' '
336         git --git-dir=nonexistent config --list >output &&
337         test_must_be_empty output
338 '
339
340 cat > expect << EOF
341 beta.noindent
342 nextsection.nonewline
343 123456.a123
344 version.1.2.3eX.alpha
345 EOF
346
347 test_expect_success '--name-only --list' '
348         git config --name-only --list >output &&
349         test_cmp expect output
350 '
351
352 cat > expect << EOF
353 beta.noindent sillyValue
354 nextsection.nonewline wow2 for me
355 EOF
356
357 test_expect_success '--get-regexp' '
358         git config --get-regexp in >output &&
359         test_cmp expect output
360 '
361
362 cat > expect << EOF
363 beta.noindent
364 nextsection.nonewline
365 EOF
366
367 test_expect_success '--name-only --get-regexp' '
368         git config --name-only --get-regexp in >output &&
369         test_cmp expect output
370 '
371
372 cat > expect << EOF
373 wow2 for me
374 wow4 for you
375 EOF
376
377 test_expect_success '--add' '
378         git config --add nextsection.nonewline "wow4 for you" &&
379         git config --get-all nextsection.nonewline > output &&
380         test_cmp expect output
381 '
382
383 cat > .git/config << EOF
384 [novalue]
385         variable
386 [emptyvalue]
387         variable =
388 EOF
389
390 test_expect_success 'get variable with no value' '
391         git config --get novalue.variable ^$
392 '
393
394 test_expect_success 'get variable with empty value' '
395         git config --get emptyvalue.variable ^$
396 '
397
398 echo novalue.variable > expect
399
400 test_expect_success 'get-regexp variable with no value' '
401         git config --get-regexp novalue > output &&
402         test_cmp expect output
403 '
404
405 echo 'novalue.variable true' > expect
406
407 test_expect_success 'get-regexp --bool variable with no value' '
408         git config --bool --get-regexp novalue > output &&
409         test_cmp expect output
410 '
411
412 echo 'emptyvalue.variable ' > expect
413
414 test_expect_success 'get-regexp variable with empty value' '
415         git config --get-regexp emptyvalue > output &&
416         test_cmp expect output
417 '
418
419 echo true > expect
420
421 test_expect_success 'get bool variable with no value' '
422         git config --bool novalue.variable > output &&
423         test_cmp expect output
424 '
425
426 echo false > expect
427
428 test_expect_success 'get bool variable with empty value' '
429         git config --bool emptyvalue.variable > output &&
430         test_cmp expect output
431 '
432
433 test_expect_success 'no arguments, but no crash' '
434         test_must_fail git config >output 2>&1 &&
435         test_i18ngrep usage output
436 '
437
438 cat > .git/config << EOF
439 [a.b]
440         c = d
441 EOF
442
443 cat > expect << EOF
444 [a.b]
445         c = d
446 [a]
447         x = y
448 EOF
449
450 test_expect_success 'new section is partial match of another' '
451         git config a.x y &&
452         test_cmp expect .git/config
453 '
454
455 cat > expect << EOF
456 [a.b]
457         c = d
458 [a]
459         x = y
460         b = c
461 [b]
462         x = y
463 EOF
464
465 test_expect_success 'new variable inserts into proper section' '
466         git config b.x y &&
467         git config a.b c &&
468         test_cmp expect .git/config
469 '
470
471 test_expect_success 'alternative --file (non-existing file should fail)' '
472         test_must_fail git config --file non-existing-config -l &&
473         test_must_fail git config --file non-existing-config test.xyzzy
474 '
475
476 cat > other-config << EOF
477 [ein]
478         bahn = strasse
479 EOF
480
481 cat > expect << EOF
482 ein.bahn=strasse
483 EOF
484
485 test_expect_success 'alternative GIT_CONFIG' '
486         GIT_CONFIG=other-config git config --list >output &&
487         test_cmp expect output
488 '
489
490 test_expect_success 'alternative GIT_CONFIG (--file)' '
491         git config --file other-config --list >output &&
492         test_cmp expect output
493 '
494
495 test_expect_success 'alternative GIT_CONFIG (--file=-)' '
496         git config --file - --list <other-config >output &&
497         test_cmp expect output
498 '
499
500 test_expect_success 'setting a value in stdin is an error' '
501         test_must_fail git config --file - some.value foo
502 '
503
504 test_expect_success 'editing stdin is an error' '
505         test_must_fail git config --file - --edit
506 '
507
508 test_expect_success 'refer config from subdirectory' '
509         mkdir x &&
510         test_cmp_config -C x strasse --file=../other-config --get ein.bahn
511 '
512
513 cat > expect << EOF
514 [ein]
515         bahn = strasse
516 [anwohner]
517         park = ausweis
518 EOF
519
520 test_expect_success '--set in alternative file' '
521         git config --file=other-config anwohner.park ausweis &&
522         test_cmp expect other-config
523 '
524
525 cat > .git/config << EOF
526 # Hallo
527         #Bello
528 [branch "eins"]
529         x = 1
530 [branch.eins]
531         y = 1
532         [branch "1 234 blabl/a"]
533 weird
534 EOF
535
536 test_expect_success 'rename section' '
537         git config --rename-section branch.eins branch.zwei
538 '
539
540 cat > expect << EOF
541 # Hallo
542         #Bello
543 [branch "zwei"]
544         x = 1
545 [branch "zwei"]
546         y = 1
547         [branch "1 234 blabl/a"]
548 weird
549 EOF
550
551 test_expect_success 'rename succeeded' '
552         test_cmp expect .git/config
553 '
554
555 test_expect_success 'rename non-existing section' '
556         test_must_fail git config --rename-section \
557                 branch."world domination" branch.drei
558 '
559
560 test_expect_success 'rename succeeded' '
561         test_cmp expect .git/config
562 '
563
564 test_expect_success 'rename another section' '
565         git config --rename-section branch."1 234 blabl/a" branch.drei
566 '
567
568 cat > expect << EOF
569 # Hallo
570         #Bello
571 [branch "zwei"]
572         x = 1
573 [branch "zwei"]
574         y = 1
575 [branch "drei"]
576 weird
577 EOF
578
579 test_expect_success 'rename succeeded' '
580         test_cmp expect .git/config
581 '
582
583 cat >> .git/config << EOF
584 [branch "vier"] z = 1
585 EOF
586
587 test_expect_success 'rename a section with a var on the same line' '
588         git config --rename-section branch.vier branch.zwei
589 '
590
591 cat > expect << EOF
592 # Hallo
593         #Bello
594 [branch "zwei"]
595         x = 1
596 [branch "zwei"]
597         y = 1
598 [branch "drei"]
599 weird
600 [branch "zwei"]
601         z = 1
602 EOF
603
604 test_expect_success 'rename succeeded' '
605         test_cmp expect .git/config
606 '
607
608 test_expect_success 'renaming empty section name is rejected' '
609         test_must_fail git config --rename-section branch.zwei ""
610 '
611
612 test_expect_success 'renaming to bogus section is rejected' '
613         test_must_fail git config --rename-section branch.zwei "bogus name"
614 '
615
616 cat >> .git/config << EOF
617   [branch "zwei"] a = 1 [branch "vier"]
618 EOF
619
620 test_expect_success 'remove section' '
621         git config --remove-section branch.zwei
622 '
623
624 cat > expect << EOF
625 # Hallo
626         #Bello
627 [branch "drei"]
628 weird
629 EOF
630
631 test_expect_success 'section was removed properly' '
632         test_cmp expect .git/config
633 '
634
635 cat > expect << EOF
636 [gitcvs]
637         enabled = true
638         dbname = %Ggitcvs2.%a.%m.sqlite
639 [gitcvs "ext"]
640         dbname = %Ggitcvs1.%a.%m.sqlite
641 EOF
642
643 test_expect_success 'section ending' '
644         rm -f .git/config &&
645         git config gitcvs.enabled true &&
646         git config gitcvs.ext.dbname %Ggitcvs1.%a.%m.sqlite &&
647         git config gitcvs.dbname %Ggitcvs2.%a.%m.sqlite &&
648         test_cmp expect .git/config
649
650 '
651
652 test_expect_success numbers '
653         git config kilo.gram 1k &&
654         git config mega.ton 1m &&
655         echo 1024 >expect &&
656         echo 1048576 >>expect &&
657         git config --int --get kilo.gram >actual &&
658         git config --int --get mega.ton >>actual &&
659         test_cmp expect actual
660 '
661
662 test_expect_success '--int is at least 64 bits' '
663         git config giga.watts 121g &&
664         echo  >expect &&
665         test_cmp_config 129922760704 --int --get giga.watts
666 '
667
668 test_expect_success 'invalid unit' '
669         git config aninvalid.unit "1auto" &&
670         test_cmp_config 1auto aninvalid.unit &&
671         test_must_fail git config --int --get aninvalid.unit 2>actual &&
672         test_i18ngrep "bad numeric config value .1auto. for .aninvalid.unit. in file .git/config: invalid unit" actual
673 '
674
675 test_expect_success 'line number is reported correctly' '
676         printf "[bool]\n\tvar\n" >invalid &&
677         test_must_fail git config -f invalid --path bool.var 2>actual &&
678         test_i18ngrep "line 2" actual
679 '
680
681 test_expect_success 'invalid stdin config' '
682         echo "[broken" | test_must_fail git config --list --file - >output 2>&1 &&
683         test_i18ngrep "bad config line 1 in standard input" output
684 '
685
686 cat > expect << EOF
687 true
688 false
689 true
690 false
691 true
692 false
693 true
694 false
695 EOF
696
697 test_expect_success bool '
698
699         git config bool.true1 01 &&
700         git config bool.true2 -1 &&
701         git config bool.true3 YeS &&
702         git config bool.true4 true &&
703         git config bool.false1 000 &&
704         git config bool.false2 "" &&
705         git config bool.false3 nO &&
706         git config bool.false4 FALSE &&
707         rm -f result &&
708         for i in 1 2 3 4
709         do
710             git config --bool --get bool.true$i >>result
711             git config --bool --get bool.false$i >>result
712         done &&
713         test_cmp expect result'
714
715 test_expect_success 'invalid bool (--get)' '
716
717         git config bool.nobool foobar &&
718         test_must_fail git config --bool --get bool.nobool'
719
720 test_expect_success 'invalid bool (set)' '
721
722         test_must_fail git config --bool bool.nobool foobar'
723
724 cat > expect <<\EOF
725 [bool]
726         true1 = true
727         true2 = true
728         true3 = true
729         true4 = true
730         false1 = false
731         false2 = false
732         false3 = false
733         false4 = false
734 EOF
735
736 test_expect_success 'set --bool' '
737
738         rm -f .git/config &&
739         git config --bool bool.true1 01 &&
740         git config --bool bool.true2 -1 &&
741         git config --bool bool.true3 YeS &&
742         git config --bool bool.true4 true &&
743         git config --bool bool.false1 000 &&
744         git config --bool bool.false2 "" &&
745         git config --bool bool.false3 nO &&
746         git config --bool bool.false4 FALSE &&
747         test_cmp expect .git/config'
748
749 cat > expect <<\EOF
750 [int]
751         val1 = 1
752         val2 = -1
753         val3 = 5242880
754 EOF
755
756 test_expect_success 'set --int' '
757
758         rm -f .git/config &&
759         git config --int int.val1 01 &&
760         git config --int int.val2 -1 &&
761         git config --int int.val3 5m &&
762         test_cmp expect .git/config
763 '
764
765 test_expect_success 'get --bool-or-int' '
766         cat >.git/config <<-\EOF &&
767         [bool]
768         true1
769         true2 = true
770         false = false
771         [int]
772         int1 = 0
773         int2 = 1
774         int3 = -1
775         EOF
776         cat >expect <<-\EOF &&
777         true
778         true
779         false
780         0
781         1
782         -1
783         EOF
784         {
785                 git config --bool-or-int bool.true1 &&
786                 git config --bool-or-int bool.true2 &&
787                 git config --bool-or-int bool.false &&
788                 git config --bool-or-int int.int1 &&
789                 git config --bool-or-int int.int2 &&
790                 git config --bool-or-int int.int3
791         } >actual &&
792         test_cmp expect actual
793 '
794
795 cat >expect <<\EOF
796 [bool]
797         true1 = true
798         false1 = false
799         true2 = true
800         false2 = false
801 [int]
802         int1 = 0
803         int2 = 1
804         int3 = -1
805 EOF
806
807 test_expect_success 'set --bool-or-int' '
808         rm -f .git/config &&
809         git config --bool-or-int bool.true1 true &&
810         git config --bool-or-int bool.false1 false &&
811         git config --bool-or-int bool.true2 yes &&
812         git config --bool-or-int bool.false2 no &&
813         git config --bool-or-int int.int1 0 &&
814         git config --bool-or-int int.int2 1 &&
815         git config --bool-or-int int.int3 -1 &&
816         test_cmp expect .git/config
817 '
818
819 cat >expect <<\EOF
820 [path]
821         home = ~/
822         normal = /dev/null
823         trailingtilde = foo~
824 EOF
825
826 test_expect_success !MINGW 'set --path' '
827         rm -f .git/config &&
828         git config --path path.home "~/" &&
829         git config --path path.normal "/dev/null" &&
830         git config --path path.trailingtilde "foo~" &&
831         test_cmp expect .git/config'
832
833 if test_have_prereq !MINGW && test "${HOME+set}"
834 then
835         test_set_prereq HOMEVAR
836 fi
837
838 cat >expect <<EOF
839 $HOME/
840 /dev/null
841 foo~
842 EOF
843
844 test_expect_success HOMEVAR 'get --path' '
845         git config --get --path path.home > result &&
846         git config --get --path path.normal >> result &&
847         git config --get --path path.trailingtilde >> result &&
848         test_cmp expect result
849 '
850
851 cat >expect <<\EOF
852 /dev/null
853 foo~
854 EOF
855
856 test_expect_success !MINGW 'get --path copes with unset $HOME' '
857         (
858                 sane_unset HOME &&
859                 test_must_fail git config --get --path path.home \
860                         >result 2>msg &&
861                 git config --get --path path.normal >>result &&
862                 git config --get --path path.trailingtilde >>result
863         ) &&
864         test_i18ngrep "[Ff]ailed to expand.*~/" msg &&
865         test_cmp expect result
866 '
867
868 test_expect_success 'get --path barfs on boolean variable' '
869         echo "[path]bool" >.git/config &&
870         test_must_fail git config --get --path path.bool
871 '
872
873 test_expect_success 'get --expiry-date' '
874         rel="3.weeks.5.days.00:00" &&
875         rel_out="$rel ->" &&
876         cat >.git/config <<-\EOF &&
877         [date]
878         valid1 = "3.weeks.5.days 00:00"
879         valid2 = "Fri Jun 4 15:46:55 2010"
880         valid3 = "2017/11/11 11:11:11PM"
881         valid4 = "2017/11/10 09:08:07 PM"
882         valid5 = "never"
883         invalid1 = "abc"
884         EOF
885         cat >expect <<-EOF &&
886         $(test-tool date timestamp $rel)
887         1275666415
888         1510441871
889         1510348087
890         0
891         EOF
892         : "work around heredoc parsing bug fixed in dash 0.5.7 (in ec2c84d)" &&
893         {
894                 echo "$rel_out $(git config --expiry-date date.valid1)"
895                 git config --expiry-date date.valid2 &&
896                 git config --expiry-date date.valid3 &&
897                 git config --expiry-date date.valid4 &&
898                 git config --expiry-date date.valid5
899         } >actual &&
900         test_cmp expect actual &&
901         test_must_fail git config --expiry-date date.invalid1
902 '
903
904 test_expect_success 'get --type=color' '
905         rm .git/config &&
906         git config foo.color "red" &&
907         git config --get --type=color foo.color >actual.raw &&
908         test_decode_color <actual.raw >actual &&
909         echo "<RED>" >expect &&
910         test_cmp expect actual
911 '
912
913 cat >expect << EOF
914 [foo]
915         color = red
916 EOF
917
918 test_expect_success 'set --type=color' '
919         rm .git/config &&
920         git config --type=color foo.color "red" &&
921         test_cmp expect .git/config
922 '
923
924 test_expect_success 'get --type=color barfs on non-color' '
925         echo "[foo]bar=not-a-color" >.git/config &&
926         test_must_fail git config --get --type=color foo.bar
927 '
928
929 test_expect_success 'set --type=color barfs on non-color' '
930         test_must_fail git config --type=color foo.color "not-a-color" 2>error &&
931         test_i18ngrep "cannot parse color" error
932 '
933
934 cat > expect << EOF
935 [quote]
936         leading = " test"
937         ending = "test "
938         semicolon = "test;test"
939         hash = "test#test"
940 EOF
941 test_expect_success 'quoting' '
942         rm -f .git/config &&
943         git config quote.leading " test" &&
944         git config quote.ending "test " &&
945         git config quote.semicolon "test;test" &&
946         git config quote.hash "test#test" &&
947         test_cmp expect .git/config
948 '
949
950 test_expect_success 'key with newline' '
951         test_must_fail git config "key.with
952 newline" 123'
953
954 test_expect_success 'value with newline' 'git config key.sub value.with\\\
955 newline'
956
957 cat > .git/config <<\EOF
958 [section]
959         ; comment \
960         continued = cont\
961 inued
962         noncont   = not continued ; \
963         quotecont = "cont;\
964 inued"
965 EOF
966
967 cat > expect <<\EOF
968 section.continued=continued
969 section.noncont=not continued
970 section.quotecont=cont;inued
971 EOF
972
973 test_expect_success 'value continued on next line' '
974         git config --list > result &&
975         test_cmp expect result
976 '
977
978 cat > .git/config <<\EOF
979 [section "sub=section"]
980         val1 = foo=bar
981         val2 = foo\nbar
982         val3 = \n\n
983         val4 =
984         val5
985 EOF
986
987 cat > expect <<\EOF
988 section.sub=section.val1
989 foo=barQsection.sub=section.val2
990 foo
991 barQsection.sub=section.val3
992
993
994 Qsection.sub=section.val4
995 Qsection.sub=section.val5Q
996 EOF
997 test_expect_success '--null --list' '
998         git config --null --list >result.raw &&
999         nul_to_q <result.raw >result &&
1000         echo >>result &&
1001         test_cmp expect result
1002 '
1003
1004 test_expect_success '--null --get-regexp' '
1005         git config --null --get-regexp "val[0-9]" >result.raw &&
1006         nul_to_q <result.raw >result &&
1007         echo >>result &&
1008         test_cmp expect result
1009 '
1010
1011 test_expect_success 'inner whitespace kept verbatim' '
1012         git config section.val "foo       bar" &&
1013         test_cmp_config "foo      bar" section.val
1014 '
1015
1016 test_expect_success SYMLINKS 'symlinked configuration' '
1017         ln -s notyet myconfig &&
1018         git config --file=myconfig test.frotz nitfol &&
1019         test -h myconfig &&
1020         test -f notyet &&
1021         test "z$(git config --file=notyet test.frotz)" = znitfol &&
1022         git config --file=myconfig test.xyzzy rezrov &&
1023         test -h myconfig &&
1024         test -f notyet &&
1025         cat >expect <<-\EOF &&
1026         nitfol
1027         rezrov
1028         EOF
1029         {
1030                 git config --file=notyet test.frotz &&
1031                 git config --file=notyet test.xyzzy
1032         } >actual &&
1033         test_cmp expect actual
1034 '
1035
1036 test_expect_success SYMLINKS 'symlink to nonexistent configuration' '
1037         ln -s doesnotexist linktonada &&
1038         ln -s linktonada linktolinktonada &&
1039         test_must_fail git config --file=linktonada --list &&
1040         test_must_fail git config --file=linktolinktonada --list
1041 '
1042
1043 test_expect_success 'check split_cmdline return' "
1044         git config alias.split-cmdline-fix 'echo \"' &&
1045         test_must_fail git split-cmdline-fix &&
1046         echo foo > foo &&
1047         git add foo &&
1048         git commit -m 'initial commit' &&
1049         git config branch.master.mergeoptions 'echo \"' &&
1050         test_must_fail git merge master
1051 "
1052
1053 test_expect_success 'git -c "key=value" support' '
1054         cat >expect <<-\EOF &&
1055         value
1056         value
1057         true
1058         EOF
1059         {
1060                 git -c section.name=value config section.name &&
1061                 git -c foo.CamelCase=value config foo.camelcase &&
1062                 git -c foo.flag config --bool foo.flag
1063         } >actual &&
1064         test_cmp expect actual &&
1065         test_must_fail git -c name=value config section.name
1066 '
1067
1068 # We just need a type-specifier here that cares about the
1069 # distinction internally between a NULL boolean and a real
1070 # string (because most of git's internal parsers do care).
1071 # Using "--path" works, but we do not otherwise care about
1072 # its semantics.
1073 test_expect_success 'git -c can represent empty string' '
1074         echo >expect &&
1075         git -c foo.empty= config --path foo.empty >actual &&
1076         test_cmp expect actual
1077 '
1078
1079 test_expect_success 'key sanity-checking' '
1080         test_must_fail git config foo=bar &&
1081         test_must_fail git config foo=.bar &&
1082         test_must_fail git config foo.ba=r &&
1083         test_must_fail git config foo.1bar &&
1084         test_must_fail git config foo."ba
1085                                 z".bar &&
1086         test_must_fail git config . false &&
1087         test_must_fail git config .foo false &&
1088         test_must_fail git config foo. false &&
1089         test_must_fail git config .foo. false &&
1090         git config foo.bar true &&
1091         git config foo."ba =z".bar false
1092 '
1093
1094 test_expect_success 'git -c works with aliases of builtins' '
1095         git config alias.checkconfig "-c foo.check=bar config foo.check" &&
1096         echo bar >expect &&
1097         git checkconfig >actual &&
1098         test_cmp expect actual
1099 '
1100
1101 test_expect_success 'aliases can be CamelCased' '
1102         test_config alias.CamelCased "rev-parse HEAD" &&
1103         git CamelCased >out &&
1104         git rev-parse HEAD >expect &&
1105         test_cmp expect out
1106 '
1107
1108 test_expect_success 'git -c does not split values on equals' '
1109         echo "value with = in it" >expect &&
1110         git -c section.foo="value with = in it" config section.foo >actual &&
1111         test_cmp expect actual
1112 '
1113
1114 test_expect_success 'git -c dies on bogus config' '
1115         test_must_fail git -c core.bare=foo rev-parse
1116 '
1117
1118 test_expect_success 'git -c complains about empty key' '
1119         test_must_fail git -c "=foo" rev-parse
1120 '
1121
1122 test_expect_success 'git -c complains about empty key and value' '
1123         test_must_fail git -c "" rev-parse
1124 '
1125
1126 test_expect_success 'multiple git -c appends config' '
1127         test_config alias.x "!git -c x.two=2 config --get-regexp ^x\.*" &&
1128         cat >expect <<-\EOF &&
1129         x.one 1
1130         x.two 2
1131         EOF
1132         git -c x.one=1 x >actual &&
1133         test_cmp expect actual
1134 '
1135
1136 test_expect_success 'last one wins: two level vars' '
1137
1138         # sec.var and sec.VAR are the same variable, as the first
1139         # and the last level of a configuration variable name is
1140         # case insensitive.
1141
1142         echo VAL >expect &&
1143
1144         git -c sec.var=val -c sec.VAR=VAL config --get sec.var >actual &&
1145         test_cmp expect actual &&
1146         git -c SEC.var=val -c sec.var=VAL config --get sec.var >actual &&
1147         test_cmp expect actual &&
1148
1149         git -c sec.var=val -c sec.VAR=VAL config --get SEC.var >actual &&
1150         test_cmp expect actual &&
1151         git -c SEC.var=val -c sec.var=VAL config --get sec.VAR >actual &&
1152         test_cmp expect actual
1153 '
1154
1155 test_expect_success 'last one wins: three level vars' '
1156
1157         # v.a.r and v.A.r are not the same variable, as the middle
1158         # level of a three-level configuration variable name is
1159         # case sensitive.
1160
1161         echo val >expect &&
1162         git -c v.a.r=val -c v.A.r=VAL config --get v.a.r >actual &&
1163         test_cmp expect actual &&
1164         git -c v.a.r=val -c v.A.r=VAL config --get V.a.R >actual &&
1165         test_cmp expect actual &&
1166
1167         # v.a.r and V.a.R are the same variable, as the first
1168         # and the last level of a configuration variable name is
1169         # case insensitive.
1170
1171         echo VAL >expect &&
1172         git -c v.a.r=val -c v.a.R=VAL config --get v.a.r >actual &&
1173         test_cmp expect actual &&
1174         git -c v.a.r=val -c V.a.r=VAL config --get v.a.r >actual &&
1175         test_cmp expect actual &&
1176         git -c v.a.r=val -c v.a.R=VAL config --get V.a.R >actual &&
1177         test_cmp expect actual &&
1178         git -c v.a.r=val -c V.a.r=VAL config --get V.a.R >actual &&
1179         test_cmp expect actual
1180 '
1181
1182 test_expect_success 'old-fashioned settings are case insensitive' '
1183         test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1184
1185         cat >testConfig_actual <<-EOF &&
1186         [V.A]
1187         r = value1
1188         EOF
1189         q_to_tab >testConfig_expect <<-EOF &&
1190         [V.A]
1191         Qr = value2
1192         EOF
1193         git config -f testConfig_actual "v.a.r" value2 &&
1194         test_cmp testConfig_expect testConfig_actual &&
1195
1196         cat >testConfig_actual <<-EOF &&
1197         [V.A]
1198         r = value1
1199         EOF
1200         q_to_tab >testConfig_expect <<-EOF &&
1201         [V.A]
1202         QR = value2
1203         EOF
1204         git config -f testConfig_actual "V.a.R" value2 &&
1205         test_cmp testConfig_expect testConfig_actual &&
1206
1207         cat >testConfig_actual <<-EOF &&
1208         [V.A]
1209         r = value1
1210         EOF
1211         q_to_tab >testConfig_expect <<-EOF &&
1212         [V.A]
1213         r = value1
1214         Qr = value2
1215         EOF
1216         git config -f testConfig_actual "V.A.r" value2 &&
1217         test_cmp testConfig_expect testConfig_actual &&
1218
1219         cat >testConfig_actual <<-EOF &&
1220         [V.A]
1221         r = value1
1222         EOF
1223         q_to_tab >testConfig_expect <<-EOF &&
1224         [V.A]
1225         r = value1
1226         Qr = value2
1227         EOF
1228         git config -f testConfig_actual "v.A.r" value2 &&
1229         test_cmp testConfig_expect testConfig_actual
1230 '
1231
1232 test_expect_success 'setting different case sensitive subsections ' '
1233         test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1234
1235         cat >testConfig_actual <<-EOF &&
1236         [V "A"]
1237         R = v1
1238         [K "E"]
1239         Y = v1
1240         [a "b"]
1241         c = v1
1242         [d "e"]
1243         f = v1
1244         EOF
1245         q_to_tab >testConfig_expect <<-EOF &&
1246         [V "A"]
1247         Qr = v2
1248         [K "E"]
1249         Qy = v2
1250         [a "b"]
1251         Qc = v2
1252         [d "e"]
1253         f = v1
1254         [d "E"]
1255         Qf = v2
1256         EOF
1257         # exact match
1258         git config -f testConfig_actual a.b.c v2 &&
1259         # match section and subsection, key is cased differently.
1260         git config -f testConfig_actual K.E.y v2 &&
1261         # section and key are matched case insensitive, but subsection needs
1262         # to match; When writing out new values only the key is adjusted
1263         git config -f testConfig_actual v.A.r v2 &&
1264         # subsection is not matched:
1265         git config -f testConfig_actual d.E.f v2 &&
1266         test_cmp testConfig_expect testConfig_actual
1267 '
1268
1269 for VAR in a .a a. a.0b a."b c". a."b c".0d
1270 do
1271         test_expect_success "git -c $VAR=VAL rejects invalid '$VAR'" '
1272                 test_must_fail git -c "$VAR=VAL" config -l
1273         '
1274 done
1275
1276 for VAR in a.b a."b c".d
1277 do
1278         test_expect_success "git -c $VAR=VAL works with valid '$VAR'" '
1279                 echo VAL >expect &&
1280                 git -c "$VAR=VAL" config --get "$VAR" >actual &&
1281                 test_cmp expect actual
1282         '
1283 done
1284
1285 test_expect_success 'git -c is not confused by empty environment' '
1286         GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
1287 '
1288
1289 test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' '
1290         cat >expect <<-\EOF &&
1291         env.one one
1292         env.two two
1293         EOF
1294         GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ} ${SQ}env.two=two${SQ}" \
1295                 git config --get-regexp "env.*" >actual &&
1296         test_cmp expect actual &&
1297
1298         cat >expect <<-EOF &&
1299         env.one one${SQ}
1300         env.two two
1301         EOF
1302         GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ$SQ$SQ ${SQ}env.two=two${SQ}" \
1303                 git config --get-regexp "env.*" >actual &&
1304         test_cmp expect actual &&
1305
1306         test_must_fail env \
1307                 GIT_CONFIG_PARAMETERS="${SQ}env.one=one${SQ}\\$SQ ${SQ}env.two=two${SQ}" \
1308                 git config --get-regexp "env.*"
1309 '
1310
1311 test_expect_success 'git config --edit works' '
1312         git config -f tmp test.value no &&
1313         echo test.value=yes >expect &&
1314         GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit &&
1315         git config -f tmp --list >actual &&
1316         test_cmp expect actual
1317 '
1318
1319 test_expect_success 'git config --edit respects core.editor' '
1320         git config -f tmp test.value no &&
1321         echo test.value=yes >expect &&
1322         test_config core.editor "echo [test]value=yes >" &&
1323         git config -f tmp --edit &&
1324         git config -f tmp --list >actual &&
1325         test_cmp expect actual
1326 '
1327
1328 # malformed configuration files
1329 test_expect_success 'barf on syntax error' '
1330         cat >.git/config <<-\EOF &&
1331         # broken section line
1332         [section]
1333         key garbage
1334         EOF
1335         test_must_fail git config --get section.key >actual 2>error &&
1336         test_i18ngrep " line 3 " error
1337 '
1338
1339 test_expect_success 'barf on incomplete section header' '
1340         cat >.git/config <<-\EOF &&
1341         # broken section line
1342         [section
1343         key = value
1344         EOF
1345         test_must_fail git config --get section.key >actual 2>error &&
1346         test_i18ngrep " line 2 " error
1347 '
1348
1349 test_expect_success 'barf on incomplete string' '
1350         cat >.git/config <<-\EOF &&
1351         # broken section line
1352         [section]
1353         key = "value string
1354         EOF
1355         test_must_fail git config --get section.key >actual 2>error &&
1356         test_i18ngrep " line 3 " error
1357 '
1358
1359 test_expect_success 'urlmatch' '
1360         cat >.git/config <<-\EOF &&
1361         [http]
1362                 sslVerify
1363         [http "https://weak.example.com"]
1364                 sslVerify = false
1365                 cookieFile = /tmp/cookie.txt
1366         EOF
1367
1368         test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
1369         test_must_be_empty actual &&
1370
1371         echo true >expect &&
1372         git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
1373         test_cmp expect actual &&
1374
1375         echo false >expect &&
1376         git config --bool --get-urlmatch http.sslverify https://weak.example.com >actual &&
1377         test_cmp expect actual &&
1378
1379         {
1380                 echo http.cookiefile /tmp/cookie.txt &&
1381                 echo http.sslverify false
1382         } >expect &&
1383         git config --get-urlmatch HTTP https://weak.example.com >actual &&
1384         test_cmp expect actual
1385 '
1386
1387 test_expect_success 'urlmatch favors more specific URLs' '
1388         cat >.git/config <<-\EOF &&
1389         [http "https://example.com/"]
1390                 cookieFile = /tmp/root.txt
1391         [http "https://example.com/subdirectory"]
1392                 cookieFile = /tmp/subdirectory.txt
1393         [http "https://user@example.com/"]
1394                 cookieFile = /tmp/user.txt
1395         [http "https://averylonguser@example.com/"]
1396                 cookieFile = /tmp/averylonguser.txt
1397         [http "https://preceding.example.com"]
1398                 cookieFile = /tmp/preceding.txt
1399         [http "https://*.example.com"]
1400                 cookieFile = /tmp/wildcard.txt
1401         [http "https://*.example.com/wildcardwithsubdomain"]
1402                 cookieFile = /tmp/wildcardwithsubdomain.txt
1403         [http "https://*.example.*"]
1404                 cookieFile = /tmp/multiwildcard.txt
1405         [http "https://trailing.example.com"]
1406                 cookieFile = /tmp/trailing.txt
1407         [http "https://user@*.example.com/"]
1408                 cookieFile = /tmp/wildcardwithuser.txt
1409         [http "https://sub.example.com/"]
1410                 cookieFile = /tmp/sub.txt
1411         EOF
1412
1413         echo http.cookiefile /tmp/root.txt >expect &&
1414         git config --get-urlmatch HTTP https://example.com >actual &&
1415         test_cmp expect actual &&
1416
1417         echo http.cookiefile /tmp/subdirectory.txt >expect &&
1418         git config --get-urlmatch HTTP https://example.com/subdirectory >actual &&
1419         test_cmp expect actual &&
1420
1421         echo http.cookiefile /tmp/subdirectory.txt >expect &&
1422         git config --get-urlmatch HTTP https://example.com/subdirectory/nested >actual &&
1423         test_cmp expect actual &&
1424
1425         echo http.cookiefile /tmp/user.txt >expect &&
1426         git config --get-urlmatch HTTP https://user@example.com/ >actual &&
1427         test_cmp expect actual &&
1428
1429         echo http.cookiefile /tmp/subdirectory.txt >expect &&
1430         git config --get-urlmatch HTTP https://averylonguser@example.com/subdirectory >actual &&
1431         test_cmp expect actual &&
1432
1433         echo http.cookiefile /tmp/preceding.txt >expect &&
1434         git config --get-urlmatch HTTP https://preceding.example.com >actual &&
1435         test_cmp expect actual &&
1436
1437         echo http.cookiefile /tmp/wildcard.txt >expect &&
1438         git config --get-urlmatch HTTP https://wildcard.example.com >actual &&
1439         test_cmp expect actual &&
1440
1441         echo http.cookiefile /tmp/sub.txt >expect &&
1442         git config --get-urlmatch HTTP https://sub.example.com/wildcardwithsubdomain >actual &&
1443         test_cmp expect actual &&
1444
1445         echo http.cookiefile /tmp/trailing.txt >expect &&
1446         git config --get-urlmatch HTTP https://trailing.example.com >actual &&
1447         test_cmp expect actual &&
1448
1449         echo http.cookiefile /tmp/sub.txt >expect &&
1450         git config --get-urlmatch HTTP https://user@sub.example.com >actual &&
1451         test_cmp expect actual &&
1452
1453         echo http.cookiefile /tmp/multiwildcard.txt >expect &&
1454         git config --get-urlmatch HTTP https://wildcard.example.org >actual &&
1455         test_cmp expect actual
1456 '
1457
1458 test_expect_success 'urlmatch with wildcard' '
1459         cat >.git/config <<-\EOF &&
1460         [http]
1461                 sslVerify
1462         [http "https://*.example.com"]
1463                 sslVerify = false
1464                 cookieFile = /tmp/cookie.txt
1465         EOF
1466
1467         test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
1468         test_must_be_empty actual &&
1469
1470         echo true >expect &&
1471         git config --bool --get-urlmatch http.SSLverify https://example.com >actual &&
1472         test_cmp expect actual &&
1473
1474         echo true >expect &&
1475         git config --bool --get-urlmatch http.SSLverify https://good-example.com >actual &&
1476         test_cmp expect actual &&
1477
1478         echo true >expect &&
1479         git config --bool --get-urlmatch http.sslverify https://deep.nested.example.com >actual &&
1480         test_cmp expect actual &&
1481
1482         echo false >expect &&
1483         git config --bool --get-urlmatch http.sslverify https://good.example.com >actual &&
1484         test_cmp expect actual &&
1485
1486         {
1487                 echo http.cookiefile /tmp/cookie.txt &&
1488                 echo http.sslverify false
1489         } >expect &&
1490         git config --get-urlmatch HTTP https://good.example.com >actual &&
1491         test_cmp expect actual &&
1492
1493         echo http.sslverify >expect &&
1494         git config --get-urlmatch HTTP https://more.example.com.au >actual &&
1495         test_cmp expect actual
1496 '
1497
1498 # good section hygiene
1499 test_expect_success '--unset last key removes section (except if commented)' '
1500         cat >.git/config <<-\EOF &&
1501         # some generic comment on the configuration file itself
1502         # a comment specific to this "section" section.
1503         [section]
1504         # some intervening lines
1505         # that should also be dropped
1506
1507         key = value
1508         # please be careful when you update the above variable
1509         EOF
1510
1511         cat >expect <<-\EOF &&
1512         # some generic comment on the configuration file itself
1513         # a comment specific to this "section" section.
1514         [section]
1515         # some intervening lines
1516         # that should also be dropped
1517
1518         # please be careful when you update the above variable
1519         EOF
1520
1521         git config --unset section.key &&
1522         test_cmp expect .git/config &&
1523
1524         cat >.git/config <<-\EOF &&
1525         [section]
1526         key = value
1527         [next-section]
1528         EOF
1529
1530         cat >expect <<-\EOF &&
1531         [next-section]
1532         EOF
1533
1534         git config --unset section.key &&
1535         test_cmp expect .git/config &&
1536
1537         q_to_tab >.git/config <<-\EOF &&
1538         [one]
1539         Qkey = "multiline \
1540         QQ# with comment"
1541         [two]
1542         key = true
1543         EOF
1544         git config --unset two.key &&
1545         ! grep two .git/config &&
1546
1547         q_to_tab >.git/config <<-\EOF &&
1548         [one]
1549         Qkey = "multiline \
1550         QQ# with comment"
1551         [one]
1552         key = true
1553         EOF
1554         git config --unset-all one.key &&
1555         test_line_count = 0 .git/config &&
1556
1557         q_to_tab >.git/config <<-\EOF &&
1558         [one]
1559         Qkey = true
1560         Q# a comment not at the start
1561         [two]
1562         Qkey = true
1563         EOF
1564         git config --unset two.key &&
1565         grep two .git/config &&
1566
1567         q_to_tab >.git/config <<-\EOF &&
1568         [one]
1569         Qkey = not [two "subsection"]
1570         [two "subsection"]
1571         [two "subsection"]
1572         Qkey = true
1573         [TWO "subsection"]
1574         [one]
1575         EOF
1576         git config --unset two.subsection.key &&
1577         test "not [two subsection]" = "$(git config one.key)" &&
1578         test_line_count = 3 .git/config
1579 '
1580
1581 test_expect_success '--unset-all removes section if empty & uncommented' '
1582         cat >.git/config <<-\EOF &&
1583         [section]
1584         key = value1
1585         key = value2
1586         EOF
1587
1588         git config --unset-all section.key &&
1589         test_line_count = 0 .git/config
1590 '
1591
1592 test_expect_success 'adding a key into an empty section reuses header' '
1593         cat >.git/config <<-\EOF &&
1594         [section]
1595         EOF
1596
1597         q_to_tab >expect <<-\EOF &&
1598         [section]
1599         Qkey = value
1600         EOF
1601
1602         git config section.key value &&
1603         test_cmp expect .git/config
1604 '
1605
1606 test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
1607         chmod 0600 .git/config &&
1608         git config imap.pass Hunter2 &&
1609         perl -e \
1610           "die q(badset) if ((stat(q(.git/config)))[2] & 07777) != 0600" &&
1611         git config --rename-section imap pop &&
1612         perl -e \
1613           "die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
1614 '
1615
1616 ! test_have_prereq MINGW ||
1617 HOME="$(pwd)" # convert to Windows path
1618
1619 test_expect_success 'set up --show-origin tests' '
1620         INCLUDE_DIR="$HOME/include" &&
1621         mkdir -p "$INCLUDE_DIR" &&
1622         cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
1623         [user]
1624                 absolute = include
1625         EOF
1626         cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
1627         [user]
1628                 relative = include
1629         EOF
1630         cat >"$HOME"/.gitconfig <<-EOF &&
1631         [user]
1632                 global = true
1633                 override = global
1634         [include]
1635                 path = "$INCLUDE_DIR/absolute.include"
1636         EOF
1637         cat >.git/config <<-\EOF
1638         [user]
1639                 local = true
1640                 override = local
1641         [include]
1642                 path = ../include/relative.include
1643         EOF
1644 '
1645
1646 test_expect_success '--show-origin with --list' '
1647         cat >expect <<-EOF &&
1648         file:$HOME/.gitconfig   user.global=true
1649         file:$HOME/.gitconfig   user.override=global
1650         file:$HOME/.gitconfig   include.path=$INCLUDE_DIR/absolute.include
1651         file:$INCLUDE_DIR/absolute.include      user.absolute=include
1652         file:.git/config        user.local=true
1653         file:.git/config        user.override=local
1654         file:.git/config        include.path=../include/relative.include
1655         file:.git/../include/relative.include   user.relative=include
1656         command line:   user.cmdline=true
1657         EOF
1658         git -c user.cmdline=true config --list --show-origin >output &&
1659         test_cmp expect output
1660 '
1661
1662 test_expect_success '--show-origin with --list --null' '
1663         cat >expect <<-EOF &&
1664         file:$HOME/.gitconfigQuser.global
1665         trueQfile:$HOME/.gitconfigQuser.override
1666         globalQfile:$HOME/.gitconfigQinclude.path
1667         $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
1668         includeQfile:.git/configQuser.local
1669         trueQfile:.git/configQuser.override
1670         localQfile:.git/configQinclude.path
1671         ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
1672         includeQcommand line:Quser.cmdline
1673         trueQ
1674         EOF
1675         git -c user.cmdline=true config --null --list --show-origin >output.raw &&
1676         nul_to_q <output.raw >output &&
1677         # The here-doc above adds a newline that the --null output would not
1678         # include. Add it here to make the two comparable.
1679         echo >>output &&
1680         test_cmp expect output
1681 '
1682
1683 test_expect_success '--show-origin with single file' '
1684         cat >expect <<-\EOF &&
1685         file:.git/config        user.local=true
1686         file:.git/config        user.override=local
1687         file:.git/config        include.path=../include/relative.include
1688         EOF
1689         git config --local --list --show-origin >output &&
1690         test_cmp expect output
1691 '
1692
1693 test_expect_success '--show-origin with --get-regexp' '
1694         cat >expect <<-EOF &&
1695         file:$HOME/.gitconfig   user.global true
1696         file:.git/config        user.local true
1697         EOF
1698         git config --show-origin --get-regexp "user\.[g|l].*" >output &&
1699         test_cmp expect output
1700 '
1701
1702 test_expect_success '--show-origin getting a single key' '
1703         cat >expect <<-\EOF &&
1704         file:.git/config        local
1705         EOF
1706         git config --show-origin user.override >output &&
1707         test_cmp expect output
1708 '
1709
1710 test_expect_success 'set up custom config file' '
1711         CUSTOM_CONFIG_FILE="custom.conf" &&
1712         cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
1713         [user]
1714                 custom = true
1715         EOF
1716 '
1717
1718 test_expect_success !MINGW 'set up custom config file with special name characters' '
1719         WEIRDLY_NAMED_FILE="file\" (dq) and spaces.conf" &&
1720         cp "$CUSTOM_CONFIG_FILE" "$WEIRDLY_NAMED_FILE"
1721 '
1722
1723 test_expect_success !MINGW '--show-origin escape special file name characters' '
1724         cat >expect <<-\EOF &&
1725         file:"file\" (dq) and spaces.conf"      user.custom=true
1726         EOF
1727         git config --file "$WEIRDLY_NAMED_FILE" --show-origin --list >output &&
1728         test_cmp expect output
1729 '
1730
1731 test_expect_success '--show-origin stdin' '
1732         cat >expect <<-\EOF &&
1733         standard input: user.custom=true
1734         EOF
1735         git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
1736         test_cmp expect output
1737 '
1738
1739 test_expect_success '--show-origin stdin with file include' '
1740         cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
1741         [user]
1742                 stdin = include
1743         EOF
1744         cat >expect <<-EOF &&
1745         file:$INCLUDE_DIR/stdin.include include
1746         EOF
1747         echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
1748         git config --show-origin --includes --file - user.stdin >output &&
1749
1750         test_cmp expect output
1751 '
1752
1753 test_expect_success '--show-origin blob' '
1754         blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
1755         cat >expect <<-EOF &&
1756         blob:$blob      user.custom=true
1757         EOF
1758         git config --blob=$blob --show-origin --list >output &&
1759         test_cmp expect output
1760 '
1761
1762 test_expect_success '--show-origin blob ref' '
1763         cat >expect <<-\EOF &&
1764         blob:master:custom.conf user.custom=true
1765         EOF
1766         git add "$CUSTOM_CONFIG_FILE" &&
1767         git commit -m "new config file" &&
1768         git config --blob=master:"$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
1769         test_cmp expect output
1770 '
1771
1772 test_expect_success '--show-scope with --list' '
1773         cat >expect <<-EOF &&
1774         global  user.global=true
1775         global  user.override=global
1776         global  include.path=$INCLUDE_DIR/absolute.include
1777         global  user.absolute=include
1778         local   user.local=true
1779         local   user.override=local
1780         local   include.path=../include/relative.include
1781         local   user.relative=include
1782         command user.cmdline=true
1783         EOF
1784         git -c user.cmdline=true config --list --show-scope >output &&
1785         test_cmp expect output
1786 '
1787
1788 test_expect_success !MINGW '--show-scope with --blob' '
1789         blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
1790         cat >expect <<-EOF &&
1791         command user.custom=true
1792         EOF
1793         git config --blob=$blob --show-scope --list >output &&
1794         test_cmp expect output
1795 '
1796
1797 test_expect_success '--show-scope with --local' '
1798         cat >expect <<-\EOF &&
1799         local   user.local=true
1800         local   user.override=local
1801         local   include.path=../include/relative.include
1802         EOF
1803         git config --local --list --show-scope >output &&
1804         test_cmp expect output
1805 '
1806
1807 test_expect_success '--show-scope getting a single value' '
1808         cat >expect <<-\EOF &&
1809         local   true
1810         EOF
1811         git config --show-scope --get user.local >output &&
1812         test_cmp expect output
1813 '
1814
1815 test_expect_success '--show-scope with --show-origin' '
1816         cat >expect <<-EOF &&
1817         global  file:$HOME/.gitconfig   user.global=true
1818         global  file:$HOME/.gitconfig   user.override=global
1819         global  file:$HOME/.gitconfig   include.path=$INCLUDE_DIR/absolute.include
1820         global  file:$INCLUDE_DIR/absolute.include      user.absolute=include
1821         local   file:.git/config        user.local=true
1822         local   file:.git/config        user.override=local
1823         local   file:.git/config        include.path=../include/relative.include
1824         local   file:.git/../include/relative.include   user.relative=include
1825         command command line:   user.cmdline=true
1826         EOF
1827         git -c user.cmdline=true config --list --show-origin --show-scope >output &&
1828         test_cmp expect output
1829 '
1830
1831 for opt in --local --worktree
1832 do
1833         test_expect_success "$opt requires a repo" '
1834                 # we expect 128 to ensure that we do not simply
1835                 # fail to find anything and return code "1"
1836                 test_expect_code 128 nongit git config $opt foo.bar
1837         '
1838 done
1839
1840 cat >.git/config <<-\EOF &&
1841 [section]
1842 foo = true
1843 number = 10
1844 big = 1M
1845 EOF
1846
1847 test_expect_success 'identical modern --type specifiers are allowed' '
1848         test_cmp_config 1048576 --type=int --type=int section.big
1849 '
1850
1851 test_expect_success 'identical legacy --type specifiers are allowed' '
1852         test_cmp_config 1048576 --int --int section.big
1853 '
1854
1855 test_expect_success 'identical mixed --type specifiers are allowed' '
1856         test_cmp_config 1048576 --int --type=int section.big
1857 '
1858
1859 test_expect_success 'non-identical modern --type specifiers are not allowed' '
1860         test_must_fail git config --type=int --type=bool section.big 2>error &&
1861         test_i18ngrep "only one type at a time" error
1862 '
1863
1864 test_expect_success 'non-identical legacy --type specifiers are not allowed' '
1865         test_must_fail git config --int --bool section.big 2>error &&
1866         test_i18ngrep "only one type at a time" error
1867 '
1868
1869 test_expect_success 'non-identical mixed --type specifiers are not allowed' '
1870         test_must_fail git config --type=int --bool section.big 2>error &&
1871         test_i18ngrep "only one type at a time" error
1872 '
1873
1874 test_expect_success '--type allows valid type specifiers' '
1875         test_cmp_config true  --type=bool section.foo
1876 '
1877
1878 test_expect_success '--no-type unsets type specifiers' '
1879         test_cmp_config 10 --type=bool --no-type section.number
1880 '
1881
1882 test_expect_success 'unset type specifiers may be reset to conflicting ones' '
1883         test_cmp_config 1048576 --type=bool --no-type --type=int section.big
1884 '
1885
1886 test_expect_success '--type rejects unknown specifiers' '
1887         test_must_fail git config --type=nonsense section.foo 2>error &&
1888         test_i18ngrep "unrecognized --type argument" error
1889 '
1890
1891 test_expect_success '--replace-all does not invent newlines' '
1892         q_to_tab >.git/config <<-\EOF &&
1893         [abc]key
1894         QkeepSection
1895         [xyz]
1896         Qkey = 1
1897         [abc]
1898         Qkey = a
1899         EOF
1900         q_to_tab >expect <<-\EOF &&
1901         [abc]
1902         QkeepSection
1903         [xyz]
1904         Qkey = 1
1905         [abc]
1906         Qkey = b
1907         EOF
1908         git config --replace-all abc.key b &&
1909         test_cmp expect .git/config
1910 '
1911
1912 test_expect_success 'set all config with value-pattern' '
1913         test_when_finished rm -f config initial &&
1914         git config --file=initial abc.key one &&
1915
1916         # no match => add new entry
1917         cp initial config &&
1918         git config --file=config abc.key two a+ &&
1919         git config --file=config --list >actual &&
1920         cat >expect <<-\EOF &&
1921         abc.key=one
1922         abc.key=two
1923         EOF
1924         test_cmp expect actual &&
1925
1926         # multiple matches => failure
1927         test_must_fail git config --file=config abc.key three o+ 2>err &&
1928         test_i18ngrep "has multiple values" err &&
1929
1930         # multiple values, no match => add
1931         git config --file=config abc.key three a+ &&
1932         git config --file=config --list >actual &&
1933         cat >expect <<-\EOF &&
1934         abc.key=one
1935         abc.key=two
1936         abc.key=three
1937         EOF
1938         test_cmp expect actual &&
1939
1940         # single match => replace
1941         git config --file=config abc.key four h+ &&
1942         git config --file=config --list >actual &&
1943         cat >expect <<-\EOF &&
1944         abc.key=one
1945         abc.key=two
1946         abc.key=four
1947         EOF
1948         test_cmp expect actual
1949 '
1950
1951 test_expect_success '--replace-all and value-pattern' '
1952         test_when_finished rm -f config &&
1953         git config --file=config --add abc.key one &&
1954         git config --file=config --add abc.key two &&
1955         git config --file=config --add abc.key three &&
1956         git config --file=config --replace-all abc.key four "o+" &&
1957         git config --file=config --list >actual &&
1958         cat >expect <<-\EOF &&
1959         abc.key=four
1960         abc.key=three
1961         EOF
1962         test_cmp expect actual
1963 '
1964
1965 test_expect_success 'refuse --fixed-value for incompatible actions' '
1966         test_when_finished rm -f config &&
1967         git config --file=config dev.null bogus &&
1968
1969         # These modes do not allow --fixed-value at all
1970         test_must_fail git config --file=config --fixed-value --add dev.null bogus &&
1971         test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus &&
1972         test_must_fail git config --file=config --fixed-value --get-urlmatch dev.null bogus &&
1973         test_must_fail git config --file=config --fixed-value --rename-section dev null &&
1974         test_must_fail git config --file=config --fixed-value --remove-section dev &&
1975         test_must_fail git config --file=config --fixed-value --list &&
1976         test_must_fail git config --file=config --fixed-value --get-color dev.null &&
1977         test_must_fail git config --file=config --fixed-value --get-colorbool dev.null &&
1978
1979         # These modes complain when --fixed-value has no value-pattern
1980         test_must_fail git config --file=config --fixed-value dev.null bogus &&
1981         test_must_fail git config --file=config --fixed-value --replace-all dev.null bogus &&
1982         test_must_fail git config --file=config --fixed-value --get dev.null &&
1983         test_must_fail git config --file=config --fixed-value --get-all dev.null &&
1984         test_must_fail git config --file=config --fixed-value --get-regexp "dev.*" &&
1985         test_must_fail git config --file=config --fixed-value --unset dev.null &&
1986         test_must_fail git config --file=config --fixed-value --unset-all dev.null
1987 '
1988
1989 test_expect_success '--fixed-value uses exact string matching' '
1990         test_when_finished rm -f config initial &&
1991         META="a+b*c?d[e]f.g" &&
1992         git config --file=initial fixed.test "$META" &&
1993
1994         cp initial config &&
1995         git config --file=config fixed.test bogus "$META" &&
1996         git config --file=config --list >actual &&
1997         cat >expect <<-EOF &&
1998         fixed.test=$META
1999         fixed.test=bogus
2000         EOF
2001         test_cmp expect actual &&
2002
2003         cp initial config &&
2004         git config --file=config --fixed-value fixed.test bogus "$META" &&
2005         git config --file=config --list >actual &&
2006         cat >expect <<-\EOF &&
2007         fixed.test=bogus
2008         EOF
2009         test_cmp expect actual &&
2010
2011         cp initial config &&
2012         test_must_fail git config --file=config --unset fixed.test "$META" &&
2013         git config --file=config --fixed-value --unset fixed.test "$META" &&
2014         test_must_fail git config --file=config fixed.test &&
2015
2016         cp initial config &&
2017         test_must_fail git config --file=config --unset-all fixed.test "$META" &&
2018         git config --file=config --fixed-value --unset-all fixed.test "$META" &&
2019         test_must_fail git config --file=config fixed.test &&
2020
2021         cp initial config &&
2022         git config --file=config --replace-all fixed.test bogus "$META" &&
2023         git config --file=config --list >actual &&
2024         cat >expect <<-EOF &&
2025         fixed.test=$META
2026         fixed.test=bogus
2027         EOF
2028         test_cmp expect actual &&
2029
2030         git config --file=config --fixed-value --replace-all fixed.test bogus "$META" &&
2031         git config --file=config --list >actual &&
2032         cat >expect <<-EOF &&
2033         fixed.test=bogus
2034         fixed.test=bogus
2035         EOF
2036         test_cmp expect actual
2037 '
2038
2039 test_expect_success '--get and --get-all with --fixed-value' '
2040         test_when_finished rm -f config &&
2041         META="a+b*c?d[e]f.g" &&
2042         git config --file=config fixed.test bogus &&
2043         git config --file=config --add fixed.test "$META" &&
2044
2045         git config --file=config --get fixed.test bogus &&
2046         test_must_fail git config --file=config --get fixed.test "$META" &&
2047         git config --file=config --get --fixed-value fixed.test "$META" &&
2048         test_must_fail git config --file=config --get --fixed-value fixed.test non-existent &&
2049
2050         git config --file=config --get-all fixed.test bogus &&
2051         test_must_fail git config --file=config --get-all fixed.test "$META" &&
2052         git config --file=config --get-all --fixed-value fixed.test "$META" &&
2053         test_must_fail git config --file=config --get-all --fixed-value fixed.test non-existent &&
2054
2055         git config --file=config --get-regexp fixed+ bogus &&
2056         test_must_fail git config --file=config --get-regexp fixed+ "$META" &&
2057         git config --file=config --get-regexp --fixed-value fixed+ "$META" &&
2058         test_must_fail git config --file=config --get-regexp --fixed-value fixed+ non-existent
2059 '
2060
2061 test_done