t / t1300-config.shon commit Merge branch 'ab/rebase-in-c-escape-hatch' (4520c23)
   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        {
 896                echo "$rel_out $(git config --expiry-date date.valid1)"
 897                git config --expiry-date date.valid2 &&
 898                git config --expiry-date date.valid3 &&
 899                git config --expiry-date date.valid4 &&
 900                git config --expiry-date date.valid5
 901        } >actual &&
 902        test_cmp expect actual &&
 903        test_must_fail git config --expiry-date date.invalid1
 904'
 905
 906test_expect_success 'get --type=color' '
 907        rm .git/config &&
 908        git config foo.color "red" &&
 909        git config --get --type=color foo.color >actual.raw &&
 910        test_decode_color <actual.raw >actual &&
 911        echo "<RED>" >expect &&
 912        test_cmp expect actual
 913'
 914
 915cat >expect << EOF
 916[foo]
 917        color = red
 918EOF
 919
 920test_expect_success 'set --type=color' '
 921        rm .git/config &&
 922        git config --type=color foo.color "red" &&
 923        test_cmp expect .git/config
 924'
 925
 926test_expect_success 'get --type=color barfs on non-color' '
 927        echo "[foo]bar=not-a-color" >.git/config &&
 928        test_must_fail git config --get --type=color foo.bar
 929'
 930
 931test_expect_success 'set --type=color barfs on non-color' '
 932        test_must_fail git config --type=color foo.color "not-a-color" 2>error &&
 933        test_i18ngrep "cannot parse color" error
 934'
 935
 936cat > expect << EOF
 937[quote]
 938        leading = " test"
 939        ending = "test "
 940        semicolon = "test;test"
 941        hash = "test#test"
 942EOF
 943test_expect_success 'quoting' '
 944        rm -f .git/config &&
 945        git config quote.leading " test" &&
 946        git config quote.ending "test " &&
 947        git config quote.semicolon "test;test" &&
 948        git config quote.hash "test#test" &&
 949        test_cmp expect .git/config
 950'
 951
 952test_expect_success 'key with newline' '
 953        test_must_fail git config "key.with
 954newline" 123'
 955
 956test_expect_success 'value with newline' 'git config key.sub value.with\\\
 957newline'
 958
 959cat > .git/config <<\EOF
 960[section]
 961        ; comment \
 962        continued = cont\
 963inued
 964        noncont   = not continued ; \
 965        quotecont = "cont;\
 966inued"
 967EOF
 968
 969cat > expect <<\EOF
 970section.continued=continued
 971section.noncont=not continued
 972section.quotecont=cont;inued
 973EOF
 974
 975test_expect_success 'value continued on next line' '
 976        git config --list > result &&
 977        test_cmp expect result
 978'
 979
 980cat > .git/config <<\EOF
 981[section "sub=section"]
 982        val1 = foo=bar
 983        val2 = foo\nbar
 984        val3 = \n\n
 985        val4 =
 986        val5
 987EOF
 988
 989cat > expect <<\EOF
 990section.sub=section.val1
 991foo=barQsection.sub=section.val2
 992foo
 993barQsection.sub=section.val3
 994
 995
 996Qsection.sub=section.val4
 997Qsection.sub=section.val5Q
 998EOF
 999test_expect_success '--null --list' '
