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