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