7956cb9b16d5fcda6fe5eeecca7f4af929f16900
   1#!/bin/sh
   2#
   3# Copyright (c) 2012 Felipe Contreras
   4#
   5
   6test_description='test bash completion'
   7
   8. ./lib-bash.sh
   9
  10complete ()
  11{
  12        # do nothing
  13        return 0
  14}
  15
  16# Be careful when updating this list:
  17#
  18# (1) The build tree may have build artifact from different branch, or
  19#     the user's $PATH may have a random executable that may begin
  20#     with "git-check" that are not part of the subcommands this build
  21#     will ship, e.g.  "check-ignore".  The tests for completion for
  22#     subcommand names tests how "check" is expanded; we limit the
  23#     possible candidates to "checkout" and "check-attr" to make sure
  24#     "check-attr", which is known by the filter function as a
  25#     subcommand to be thrown out, while excluding other random files
  26#     that happen to begin with "check" to avoid letting them get in
  27#     the way.
  28#
  29# (2) A test makes sure that common subcommands are included in the
  30#     completion for "git <TAB>", and a plumbing is excluded.  "add",
  31#     "filter-branch" and "ls-files" are listed for this.
  32
  33GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files'
  34
  35. "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
  36
  37# We don't need this function to actually join words or do anything special.
  38# Also, it's cleaner to avoid touching bash's internal completion variables.
  39# So let's override it with a minimal version for testing purposes.
  40_get_comp_words_by_ref ()
  41{
  42        while [ $# -gt 0 ]; do
  43                case "$1" in
  44                cur)
  45                        cur=${_words[_cword]}
  46                        ;;
  47                prev)
  48                        prev=${_words[_cword-1]}
  49                        ;;
  50                words)
  51                        words=("${_words[@]}")
  52                        ;;
  53                cword)
  54                        cword=$_cword
  55                        ;;
  56                esac
  57                shift
  58        done
  59}
  60
  61print_comp ()
  62{
  63        local IFS=$'\n'
  64        echo "${COMPREPLY[*]}" > out
  65}
  66
  67run_completion ()
  68{
  69        local -a COMPREPLY _words
  70        local _cword
  71        _words=( $1 )
  72        test "${1: -1}" = ' ' && _words[${#_words[@]}+1]=''
  73        (( _cword = ${#_words[@]} - 1 ))
  74        __git_wrap__git_main && print_comp
  75}
  76
  77# Test high-level completion
  78# Arguments are:
  79# 1: typed text so far (cur)
  80# 2: expected completion
  81test_completion ()
  82{
  83        if test $# -gt 1
  84        then
  85                printf '%s\n' "$2" >expected
  86        else
  87                sed -e 's/Z$//' >expected
  88        fi &&
  89        run_completion "$1" &&
  90        test_cmp expected out
  91}
  92
  93# Test __gitcomp.
  94# The first argument is the typed text so far (cur); the rest are
  95# passed to __gitcomp.  Expected output comes is read from the
  96# standard input, like test_completion().
  97test_gitcomp ()
  98{
  99        local -a COMPREPLY &&
 100        sed -e 's/Z$//' >expected &&
 101        local cur="$1" &&
 102        shift &&
 103        __gitcomp "$@" &&
 104        print_comp &&
 105        test_cmp expected out
 106}
 107
 108# Test __gitcomp_nl
 109# Arguments are:
 110# 1: current word (cur)
 111# -: the rest are passed to __gitcomp_nl
 112test_gitcomp_nl ()
 113{
 114        local -a COMPREPLY &&
 115        sed -e 's/Z$//' >expected &&
 116        local cur="$1" &&
 117        shift &&
 118        __gitcomp_nl "$@" &&
 119        print_comp &&
 120        test_cmp expected out
 121}
 122
 123invalid_variable_name='${foo.bar}'
 124
 125actual="$TRASH_DIRECTORY/actual"
 126
 127if test_have_prereq MINGW
 128then
 129        ROOT="$(pwd -W)"
 130else
 131        ROOT="$(pwd)"
 132fi
 133
 134test_expect_success 'setup for __gitdir tests' '
 135        mkdir -p subdir/subsubdir &&
 136        git init otherrepo
 137'
 138
 139test_expect_success '__gitdir - from command line (through $__git_dir)' '
 140        echo "$ROOT/otherrepo/.git" >expected &&
 141        (
 142                __git_dir="$ROOT/otherrepo/.git" &&
 143                __gitdir >"$actual"
 144        ) &&
 145        test_cmp expected "$actual"
 146'
 147
 148test_expect_success '__gitdir - repo as argument' '
 149        echo "otherrepo/.git" >expected &&
 150        __gitdir "otherrepo" >"$actual" &&
 151        test_cmp expected "$actual"
 152'
 153
 154test_expect_success '__gitdir - remote as argument' '
 155        echo "remote" >expected &&
 156        __gitdir "remote" >"$actual" &&
 157        test_cmp expected "$actual"
 158'
 159
 160test_expect_success '__gitdir - .git directory in cwd' '
 161        echo ".git" >expected &&
 162        __gitdir >"$actual" &&
 163        test_cmp expected "$actual"
 164'
 165
 166test_expect_success '__gitdir - .git directory in parent' '
 167        echo "$ROOT/.git" >expected &&
 168        (
 169                cd subdir/subsubdir &&
 170                __gitdir >"$actual"
 171        ) &&
 172        test_cmp expected "$actual"
 173'
 174
 175test_expect_success '__gitdir - cwd is a .git directory' '
 176        echo "." >expected &&
 177        (
 178                cd .git &&
 179                __gitdir >"$actual"
 180        ) &&
 181        test_cmp expected "$actual"
 182'
 183
 184test_expect_success '__gitdir - parent is a .git directory' '
 185        echo "$ROOT/.git" >expected &&
 186        (
 187                cd .git/refs/heads &&
 188                __gitdir >"$actual"
 189        ) &&
 190        test_cmp expected "$actual"
 191'
 192
 193test_expect_success '__gitdir - $GIT_DIR set while .git directory in cwd' '
 194        echo "$ROOT/otherrepo/.git" >expected &&
 195        (
 196                GIT_DIR="$ROOT/otherrepo/.git" &&
 197                export GIT_DIR &&
 198                __gitdir >"$actual"
 199        ) &&
 200        test_cmp expected "$actual"
 201'
 202
 203test_expect_success '__gitdir - $GIT_DIR set while .git directory in parent' '
 204        echo "$ROOT/otherrepo/.git" >expected &&
 205        (
 206                GIT_DIR="$ROOT/otherrepo/.git" &&
 207                export GIT_DIR &&
 208                cd subdir &&
 209                __gitdir >"$actual"
 210        ) &&
 211        test_cmp expected "$actual"
 212'
 213
 214test_expect_success '__gitdir - non-existing $GIT_DIR' '
 215        (
 216                GIT_DIR="$ROOT/non-existing" &&
 217                export GIT_DIR &&
 218                test_must_fail __gitdir >"$actual"
 219        ) &&
 220        test_must_be_empty "$actual"
 221'
 222
 223test_expect_success '__gitdir - gitfile in cwd' '
 224        echo "$ROOT/otherrepo/.git" >expected &&
 225        echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
 226        test_when_finished "rm -f subdir/.git" &&
 227        (
 228                cd subdir &&
 229                __gitdir >"$actual"
 230        ) &&
 231        test_cmp expected "$actual"
 232'
 233
 234test_expect_success '__gitdir - gitfile in parent' '
 235        echo "$ROOT/otherrepo/.git" >expected &&
 236        echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
 237        test_when_finished "rm -f subdir/.git" &&
 238        (
 239                cd subdir/subsubdir &&
 240                __gitdir >"$actual"
 241        ) &&
 242        test_cmp expected "$actual"
 243'
 244
 245test_expect_success SYMLINKS '__gitdir - resulting path avoids symlinks' '
 246        echo "$ROOT/otherrepo/.git" >expected &&
 247        mkdir otherrepo/dir &&
 248        test_when_finished "rm -rf otherrepo/dir" &&
 249        ln -s otherrepo/dir link &&
 250        test_when_finished "rm -f link" &&
 251        (
 252                cd link &&
 253                __gitdir >"$actual"
 254        ) &&
 255        test_cmp expected "$actual"
 256'
 257
 258test_expect_success '__gitdir - not a git repository' '
 259        nongit test_must_fail __gitdir >"$actual" &&
 260        test_must_be_empty "$actual"
 261'
 262
 263test_expect_success '__gitcomp - trailing space - options' '
 264        test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
 265                --reset-author" <<-EOF
 266        --reuse-message=Z
 267        --reedit-message=Z
 268        --reset-author Z
 269        EOF
 270'
 271
 272test_expect_success '__gitcomp - trailing space - config keys' '
 273        test_gitcomp "br" "branch. branch.autosetupmerge
 274                branch.autosetuprebase browser." <<-\EOF
 275        branch.Z
 276        branch.autosetupmerge Z
 277        branch.autosetuprebase Z
 278        browser.Z
 279        EOF
 280'
 281
 282test_expect_success '__gitcomp - option parameter' '
 283        test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
 284                "" "re" <<-\EOF
 285        recursive Z
 286        resolve Z
 287        EOF
 288'
 289
 290test_expect_success '__gitcomp - prefix' '
 291        test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
 292                "branch.maint." "me" <<-\EOF
 293        branch.maint.merge Z
 294        branch.maint.mergeoptions Z
 295        EOF
 296'
 297
 298test_expect_success '__gitcomp - suffix' '
 299        test_gitcomp "branch.me" "master maint next pu" "branch." \
 300                "ma" "." <<-\EOF
 301        branch.master.Z
 302        branch.maint.Z
 303        EOF
 304'
 305
 306test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
 307        __gitcomp "$invalid_variable_name"
 308'
 309
 310read -r -d "" refs <<-\EOF
 311maint
 312master
 313next
 314pu
 315EOF
 316
 317test_expect_success '__gitcomp_nl - trailing space' '
 318        test_gitcomp_nl "m" "$refs" <<-EOF
 319        maint Z
 320        master Z
 321        EOF
 322'
 323
 324test_expect_success '__gitcomp_nl - prefix' '
 325        test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
 326        --fixup=maint Z
 327        --fixup=master Z
 328        EOF
 329'
 330
 331test_expect_success '__gitcomp_nl - suffix' '
 332        test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
 333        branch.maint.Z
 334        branch.master.Z
 335        EOF
 336'
 337
 338test_expect_success '__gitcomp_nl - no suffix' '
 339        test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
 340        maintZ
 341        masterZ
 342        EOF
 343'
 344
 345test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
 346        __gitcomp_nl "$invalid_variable_name"
 347'
 348
 349test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '
 350        cat >expect <<-EOF &&
 351        remote_from_file_1
 352        remote_from_file_2
 353        remote_in_config_1
 354        remote_in_config_2
 355        EOF
 356        test_when_finished "rm -rf .git/remotes" &&
 357        mkdir -p .git/remotes &&
 358        >.git/remotes/remote_from_file_1 &&
 359        >.git/remotes/remote_from_file_2 &&
 360        test_when_finished "git remote remove remote_in_config_1" &&
 361        git remote add remote_in_config_1 git://remote_1 &&
 362        test_when_finished "git remote remove remote_in_config_2" &&
 363        git remote add remote_in_config_2 git://remote_2 &&
 364        __git_remotes >actual &&
 365        test_cmp expect actual
 366'
 367
 368test_expect_success 'setup for ref completion' '
 369        git commit --allow-empty -m initial &&
 370        git branch matching-branch &&
 371        git tag matching-tag &&
 372        (
 373                cd otherrepo &&
 374                git commit --allow-empty -m initial &&
 375                git branch -m master master-in-other &&
 376                git branch branch-in-other &&
 377                git tag tag-in-other
 378        ) &&
 379        git remote add other "$ROOT/otherrepo/.git" &&
 380        git fetch --no-tags other &&
 381        rm -f .git/FETCH_HEAD &&
 382        git init thirdrepo
 383'
 384
 385test_expect_success '__git_refs - simple' '
 386        cat >expected <<-EOF &&
 387        HEAD
 388        master
 389        matching-branch
 390        other/branch-in-other
 391        other/master-in-other
 392        matching-tag
 393        EOF
 394        (
 395                cur= &&
 396                __git_refs >"$actual"
 397        ) &&
 398        test_cmp expected "$actual"
 399'
 400
 401test_expect_success '__git_refs - full refs' '
 402        cat >expected <<-EOF &&
 403        refs/heads/master
 404        refs/heads/matching-branch
 405        EOF
 406        (
 407                cur=refs/heads/ &&
 408                __git_refs >"$actual"
 409        ) &&
 410        test_cmp expected "$actual"
 411'
 412
 413test_expect_success '__git_refs - repo given on the command line' '
 414        cat >expected <<-EOF &&
 415        HEAD
 416        branch-in-other
 417        master-in-other
 418        tag-in-other
 419        EOF
 420        (
 421                __git_dir="$ROOT/otherrepo/.git" &&
 422                cur= &&
 423                __git_refs >"$actual"
 424        ) &&
 425        test_cmp expected "$actual"
 426'
 427
 428test_expect_success '__git_refs - remote on local file system' '
 429        cat >expected <<-EOF &&
 430        HEAD
 431        branch-in-other
 432        master-in-other
 433        tag-in-other
 434        EOF
 435        (
 436                cur= &&
 437                __git_refs otherrepo >"$actual"
 438        ) &&
 439        test_cmp expected "$actual"
 440'
 441
 442test_expect_success '__git_refs - remote on local file system - full refs' '
 443        cat >expected <<-EOF &&
 444        refs/heads/branch-in-other
 445        refs/heads/master-in-other
 446        refs/tags/tag-in-other
 447        EOF
 448        (
 449                cur=refs/ &&
 450                __git_refs otherrepo >"$actual"
 451        ) &&
 452        test_cmp expected "$actual"
 453'
 454
 455test_expect_success '__git_refs - configured remote' '
 456        cat >expected <<-EOF &&
 457        HEAD
 458        branch-in-other
 459        master-in-other
 460        EOF
 461        (
 462                cur= &&
 463                __git_refs other >"$actual"
 464        ) &&
 465        test_cmp expected "$actual"
 466'
 467
 468test_expect_success '__git_refs - configured remote - full refs' '
 469        cat >expected <<-EOF &&
 470        refs/heads/branch-in-other
 471        refs/heads/master-in-other
 472        refs/tags/tag-in-other
 473        EOF
 474        (
 475                cur=refs/ &&
 476                __git_refs other >"$actual"
 477        ) &&
 478        test_cmp expected "$actual"
 479'
 480
 481test_expect_failure '__git_refs - configured remote - repo given on the command line' '
 482        cat >expected <<-EOF &&
 483        HEAD
 484        branch-in-other
 485        master-in-other
 486        EOF
 487        (
 488                cd thirdrepo &&
 489                __git_dir="$ROOT/.git" &&
 490                cur= &&
 491                __git_refs other >"$actual"
 492        ) &&
 493        test_cmp expected "$actual"
 494'
 495
 496test_expect_failure '__git_refs - configured remote - full refs - repo given on the command line' '
 497        cat >expected <<-EOF &&
 498        refs/heads/branch-in-other
 499        refs/heads/master-in-other
 500        refs/tags/tag-in-other
 501        EOF
 502        (
 503                cd thirdrepo &&
 504                __git_dir="$ROOT/.git" &&
 505                cur=refs/ &&
 506                __git_refs other >"$actual"
 507        ) &&
 508        test_cmp expected "$actual"
 509'
 510
 511test_expect_failure '__git_refs - configured remote - remote name matches a directory' '
 512        cat >expected <<-EOF &&
 513        HEAD
 514        branch-in-other
 515        master-in-other
 516        EOF
 517        mkdir other &&
 518        test_when_finished "rm -rf other" &&
 519        (
 520                cur= &&
 521                __git_refs other >"$actual"
 522        ) &&
 523        test_cmp expected "$actual"
 524'
 525
 526test_expect_failure '__git_refs - URL remote' '
 527        cat >expected <<-EOF &&
 528        HEAD
 529        branch-in-other
 530        master-in-other
 531        tag-in-other
 532        EOF
 533        (
 534                cur= &&
 535                __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
 536        ) &&
 537        test_cmp expected "$actual"
 538'
 539
 540test_expect_success '__git_refs - URL remote - full refs' '
 541        cat >expected <<-EOF &&
 542        refs/heads/branch-in-other
 543        refs/heads/master-in-other
 544        refs/tags/tag-in-other
 545        EOF
 546        (
 547                cur=refs/ &&
 548                __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
 549        ) &&
 550        test_cmp expected "$actual"
 551'
 552
 553test_expect_failure '__git_refs - non-existing remote' '
 554        (
 555                cur= &&
 556                __git_refs non-existing >"$actual"
 557        ) &&
 558        test_must_be_empty "$actual"
 559'
 560
 561test_expect_success '__git_refs - non-existing remote - full refs' '
 562        (
 563                cur=refs/ &&
 564                __git_refs non-existing >"$actual"
 565        ) &&
 566        test_must_be_empty "$actual"
 567'
 568
 569test_expect_failure '__git_refs - non-existing URL remote' '
 570        (
 571                cur= &&
 572                __git_refs "file://$ROOT/non-existing" >"$actual"
 573        ) &&
 574        test_must_be_empty "$actual"
 575'
 576
 577test_expect_success '__git_refs - non-existing URL remote - full refs' '
 578        (
 579                cur=refs/ &&
 580                __git_refs "file://$ROOT/non-existing" >"$actual"
 581        ) &&
 582        test_must_be_empty "$actual"
 583'
 584
 585test_expect_failure '__git_refs - not in a git repository' '
 586        (
 587                GIT_CEILING_DIRECTORIES="$ROOT" &&
 588                export GIT_CEILING_DIRECTORIES &&
 589                cd subdir &&
 590                cur= &&
 591                __git_refs >"$actual"
 592        ) &&
 593        test_must_be_empty "$actual"
 594'
 595
 596test_expect_success '__git_refs - unique remote branches for git checkout DWIMery' '
 597        cat >expected <<-EOF &&
 598        HEAD
 599        master
 600        matching-branch
 601        other/ambiguous
 602        other/branch-in-other
 603        other/master-in-other
 604        remote/ambiguous
 605        remote/branch-in-remote
 606        matching-tag
 607        branch-in-other
 608        branch-in-remote
 609        master-in-other
 610        EOF
 611        for remote_ref in refs/remotes/other/ambiguous \
 612                refs/remotes/remote/ambiguous \
 613                refs/remotes/remote/branch-in-remote
 614        do
 615                git update-ref $remote_ref master &&
 616                test_when_finished "git update-ref -d $remote_ref"
 617        done &&
 618        (
 619                cur= &&
 620                __git_refs "" 1 >"$actual"
 621        ) &&
 622        test_cmp expected "$actual"
 623'
 624
 625test_expect_success 'teardown after ref completion' '
 626        git branch -d matching-branch &&
 627        git tag -d matching-tag &&
 628        git remote remove other
 629'
 630
 631test_expect_success '__git_get_config_variables' '
 632        cat >expect <<-EOF &&
 633        name-1
 634        name-2
 635        EOF
 636        test_config interesting.name-1 good &&
 637        test_config interesting.name-2 good &&
 638        test_config subsection.interesting.name-3 bad &&
 639        __git_get_config_variables interesting >actual &&
 640        test_cmp expect actual
 641'
 642
 643test_expect_success '__git_pretty_aliases' '
 644        cat >expect <<-EOF &&
 645        author
 646        hash
 647        EOF
 648        test_config pretty.author "%an %ae" &&
 649        test_config pretty.hash %H &&
 650        __git_pretty_aliases >actual &&
 651        test_cmp expect actual
 652'
 653
 654test_expect_success '__git_aliases' '
 655        cat >expect <<-EOF &&
 656        ci
 657        co
 658        EOF
 659        test_config alias.ci commit &&
 660        test_config alias.co checkout &&
 661        __git_aliases >actual &&
 662        test_cmp expect actual
 663'
 664
 665test_expect_success 'basic' '
 666        run_completion "git " &&
 667        # built-in
 668        grep -q "^add \$" out &&
 669        # script
 670        grep -q "^filter-branch \$" out &&
 671        # plumbing
 672        ! grep -q "^ls-files \$" out &&
 673
 674        run_completion "git f" &&
 675        ! grep -q -v "^f" out
 676'
 677
 678test_expect_success 'double dash "git" itself' '
 679        test_completion "git --" <<-\EOF
 680        --paginate Z
 681        --no-pager Z
 682        --git-dir=
 683        --bare Z
 684        --version Z
 685        --exec-path Z
 686        --exec-path=
 687        --html-path Z
 688        --man-path Z
 689        --info-path Z
 690        --work-tree=
 691        --namespace=
 692        --no-replace-objects Z
 693        --help Z
 694        EOF
 695'
 696
 697test_expect_success 'double dash "git checkout"' '
 698        test_completion "git checkout --" <<-\EOF
 699        --quiet Z
 700        --ours Z
 701        --theirs Z
 702        --track Z
 703        --no-track Z
 704        --merge Z
 705        --conflict=
 706        --orphan Z
 707        --patch Z
 708        EOF
 709'
 710
 711test_expect_success 'general options' '
 712        test_completion "git --ver" "--version " &&
 713        test_completion "git --hel" "--help " &&
 714        test_completion "git --exe" <<-\EOF &&
 715        --exec-path Z
 716        --exec-path=
 717        EOF
 718        test_completion "git --htm" "--html-path " &&
 719        test_completion "git --pag" "--paginate " &&
 720        test_completion "git --no-p" "--no-pager " &&
 721        test_completion "git --git" "--git-dir=" &&
 722        test_completion "git --wor" "--work-tree=" &&
 723        test_completion "git --nam" "--namespace=" &&
 724        test_completion "git --bar" "--bare " &&
 725        test_completion "git --inf" "--info-path " &&
 726        test_completion "git --no-r" "--no-replace-objects "
 727'
 728
 729test_expect_success 'general options plus command' '
 730        test_completion "git --version check" "checkout " &&
 731        test_completion "git --paginate check" "checkout " &&
 732        test_completion "git --git-dir=foo check" "checkout " &&
 733        test_completion "git --bare check" "checkout " &&
 734        test_completion "git --exec-path=foo check" "checkout " &&
 735        test_completion "git --html-path check" "checkout " &&
 736        test_completion "git --no-pager check" "checkout " &&
 737        test_completion "git --work-tree=foo check" "checkout " &&
 738        test_completion "git --namespace=foo check" "checkout " &&
 739        test_completion "git --paginate check" "checkout " &&
 740        test_completion "git --info-path check" "checkout " &&
 741        test_completion "git --no-replace-objects check" "checkout "
 742'
 743
 744test_expect_success 'git --help completion' '
 745        test_completion "git --help ad" "add " &&
 746        test_completion "git --help core" "core-tutorial "
 747'
 748
 749test_expect_success 'setup for integration tests' '
 750        echo content >file1 &&
 751        echo more >file2 &&
 752        git add file1 file2 &&
 753        git commit -m one &&
 754        git branch mybranch &&
 755        git tag mytag
 756'
 757
 758test_expect_success 'checkout completes ref names' '
 759        test_completion "git checkout m" <<-\EOF
 760        master Z
 761        mybranch Z
 762        mytag Z
 763        EOF
 764'
 765
 766test_expect_success 'show completes all refs' '
 767        test_completion "git show m" <<-\EOF
 768        master Z
 769        mybranch Z
 770        mytag Z
 771        EOF
 772'
 773
 774test_expect_success '<ref>: completes paths' '
 775        test_completion "git show mytag:f" <<-\EOF
 776        file1 Z
 777        file2 Z
 778        EOF
 779'
 780
 781test_expect_success 'complete tree filename with spaces' '
 782        echo content >"name with spaces" &&
 783        git add "name with spaces" &&
 784        git commit -m spaces &&
 785        test_completion "git show HEAD:nam" <<-\EOF
 786        name with spaces Z
 787        EOF
 788'
 789
 790test_expect_success 'complete tree filename with metacharacters' '
 791        echo content >"name with \${meta}" &&
 792        git add "name with \${meta}" &&
 793        git commit -m meta &&
 794        test_completion "git show HEAD:nam" <<-\EOF
 795        name with ${meta} Z
 796        name with spaces Z
 797        EOF
 798'
 799
 800test_expect_success 'send-email' '
 801        test_completion "git send-email --cov" "--cover-letter " &&
 802        test_completion "git send-email ma" "master "
 803'
 804
 805test_expect_success 'complete files' '
 806        git init tmp && cd tmp &&
 807        test_when_finished "cd .. && rm -rf tmp" &&
 808
 809        echo "expected" > .gitignore &&
 810        echo "out" >> .gitignore &&
 811
 812        git add .gitignore &&
 813        test_completion "git commit " ".gitignore" &&
 814
 815        git commit -m ignore &&
 816
 817        touch new &&
 818        test_completion "git add " "new" &&
 819
 820        git add new &&
 821        git commit -a -m new &&
 822        test_completion "git add " "" &&
 823
 824        git mv new modified &&
 825        echo modify > modified &&
 826        test_completion "git add " "modified" &&
 827
 828        touch untracked &&
 829
 830        : TODO .gitignore should not be here &&
 831        test_completion "git rm " <<-\EOF &&
 832        .gitignore
 833        modified
 834        EOF
 835
 836        test_completion "git clean " "untracked" &&
 837
 838        : TODO .gitignore should not be here &&
 839        test_completion "git mv " <<-\EOF &&
 840        .gitignore
 841        modified
 842        EOF
 843
 844        mkdir dir &&
 845        touch dir/file-in-dir &&
 846        git add dir/file-in-dir &&
 847        git commit -m dir &&
 848
 849        mkdir untracked-dir &&
 850
 851        : TODO .gitignore should not be here &&
 852        test_completion "git mv modified " <<-\EOF &&
 853        .gitignore
 854        dir
 855        modified
 856        untracked
 857        untracked-dir
 858        EOF
 859
 860        test_completion "git commit " "modified" &&
 861
 862        : TODO .gitignore should not be here &&
 863        test_completion "git ls-files " <<-\EOF &&
 864        .gitignore
 865        dir
 866        modified
 867        EOF
 868
 869        touch momified &&
 870        test_completion "git add mom" "momified"
 871'
 872
 873test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
 874        test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
 875        test_completion "git co m" <<-\EOF
 876        master Z
 877        mybranch Z
 878        mytag Z
 879        EOF
 880'
 881
 882test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
 883        test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
 884        test_completion "git co m" <<-\EOF
 885        master Z
 886        mybranch Z
 887        mytag Z
 888        EOF
 889'
 890
 891test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
 892        test_config alias.co "!f() { : git checkout ; if ... } f" &&
 893        test_completion "git co m" <<-\EOF
 894        master Z
 895        mybranch Z
 896        mytag Z
 897        EOF
 898'
 899
 900test_expect_failure 'complete with tilde expansion' '
 901        git init tmp && cd tmp &&
 902        test_when_finished "cd .. && rm -rf tmp" &&
 903
 904        touch ~/tmp/file &&
 905
 906        test_completion "git add ~/tmp/" "~/tmp/file"
 907'
 908
 909test_done