1000        git config --null --list >result.raw &&
1001        nul_to_q <result.raw >result &&
1002        echo >>result &&
1003        test_cmp expect result
1004'
1005
1006test_expect_success '--null --get-regexp' '
1007        git config --null --get-regexp "val[0-9]" >result.raw &&
1008        nul_to_q <result.raw >result &&
1009        echo >>result &&
1010        test_cmp expect result
1011'
1012
1013test_expect_success 'inner whitespace kept verbatim' '
1014        git config section.val "foo       bar" &&
1015        test_cmp_config "foo      bar" section.val
1016'
1017
1018test_expect_success SYMLINKS 'symlinked configuration' '
1019        ln -s notyet myconfig &&
1020        git config --file=myconfig test.frotz nitfol &&
1021        test -h myconfig &&
1022        test -f notyet &&
1023        test "z$(git config --file=notyet test.frotz)" = znitfol &&
1024        git config --file=myconfig test.xyzzy rezrov &&
1025        test -h myconfig &&
1026        test -f notyet &&
1027        cat >expect <<-\EOF &&
1028        nitfol
1029        rezrov
1030        EOF
1031        {
1032                git config --file=notyet test.frotz &&
1033                git config --file=notyet test.xyzzy
1034        } >actual &&
1035        test_cmp expect actual
1036'
1037
1038test_expect_success 'nonexistent configuration' '
1039        test_must_fail git config --file=doesnotexist --list &&
1040        test_must_fail git config --file=doesnotexist test.xyzzy
1041'
1042
1043test_expect_success SYMLINKS 'symlink to nonexistent configuration' '
1044        ln -s doesnotexist linktonada &&
1045        ln -s linktonada linktolinktonada &&
1046        test_must_fail git config --file=linktonada --list &&
1047        test_must_fail git config --file=linktolinktonada --list
1048'
1049
1050test_expect_success 'check split_cmdline return' "
1051        git config alias.split-cmdline-fix 'echo \"' &&
1052        test_must_fail git split-cmdline-fix &&
1053        echo foo > foo &&
1054        git add foo &&
1055        git commit -m 'initial commit' &&
1056        git config branch.master.mergeoptions 'echo \"' &&
1057        test_must_fail git merge master
1058"
1059
1060test_expect_success 'git -c "key=value" support' '
1061        cat >expect <<-\EOF &&
1062        value
1063        value
1064        true
1065        EOF
1066        {
1067                git -c core.name=value config core.name &&
1068                git -c foo.CamelCase=value config foo.camelcase &&
1069                git -c foo.flag config --bool foo.flag
1070        } >actual &&
1071        test_cmp expect actual &&
1072        test_must_fail git -c name=value config core.name
1073'
1074
1075# We just need a type-specifier here that cares about the
1076# distinction internally between a NULL boolean and a real
1077# string (because most of git's internal parsers do care).
1078# Using "--path" works, but we do not otherwise care about
1079# its semantics.
1080test_expect_success 'git -c can represent empty string' '
1081        echo >expect &&
1082        git -c foo.empty= config --path foo.empty >actual &&
1083        test_cmp expect actual
1084'
1085
1086test_expect_success 'key sanity-checking' '
1087        test_must_fail git config foo=bar &&
1088        test_must_fail git config foo=.bar &&
1089        test_must_fail git config foo.ba=r &&
1090        test_must_fail git config foo.1bar &&
1091        test_must_fail git config foo."ba
1092                                z".bar &&
1093        test_must_fail git config . false &&
1094        test_must_fail git config .foo false &&
1095        test_must_fail git config foo. false &&
1096        test_must_fail git config .foo. false &&
1097        git config foo.bar true &&
1098        git config foo."ba =z".bar false
1099'
1100
1101test_expect_success 'git -c works with aliases of builtins' '
1102        git config alias.checkconfig "-c foo.check=bar config foo.check" &&
1103        echo bar >expect &&
1104        git checkconfig >actual &&
1105        test_cmp expect actual
1106'
1107
1108test_expect_success 'aliases can be CamelCased' '
1109        test_config alias.CamelCased "rev-parse HEAD" &&
1110        git CamelCased >out &&
1111        git rev-parse HEAD >expect &&
1112        test_cmp expect out
1113'
1114
1115test_expect_success 'git -c does not split values on equals' '
1116        echo "value with = in it" >expect &&
1117        git -c core.foo="value with = in it" config core.foo >actual &&
1118        test_cmp expect actual
1119'
1120
1121test_expect_success 'git -c dies on bogus config' '
1122        test_must_fail git -c core.bare=foo rev-parse
1123'
1124
1125test_expect_success 'git -c complains about empty key' '
1126        test_must_fail git -c "=foo" rev-parse
1127'
1128
1129test_expect_success 'git -c complains about empty key and value' '
1130        test_must_fail git -c "" rev-parse
1131'
1132
1133test_expect_success 'multiple git -c appends config' '
1134        test_config alias.x "!git -c x.two=2 config --get-regexp ^x\.*" &&
1135        cat >expect <<-\EOF &&
1136        x.one 1
1137        x.two 2
1138        EOF
1139        git -c x.one=1 x >actual &&
1140        test_cmp expect actual
1141'
1142
1143test_expect_success 'last one wins: two level vars' '
1144
1145        # sec.var and sec.VAR are the same variable, as the first
1146        # and the last level of a configuration variable name is
1147        # case insensitive.
1148
1149        echo VAL >expect &&
1150
1151        git -c sec.var=val -c sec.VAR=VAL config --get sec.var >actual &&
1152        test_cmp expect actual &&
1153        git -c SEC.var=val -c sec.var=VAL config --get sec.var >actual &&
1154        test_cmp expect actual &&
1155
1156        git -c sec.var=val -c sec.VAR=VAL config --get SEC.var >actual &&
1157        test_cmp expect actual &&
1158        git -c SEC.var=val -c sec.var=VAL config --get sec.VAR >actual &&
1159        test_cmp expect actual
1160'
1161
1162test_expect_success 'last one wins: three level vars' '
1163
1164        # v.a.r and v.A.r are not the same variable, as the middle
1165        # level of a three-level configuration variable name is
1166        # case sensitive.
1167
1168        echo val >expect &&
1169        git -c v.a.r=val -c v.A.r=VAL config --get v.a.r >actual &&
1170        test_cmp expect actual &&
1171        git -c v.a.r=val -c v.A.r=VAL config --get V.a.R >actual &&
1172        test_cmp expect actual &&
1173
1174        # v.a.r and V.a.R 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        git -c v.a.r=val -c v.a.R=VAL config --get v.a.r >actual &&
1180        test_cmp expect actual &&
1181        git -c v.a.r=val -c V.a.r=VAL config --get v.a.r >actual &&
1182        test_cmp expect actual &&
1183        git -c v.a.r=val -c v.a.R=VAL config --get V.a.R >actual &&
1184        test_cmp expect actual &&
1185        git -c v.a.r=val -c V.a.r=VAL config --get V.a.R >actual &&
1186        test_cmp expect actual
1187'
1188
1189test_expect_success 'old-fashioned settings are case insensitive' '
1190        test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1191
1192        cat >testConfig_actual <<-EOF &&
1193                [V.A]
1194                r = value1
1195        EOF
1196        q_to_tab >testConfig_expect <<-EOF &&
1197                [V.A]
1198                Qr = value2
1199        EOF
1200        git config -f testConfig_actual "v.a.r" value2 &&
1201        test_cmp testConfig_expect testConfig_actual &&
1202
1203        cat >testConfig_actual <<-EOF &&
1204                [V.A]
1205                r = value1
1206        EOF
1207        q_to_tab >testConfig_expect <<-EOF &&
1208                [V.A]
1209                QR = value2
1210        EOF
1211        git config -f testConfig_actual "V.a.R" value2 &&
1212        test_cmp testConfig_expect testConfig_actual &&
1213
1214        cat >testConfig_actual <<-EOF &&
1215                [V.A]
1216                r = value1
1217        EOF
1218        q_to_tab >testConfig_expect <<-EOF &&
1219                [V.A]
1220                r = value1
1221                Qr = value2
1222        EOF
1223        git config -f testConfig_actual "V.A.r" value2 &&
1224        test_cmp testConfig_expect testConfig_actual &&
1225
1226        cat >testConfig_actual <<-EOF &&
1227                [V.A]
1228                r = value1
1229        EOF
1230        q_to_tab >testConfig_expect <<-EOF &&
1231                [V.A]
1232                r = value1
1233                Qr = value2
1234        EOF
1235        git config -f testConfig_actual "v.A.r" value2 &&
1236        test_cmp testConfig_expect testConfig_actual
1237'
1238
1239test_expect_success 'setting different case sensitive subsections ' '
1240        test_when_finished "rm -f testConfig testConfig_expect testConfig_actual" &&
1241
1242        cat >testConfig_actual <<-EOF &&
1243                [V "A"]
1244                R = v1
1245                [K "E"]
1246                Y = v1
1247                [a "b"]
1248                c = v1
1249                [d "e"]
1250                f = v1
1251        EOF
1252        q_to_tab >testConfig_expect <<-EOF &&
1253                [V "A"]
1254                Qr = v2
1255                [K "E"]
1256                Qy = v2
1257                [a "b"]
1258                Qc = v2
1259                [d "e"]
1260                f = v1
1261                [d "E"]
1262                Qf = v2
1263        EOF
1264        # exact match
1265        git config -f testConfig_actual a.b.c v2 &&
1266        # match section and subsection, key is cased differently.
1267        git config -f testConfig_actual K.E.y v2 &&
1268        # section and key are matched case insensitive, but subsection needs
1269        # to match; When writing out new values only the key is adjusted
1270        git config -f testConfig_actual v.A.r v2 &&
1271        # subsection is not matched:
1272        git config -f testConfig_actual d.E.f v2 &&
1273        test_cmp testConfig_expect testConfig_actual
1274'
1275
1276for VAR in a .a a. a.0b a."b c". a."b c".0d
1277do
1278        test_expect_success "git -c $VAR=VAL rejects invalid '$VAR'" '
1279                test_must_fail git -c "$VAR=VAL" config -l
1280        '
1281done
1282
1283for VAR in a.b a."b c".d
1284do
1285        test_expect_success "git -c $VAR=VAL works with valid '$VAR'" '
1286                echo VAL >expect &&
1287                git -c "$VAR=VAL" config --get "$VAR" >actual &&
1288                test_cmp expect actual
1289        '
1290done
1291
1292test_expect_success 'git -c is not confused by empty environment' '
1293        GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list
1294'
1295
1296sq="'"
1297test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' '
1298        cat >expect <<-\EOF &&
1299        env.one one
1300        env.two two
1301        EOF
1302        GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq} ${sq}env.two=two${sq}" \
1303                git config --get-regexp "env.*" >actual &&
1304        test_cmp expect actual &&
1305
1306        cat >expect <<-EOF &&
1307        env.one one${sq}
1308        env.two two
1309        EOF
1310        GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq$sq$sq ${sq}env.two=two${sq}" \
1311                git config --get-regexp "env.*" >actual &&
1312        test_cmp expect actual &&
1313
1314        test_must_fail env \
1315                GIT_CONFIG_PARAMETERS="${sq}env.one=one${sq}\\$sq ${sq}env.two=two${sq}" \
1316                git config --get-regexp "env.*"
1317'
1318
1319test_expect_success 'git config --edit works' '
1320        git config -f tmp test.value no &&
1321        echo test.value=yes >expect &&
1322        GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit &&
1323        git config -f tmp --list >actual &&
1324        test_cmp expect actual
1325'
1326
1327test_expect_success 'git config --edit respects core.editor' '
1328        git config -f tmp test.value no &&
1329        echo test.value=yes >expect &&
1330        test_config core.editor "echo [test]value=yes >" &&
1331        git config -f tmp --edit &&
1332        git config -f tmp --list >actual &&
1333        test_cmp expect actual
1334'
1335
1336# malformed configuration files
1337test_expect_success 'barf on syntax error' '
1338        cat >.git/config <<-\EOF &&
1339        # broken section line
1340        [section]
1341        key garbage
1342        EOF
1343        test_must_fail git config --get section.key >actual 2>error &&
1344        test_i18ngrep " line 3 " error
1345'
1346
1347test_expect_success 'barf on incomplete section header' '
1348        cat >.git/config <<-\EOF &&
1349        # broken section line
1350        [section
1351        key = value
1352        EOF
1353        test_must_fail git config --get section.key >actual 2>error &&
1354        test_i18ngrep " line 2 " error
1355'
1356
1357test_expect_success 'barf on incomplete string' '
1358        cat >.git/config <<-\EOF &&
1359        # broken section line
1360        [section]
1361        key = "value string
1362        EOF
1363        test_must_fail git config --get section.key >actual 2>error &&
1364        test_i18ngrep " line 3 " error
1365'
1366
1367test_expect_success 'urlmatch' '
1368        cat >.git/config <<-\EOF &&
1369        [http]
1370                sslVerify
1371        [http "https://weak.example.com"]
1372                sslVerify = false
1373                cookieFile = /tmp/cookie.txt
1374        EOF
1375
1376        test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
1377        test_must_be_empty actual &&
1378
1379        echo true >expect &&
1380        git config --bool --get-urlmatch http.SSLverify https://good.example.com >actual &&
1381        test_cmp expect actual &&
1382
1383        echo false >expect &&
1384        git config --bool --get-urlmatch http.sslverify https://weak.example.com >actual &&
1385        test_cmp expect actual &&
1386
1387        {
1388                echo http.cookiefile /tmp/cookie.txt &&
1389                echo http.sslverify false
1390        } >expect &&
1391        git config --get-urlmatch HTTP https://weak.example.com >actual &&
1392        test_cmp expect actual
1393'
1394
1395test_expect_success 'urlmatch favors more specific URLs' '
1396        cat >.git/config <<-\EOF &&
1397        [http "https://example.com/"]
1398                cookieFile = /tmp/root.txt
1399        [http "https://example.com/subdirectory"]
1400                cookieFile = /tmp/subdirectory.txt
1401        [http "https://user@example.com/"]
1402                cookieFile = /tmp/user.txt
1403        [http "https://averylonguser@example.com/"]
1404                cookieFile = /tmp/averylonguser.txt
1405        [http "https://preceding.example.com"]
1406                cookieFile = /tmp/preceding.txt
1407        [http "https://*.example.com"]
1408                cookieFile = /tmp/wildcard.txt
1409        [http "https://*.example.com/wildcardwithsubdomain"]
1410                cookieFile = /tmp/wildcardwithsubdomain.txt
1411        [http "https://trailing.example.com"]
1412                cookieFile = /tmp/trailing.txt
1413        [http "https://user@*.example.com/"]
1414                cookieFile = /tmp/wildcardwithuser.txt
1415        [http "https://sub.example.com/"]
1416                cookieFile = /tmp/sub.txt
1417        EOF
1418
1419        echo http.cookiefile /tmp/root.txt >expect &&
1420        git config --get-urlmatch HTTP https://example.com >actual &&
1421        test_cmp expect actual &&
1422
1423        echo http.cookiefile /tmp/subdirectory.txt >expect &&
1424        git config --get-urlmatch HTTP https://example.com/subdirectory >actual &&
1425        test_cmp expect actual &&
1426
1427        echo http.cookiefile /tmp/subdirectory.txt >expect &&
1428        git config --get-urlmatch HTTP https://example.com/subdirectory/nested >actual &&
1429        test_cmp expect actual &&
1430
1431        echo http.cookiefile /tmp/user.txt >expect &&
1432        git config --get-urlmatch HTTP https://user@example.com/ >actual &&
1433        test_cmp expect actual &&
1434
1435        echo http.cookiefile /tmp/subdirectory.txt >expect &&
1436        git config --get-urlmatch HTTP https://averylonguser@example.com/subdirectory >actual &&
1437        test_cmp expect actual &&
1438
1439        echo http.cookiefile /tmp/preceding.txt >expect &&
1440        git config --get-urlmatch HTTP https://preceding.example.com >actual &&
1441        test_cmp expect actual &&
1442
1443        echo http.cookiefile /tmp/wildcard.txt >expect &&
1444        git config --get-urlmatch HTTP https://wildcard.example.com >actual &&
1445        test_cmp expect actual &&
1446
1447        echo http.cookiefile /tmp/sub.txt >expect &&
1448        git config --get-urlmatch HTTP https://sub.example.com/wildcardwithsubdomain >actual &&
1449        test_cmp expect actual &&
1450
1451        echo http.cookiefile /tmp/trailing.txt >expect &&
1452        git config --get-urlmatch HTTP https://trailing.example.com >actual &&
1453        test_cmp expect actual &&
1454
1455        echo http.cookiefile /tmp/sub.txt >expect &&
1456        git config --get-urlmatch HTTP https://user@sub.example.com >actual &&
1457        test_cmp expect actual
1458'
1459
1460test_expect_success 'urlmatch with wildcard' '
1461        cat >.git/config <<-\EOF &&
1462        [http]
1463                sslVerify
1464        [http "https://*.example.com"]
1465                sslVerify = false
1466                cookieFile = /tmp/cookie.txt
1467        EOF
1468
1469        test_expect_code 1 git config --bool --get-urlmatch doesnt.exist https://good.example.com >actual &&
1470        test_must_be_empty actual &&
1471
1472        echo true >expect &&
1473        git config --bool --get-urlmatch http.SSLverify https://example.com >actual &&
1474        test_cmp expect actual &&
1475
1476        echo true >expect &&
1477        git config --bool --get-urlmatch http.SSLverify https://good-example.com >actual &&
1478        test_cmp expect actual &&
1479
1480        echo true >expect &&
1481        git config --bool --get-urlmatch http.sslverify https://deep.nested.example.com >actual &&
1482        test_cmp expect actual &&
1483
1484        echo false >expect &&
1485        git config --bool --get-urlmatch http.sslverify https://good.example.com >actual &&
1486        test_cmp expect actual &&
1487
1488        {
1489                echo http.cookiefile /tmp/cookie.txt &&
1490                echo http.sslverify false
1491        } >expect &&
1492        git config --get-urlmatch HTTP https://good.example.com >actual &&
1493        test_cmp expect actual &&
1494
1495        echo http.sslverify >expect &&
1496        git config --get-urlmatch HTTP https://more.example.com.au >actual &&
1497        test_cmp expect actual
1498'
1499
1500# good section hygiene
1501test_expect_success '--unset last key removes section (except if commented)' '
1502        cat >.git/config <<-\EOF &&
1503        # some generic comment on the configuration file itself
1504        # a comment specific to this "section" section.
1505        [section]
1506        # some intervening lines
1507        # that should also be dropped
1508
1509        key = value
1510        # please be careful when you update the above variable
1511        EOF
1512
1513        cat >expect <<-\EOF &&
1514        # some generic comment on the configuration file itself
1515        # a comment specific to this "section" section.
1516        [section]
1517        # some intervening lines
1518        # that should also be dropped
1519
1520        # please be careful when you update the above variable
1521        EOF
1522
1523        git config --unset section.key &&
1524        test_cmp expect .git/config &&
1525
1526        cat >.git/config <<-\EOF &&
1527        [section]
1528        key = value
1529        [next-section]
1530        EOF
1531
1532        cat >expect <<-\EOF &&
1533        [next-section]
1534        EOF
1535
1536        git config --unset section.key &&
1537        test_cmp expect .git/config &&
1538
1539        q_to_tab >.git/config <<-\EOF &&
1540        [one]
1541        Qkey = "multiline \
1542        QQ# with comment"
1543        [two]
1544        key = true
1545        EOF
1546        git config --unset two.key &&
1547        ! grep two .git/config &&
1548
1549        q_to_tab >.git/config <<-\EOF &&
1550        [one]
1551        Qkey = "multiline \
1552        QQ# with comment"
1553        [one]
1554        key = true
1555        EOF
1556        git config --unset-all one.key &&
1557        test_line_count = 0 .git/config &&
1558
1559        q_to_tab >.git/config <<-\EOF &&
1560        [one]
1561        Qkey = true
1562        Q# a comment not at the start
1563        [two]
1564        Qkey = true
1565        EOF
1566        git config --unset two.key &&
1567        grep two .git/config &&
1568
1569        q_to_tab >.git/config <<-\EOF &&
1570        [one]
1571        Qkey = not [two "subsection"]
1572        [two "subsection"]
1573        [two "subsection"]
1574        Qkey = true
1575        [TWO "subsection"]
1576        [one]
1577        EOF
1578        git config --unset two.subsection.key &&
1579        test "not [two subsection]" = "$(git config one.key)" &&
1580        test_line_count = 3 .git/config
1581'
1582
1583test_expect_success '--unset-all removes section if empty & uncommented' '
1584        cat >.git/config <<-\EOF &&
1585        [section]
1586        key = value1
1587        key = value2
1588        EOF
1589
1590        git config --unset-all section.key &&
1591        test_line_count = 0 .git/config
1592'
1593
1594test_expect_success 'adding a key into an empty section reuses header' '
1595        cat >.git/config <<-\EOF &&
1596        [section]
1597        EOF
1598
1599        q_to_tab >expect <<-\EOF &&
1600        [section]
1601        Qkey = value
1602        EOF
1603
1604        git config section.key value &&
1605        test_cmp expect .git/config
1606'
1607
1608test_expect_success POSIXPERM,PERL 'preserves existing permissions' '
1609        chmod 0600 .git/config &&
1610        git config imap.pass Hunter2 &&
1611        perl -e \
1612          "die q(badset) if ((stat(q(.git/config)))[2] & 07777) != 0600" &&
1613        git config --rename-section imap pop &&
1614        perl -e \
1615          "die q(badrename) if ((stat(q(.git/config)))[2] & 07777) != 0600"
1616'
1617
1618! test_have_prereq MINGW ||
1619HOME="$(pwd)" # convert to Windows path
1620
1621test_expect_success 'set up --show-origin tests' '
1622        INCLUDE_DIR="$HOME/include" &&
1623        mkdir -p "$INCLUDE_DIR" &&
1624        cat >"$INCLUDE_DIR"/absolute.include <<-\EOF &&
1625                [user]
1626                        absolute = include
1627        EOF
1628        cat >"$INCLUDE_DIR"/relative.include <<-\EOF &&
1629                [user]
1630                        relative = include
1631        EOF
1632        cat >"$HOME"/.gitconfig <<-EOF &&
1633                [user]
1634                        global = true
1635                        override = global
1636                [include]
1637                        path = "$INCLUDE_DIR/absolute.include"
1638        EOF
1639        cat >.git/config <<-\EOF
1640                [user]
1641                        local = true
1642                        override = local
1643                [include]
1644                        path = ../include/relative.include
1645        EOF
1646'
1647
1648test_expect_success '--show-origin with --list' '
1649        cat >expect <<-EOF &&
1650                file:$HOME/.gitconfig   user.global=true
1651                file:$HOME/.gitconfig   user.override=global
1652                file:$HOME/.gitconfig   include.path=$INCLUDE_DIR/absolute.include
1653                file:$INCLUDE_DIR/absolute.include      user.absolute=include
1654                file:.git/config        user.local=true
1655                file:.git/config        user.override=local
1656                file:.git/config        include.path=../include/relative.include
1657                file:.git/../include/relative.include   user.relative=include
1658                command line:   user.cmdline=true
1659        EOF
1660        git -c user.cmdline=true config --list --show-origin >output &&
1661        test_cmp expect output
1662'
1663
1664test_expect_success '--show-origin with --list --null' '
1665        cat >expect <<-EOF &&
1666                file:$HOME/.gitconfigQuser.global
1667                trueQfile:$HOME/.gitconfigQuser.override
1668                globalQfile:$HOME/.gitconfigQinclude.path
1669                $INCLUDE_DIR/absolute.includeQfile:$INCLUDE_DIR/absolute.includeQuser.absolute
1670                includeQfile:.git/configQuser.local
1671                trueQfile:.git/configQuser.override
1672                localQfile:.git/configQinclude.path
1673                ../include/relative.includeQfile:.git/../include/relative.includeQuser.relative
1674                includeQcommand line:Quser.cmdline
1675                trueQ
1676        EOF
1677        git -c user.cmdline=true config --null --list --show-origin >output.raw &&
1678        nul_to_q <output.raw >output &&
1679        # The here-doc above adds a newline that the --null output would not
1680        # include. Add it here to make the two comparable.
1681        echo >>output &&
1682        test_cmp expect output
1683'
1684
1685test_expect_success '--show-origin with single file' '
1686        cat >expect <<-\EOF &&
1687                file:.git/config        user.local=true
1688                file:.git/config        user.override=local
1689                file:.git/config        include.path=../include/relative.include
1690        EOF
1691        git config --local --list --show-origin >output &&
1692        test_cmp expect output
1693'
1694
1695test_expect_success '--show-origin with --get-regexp' '
1696        cat >expect <<-EOF &&
1697                file:$HOME/.gitconfig   user.global true
1698                file:.git/config        user.local true
1699        EOF
1700        git config --show-origin --get-regexp "user\.[g|l].*" >output &&
1701        test_cmp expect output
1702'
1703
1704test_expect_success '--show-origin getting a single key' '
1705        cat >expect <<-\EOF &&
1706                file:.git/config        local
1707        EOF
1708        git config --show-origin user.override >output &&
1709        test_cmp expect output
1710'
1711
1712test_expect_success 'set up custom config file' '
1713        CUSTOM_CONFIG_FILE="file\" (dq) and spaces.conf" &&
1714        cat >"$CUSTOM_CONFIG_FILE" <<-\EOF
1715                [user]
1716                        custom = true
1717        EOF
1718'
1719
1720test_expect_success !MINGW '--show-origin escape special file name characters' '
1721        cat >expect <<-\EOF &&
1722                file:"file\" (dq) and spaces.conf"      user.custom=true
1723        EOF
1724        git config --file "$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
1725        test_cmp expect output
1726'
1727
1728test_expect_success '--show-origin stdin' '
1729        cat >expect <<-\EOF &&
1730                standard input: user.custom=true
1731        EOF
1732        git config --file - --show-origin --list <"$CUSTOM_CONFIG_FILE" >output &&
1733        test_cmp expect output
1734'
1735
1736test_expect_success '--show-origin stdin with file include' '
1737        cat >"$INCLUDE_DIR"/stdin.include <<-EOF &&
1738                [user]
1739                        stdin = include
1740        EOF
1741        cat >expect <<-EOF &&
1742                file:$INCLUDE_DIR/stdin.include include
1743        EOF
1744        echo "[include]path=\"$INCLUDE_DIR\"/stdin.include" |
1745        git config --show-origin --includes --file - user.stdin >output &&
1746
1747        test_cmp expect output
1748'
1749
1750test_expect_success !MINGW '--show-origin blob' '
1751        blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
1752        cat >expect <<-EOF &&
1753                blob:$blob      user.custom=true
1754        EOF
1755        git config --blob=$blob --show-origin --list >output &&
1756        test_cmp expect output
1757'
1758
1759test_expect_success !MINGW '--show-origin blob ref' '
1760        cat >expect <<-\EOF &&
1761                blob:"master:file\" (dq) and spaces.conf"       user.custom=true
1762        EOF
1763        git add "$CUSTOM_CONFIG_FILE" &&
1764        git commit -m "new config file" &&
1765        git config --blob=master:"$CUSTOM_CONFIG_FILE" --show-origin --list >output &&
1766        test_cmp expect output
1767'
1768
1769test_expect_success '--local requires a repo' '
1770        # we expect 128 to ensure that we do not simply
1771        # fail to find anything and return code "1"
1772        test_expect_code 128 nongit git config --local foo.bar
1773'
1774
1775cat >.git/config <<-\EOF &&
1776[core]
1777foo = true
1778number = 10
1779big = 1M
1780EOF
1781
1782test_expect_success 'identical modern --type specifiers are allowed' '
1783        test_cmp_config 1048576 --type=int --type=int core.big
1784'
1785
1786test_expect_success 'identical legacy --type specifiers are allowed' '
1787        test_cmp_config 1048576 --int --int core.big
1788'
1789
1790test_expect_success 'identical mixed --type specifiers are allowed' '
1791        test_cmp_config 1048576 --int --type=int core.big
1792'
1793
1794test_expect_success 'non-identical modern --type specifiers are not allowed' '
1795        test_must_fail git config --type=int --type=bool core.big 2>error &&
1796        test_i18ngrep "only one type at a time" error
1797'
1798
1799test_expect_success 'non-identical legacy --type specifiers are not allowed' '
1800        test_must_fail git config --int --bool core.big 2>error &&
1801        test_i18ngrep "only one type at a time" error
1802'
1803
1804test_expect_success 'non-identical mixed --type specifiers are not allowed' '
1805        test_must_fail git config --type=int --bool core.big 2>error &&
1806        test_i18ngrep "only one type at a time" error
1807'
1808
1809test_expect_success '--type allows valid type specifiers' '
1810        test_cmp_config true  --type=bool core.foo
1811'
1812
1813test_expect_success '--no-type unsets type specifiers' '
1814        test_cmp_config 10 --type=bool --no-type core.number
1815'
1816
1817test_expect_success 'unset type specifiers may be reset to conflicting ones' '
1818        test_cmp_config 1048576 --type=bool --no-type --type=int core.big
1819'
1820
1821test_expect_success '--type rejects unknown specifiers' '
1822        test_must_fail git config --type=nonsense core.foo 2>error &&
1823        test_i18ngrep "unrecognized --type argument" error
1824'
1825
1826test_expect_success '--replace-all does not invent newlines' '
1827        q_to_tab >.git/config <<-\EOF &&
1828        [abc]key
1829        QkeepSection
1830        [xyz]
1831        Qkey = 1
1832        [abc]
1833        Qkey = a
1834        EOF
1835        q_to_tab >expect <<-\EOF &&
1836        [abc]
1837        QkeepSection
1838        [xyz]
1839        Qkey = 1
1840        [abc]
1841        Qkey = b
1842        EOF
1843        git config --replace-all abc.key b &&
1844        test_cmp expect .git/config
1845'
1846
1847test_done