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