t / t9902-completion.shon commit Merge remote-tracking branch 'git-po/maint' (adf9927)
   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$//' |sort >expected
  88        fi &&
  89        run_completion "$1" &&
  90        sort out >out_sorted &&
  91        test_cmp expected out_sorted
  92}
  93
  94# Test __gitcomp.
  95# The first argument is the typed text so far (cur); the rest are
  96# passed to __gitcomp.  Expected output comes is read from the
  97# standard input, like test_completion().
  98test_gitcomp ()
  99{
 100        local -a COMPREPLY &&
 101        sed -e 's/Z$//' >expected &&
 102        local cur="$1" &&
 103        shift &&
 104        __gitcomp "$@" &&
 105        print_comp &&
 106        test_cmp expected out
 107}
 108
 109# Test __gitcomp_nl
 110# Arguments are:
 111# 1: current word (cur)
 112# -: the rest are passed to __gitcomp_nl
 113test_gitcomp_nl ()
 114{
 115        local -a COMPREPLY &&
 116        sed -e 's/Z$//' >expected &&
 117        local cur="$1" &&
 118        shift &&
 119        __gitcomp_nl "$@" &&
 120        print_comp &&
 121        test_cmp expected out
 122}
 123
 124invalid_variable_name='${foo.bar}'
 125
 126actual="$TRASH_DIRECTORY/actual"
 127
 128if test_have_prereq MINGW
 129then
 130        ROOT="$(pwd -W)"
 131else
 132        ROOT="$(pwd)"
 133fi
 134
 135test_expect_success 'setup for __git_find_repo_path/__gitdir tests' '
 136        mkdir -p subdir/subsubdir &&
 137        mkdir -p non-repo &&
 138        git init otherrepo
 139'
 140
 141test_expect_success '__git_find_repo_path - from command line (through $__git_dir)' '
 142        echo "$ROOT/otherrepo/.git" >expected &&
 143        (
 144                __git_dir="$ROOT/otherrepo/.git" &&
 145                __git_find_repo_path &&
 146                echo "$__git_repo_path" >"$actual"
 147        ) &&
 148        test_cmp expected "$actual"
 149'
 150
 151test_expect_success '__git_find_repo_path - .git directory in cwd' '
 152        echo ".git" >expected &&
 153        (
 154                __git_find_repo_path &&
 155                echo "$__git_repo_path" >"$actual"
 156        ) &&
 157        test_cmp expected "$actual"
 158'
 159
 160test_expect_success '__git_find_repo_path - .git directory in parent' '
 161        echo "$ROOT/.git" >expected &&
 162        (
 163                cd subdir/subsubdir &&
 164                __git_find_repo_path &&
 165                echo "$__git_repo_path" >"$actual"
 166        ) &&
 167        test_cmp expected "$actual"
 168'
 169
 170test_expect_success '__git_find_repo_path - cwd is a .git directory' '
 171        echo "." >expected &&
 172        (
 173                cd .git &&
 174                __git_find_repo_path &&
 175                echo "$__git_repo_path" >"$actual"
 176        ) &&
 177        test_cmp expected "$actual"
 178'
 179
 180test_expect_success '__git_find_repo_path - parent is a .git directory' '
 181        echo "$ROOT/.git" >expected &&
 182        (
 183                cd .git/refs/heads &&
 184                __git_find_repo_path &&
 185                echo "$__git_repo_path" >"$actual"
 186        ) &&
 187        test_cmp expected "$actual"
 188'
 189
 190test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in cwd' '
 191        echo "$ROOT/otherrepo/.git" >expected &&
 192        (
 193                GIT_DIR="$ROOT/otherrepo/.git" &&
 194                export GIT_DIR &&
 195                __git_find_repo_path &&
 196                echo "$__git_repo_path" >"$actual"
 197        ) &&
 198        test_cmp expected "$actual"
 199'
 200
 201test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in parent' '
 202        echo "$ROOT/otherrepo/.git" >expected &&
 203        (
 204                GIT_DIR="$ROOT/otherrepo/.git" &&
 205                export GIT_DIR &&
 206                cd subdir &&
 207                __git_find_repo_path &&
 208                echo "$__git_repo_path" >"$actual"
 209        ) &&
 210        test_cmp expected "$actual"
 211'
 212
 213test_expect_success '__git_find_repo_path - from command line while "git -C"' '
 214        echo "$ROOT/.git" >expected &&
 215        (
 216                __git_dir="$ROOT/.git" &&
 217                __git_C_args=(-C otherrepo) &&
 218                __git_find_repo_path &&
 219                echo "$__git_repo_path" >"$actual"
 220        ) &&
 221        test_cmp expected "$actual"
 222'
 223
 224test_expect_success '__git_find_repo_path - relative dir from command line and "git -C"' '
 225        echo "$ROOT/otherrepo/.git" >expected &&
 226        (
 227                cd subdir &&
 228                __git_dir="otherrepo/.git" &&
 229                __git_C_args=(-C ..) &&
 230                __git_find_repo_path &&
 231                echo "$__git_repo_path" >"$actual"
 232        ) &&
 233        test_cmp expected "$actual"
 234'
 235
 236test_expect_success '__git_find_repo_path - $GIT_DIR set while "git -C"' '
 237        echo "$ROOT/.git" >expected &&
 238        (
 239                GIT_DIR="$ROOT/.git" &&
 240                export GIT_DIR &&
 241                __git_C_args=(-C otherrepo) &&
 242                __git_find_repo_path &&
 243                echo "$__git_repo_path" >"$actual"
 244        ) &&
 245        test_cmp expected "$actual"
 246'
 247
 248test_expect_success '__git_find_repo_path - relative dir in $GIT_DIR and "git -C"' '
 249        echo "$ROOT/otherrepo/.git" >expected &&
 250        (
 251                cd subdir &&
 252                GIT_DIR="otherrepo/.git" &&
 253                export GIT_DIR &&
 254                __git_C_args=(-C ..) &&
 255                __git_find_repo_path &&
 256                echo "$__git_repo_path" >"$actual"
 257        ) &&
 258        test_cmp expected "$actual"
 259'
 260
 261test_expect_success '__git_find_repo_path - "git -C" while .git directory in cwd' '
 262        echo "$ROOT/otherrepo/.git" >expected &&
 263        (
 264                __git_C_args=(-C otherrepo) &&
 265                __git_find_repo_path &&
 266                echo "$__git_repo_path" >"$actual"
 267        ) &&
 268        test_cmp expected "$actual"
 269'
 270
 271test_expect_success '__git_find_repo_path - "git -C" while cwd is a .git directory' '
 272        echo "$ROOT/otherrepo/.git" >expected &&
 273        (
 274                cd .git &&
 275                __git_C_args=(-C .. -C otherrepo) &&
 276                __git_find_repo_path &&
 277                echo "$__git_repo_path" >"$actual"
 278        ) &&
 279        test_cmp expected "$actual"
 280'
 281
 282test_expect_success '__git_find_repo_path - "git -C" while .git directory in parent' '
 283        echo "$ROOT/otherrepo/.git" >expected &&
 284        (
 285                cd subdir &&
 286                __git_C_args=(-C .. -C otherrepo) &&
 287                __git_find_repo_path &&
 288                echo "$__git_repo_path" >"$actual"
 289        ) &&
 290        test_cmp expected "$actual"
 291'
 292
 293test_expect_success '__git_find_repo_path - non-existing path in "git -C"' '
 294        (
 295                __git_C_args=(-C non-existing) &&
 296                test_must_fail __git_find_repo_path &&
 297                printf "$__git_repo_path" >"$actual"
 298        ) &&
 299        test_must_be_empty "$actual"
 300'
 301
 302test_expect_success '__git_find_repo_path - non-existing path in $__git_dir' '
 303        (
 304                __git_dir="non-existing" &&
 305                test_must_fail __git_find_repo_path &&
 306                printf "$__git_repo_path" >"$actual"
 307        ) &&
 308        test_must_be_empty "$actual"
 309'
 310
 311test_expect_success '__git_find_repo_path - non-existing $GIT_DIR' '
 312        (
 313                GIT_DIR="$ROOT/non-existing" &&
 314                export GIT_DIR &&
 315                test_must_fail __git_find_repo_path &&
 316                printf "$__git_repo_path" >"$actual"
 317        ) &&
 318        test_must_be_empty "$actual"
 319'
 320
 321test_expect_success '__git_find_repo_path - gitfile in cwd' '
 322        echo "$ROOT/otherrepo/.git" >expected &&
 323        echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
 324        test_when_finished "rm -f subdir/.git" &&
 325        (
 326                cd subdir &&
 327                __git_find_repo_path &&
 328                echo "$__git_repo_path" >"$actual"
 329        ) &&
 330        test_cmp expected "$actual"
 331'
 332
 333test_expect_success '__git_find_repo_path - gitfile in parent' '
 334        echo "$ROOT/otherrepo/.git" >expected &&
 335        echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
 336        test_when_finished "rm -f subdir/.git" &&
 337        (
 338                cd subdir/subsubdir &&
 339                __git_find_repo_path &&
 340                echo "$__git_repo_path" >"$actual"
 341        ) &&
 342        test_cmp expected "$actual"
 343'
 344
 345test_expect_success SYMLINKS '__git_find_repo_path - resulting path avoids symlinks' '
 346        echo "$ROOT/otherrepo/.git" >expected &&
 347        mkdir otherrepo/dir &&
 348        test_when_finished "rm -rf otherrepo/dir" &&
 349        ln -s otherrepo/dir link &&
 350        test_when_finished "rm -f link" &&
 351        (
 352                cd link &&
 353                __git_find_repo_path &&
 354                echo "$__git_repo_path" >"$actual"
 355        ) &&
 356        test_cmp expected "$actual"
 357'
 358
 359test_expect_success '__git_find_repo_path - not a git repository' '
 360        (
 361                cd non-repo &&
 362                GIT_CEILING_DIRECTORIES="$ROOT" &&
 363                export GIT_CEILING_DIRECTORIES &&
 364                test_must_fail __git_find_repo_path &&
 365                printf "$__git_repo_path" >"$actual"
 366        ) &&
 367        test_must_be_empty "$actual"
 368'
 369
 370test_expect_success '__gitdir - finds repo' '
 371        echo "$ROOT/.git" >expected &&
 372        (
 373                cd subdir/subsubdir &&
 374                __gitdir >"$actual"
 375        ) &&
 376        test_cmp expected "$actual"
 377'
 378
 379
 380test_expect_success '__gitdir - returns error when cant find repo' '
 381        (
 382                __git_dir="non-existing" &&
 383                test_must_fail __gitdir >"$actual"
 384        ) &&
 385        test_must_be_empty "$actual"
 386'
 387
 388test_expect_success '__gitdir - repo as argument' '
 389        echo "otherrepo/.git" >expected &&
 390        (
 391                __gitdir "otherrepo" >"$actual"
 392        ) &&
 393        test_cmp expected "$actual"
 394'
 395
 396test_expect_success '__gitdir - remote as argument' '
 397        echo "remote" >expected &&
 398        (
 399                __gitdir "remote" >"$actual"
 400        ) &&
 401        test_cmp expected "$actual"
 402'
 403
 404
 405test_expect_success '__git_dequote - plain unquoted word' '
 406        __git_dequote unquoted-word &&
 407        verbose test unquoted-word = "$dequoted_word"
 408'
 409
 410# input:    b\a\c\k\'\\\"s\l\a\s\h\es
 411# expected: back'\"slashes
 412test_expect_success '__git_dequote - backslash escaped' '
 413        __git_dequote "b\a\c\k\\'\''\\\\\\\"s\l\a\s\h\es" &&
 414        verbose test "back'\''\\\"slashes" = "$dequoted_word"
 415'
 416
 417# input:    sin'gle\' '"quo'ted
 418# expected: single\ "quoted
 419test_expect_success '__git_dequote - single quoted' '
 420        __git_dequote "'"sin'gle\\\\' '\\\"quo'ted"'" &&
 421        verbose test '\''single\ "quoted'\'' = "$dequoted_word"
 422'
 423
 424# input:    dou"ble\\" "\"\quot"ed
 425# expected: double\ "\quoted
 426test_expect_success '__git_dequote - double quoted' '
 427        __git_dequote '\''dou"ble\\" "\"\quot"ed'\'' &&
 428        verbose test '\''double\ "\quoted'\'' = "$dequoted_word"
 429'
 430
 431# input: 'open single quote
 432test_expect_success '__git_dequote - open single quote' '
 433        __git_dequote "'\''open single quote" &&
 434        verbose test "open single quote" = "$dequoted_word"
 435'
 436
 437# input: "open double quote
 438test_expect_success '__git_dequote - open double quote' '
 439        __git_dequote "\"open double quote" &&
 440        verbose test "open double quote" = "$dequoted_word"
 441'
 442
 443
 444test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
 445        sed -e "s/Z$//g" >expected <<-EOF &&
 446        with-trailing-space Z
 447        without-trailing-spaceZ
 448        --option Z
 449        --option=Z
 450        $invalid_variable_name Z
 451        EOF
 452        (
 453                cur=should_be_ignored &&
 454                __gitcomp_direct "$(cat expected)" &&
 455                print_comp
 456        ) &&
 457        test_cmp expected out
 458'
 459
 460test_expect_success '__gitcomp - trailing space - options' '
 461        test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
 462                --reset-author" <<-EOF
 463        --reuse-message=Z
 464        --reedit-message=Z
 465        --reset-author Z
 466        EOF
 467'
 468
 469test_expect_success '__gitcomp - trailing space - config keys' '
 470        test_gitcomp "br" "branch. branch.autosetupmerge
 471                branch.autosetuprebase browser." <<-\EOF
 472        branch.Z
 473        branch.autosetupmerge Z
 474        branch.autosetuprebase Z
 475        browser.Z
 476        EOF
 477'
 478
 479test_expect_success '__gitcomp - option parameter' '
 480        test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
 481                "" "re" <<-\EOF
 482        recursive Z
 483        resolve Z
 484        EOF
 485'
 486
 487test_expect_success '__gitcomp - prefix' '
 488        test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
 489                "branch.maint." "me" <<-\EOF
 490        branch.maint.merge Z
 491        branch.maint.mergeoptions Z
 492        EOF
 493'
 494
 495test_expect_success '__gitcomp - suffix' '
 496        test_gitcomp "branch.me" "master maint next pu" "branch." \
 497                "ma" "." <<-\EOF
 498        branch.master.Z
 499        branch.maint.Z
 500        EOF
 501'
 502
 503test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
 504        __gitcomp "$invalid_variable_name"
 505'
 506
 507read -r -d "" refs <<-\EOF
 508maint
 509master
 510next
 511pu
 512EOF
 513
 514test_expect_success '__gitcomp_nl - trailing space' '
 515        test_gitcomp_nl "m" "$refs" <<-EOF
 516        maint Z
 517        master Z
 518        EOF
 519'
 520
 521test_expect_success '__gitcomp_nl - prefix' '
 522        test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
 523        --fixup=maint Z
 524        --fixup=master Z
 525        EOF
 526'
 527
 528test_expect_success '__gitcomp_nl - suffix' '
 529        test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
 530        branch.maint.Z
 531        branch.master.Z
 532        EOF
 533'
 534
 535test_expect_success '__gitcomp_nl - no suffix' '
 536        test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
 537        maintZ
 538        masterZ
 539        EOF
 540'
 541
 542test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
 543        __gitcomp_nl "$invalid_variable_name"
 544'
 545
 546test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '
 547        cat >expect <<-EOF &&
 548        remote_from_file_1
 549        remote_from_file_2
 550        remote_in_config_1
 551        remote_in_config_2
 552        EOF
 553        test_when_finished "rm -rf .git/remotes" &&
 554        mkdir -p .git/remotes &&
 555        >.git/remotes/remote_from_file_1 &&
 556        >.git/remotes/remote_from_file_2 &&
 557        test_when_finished "git remote remove remote_in_config_1" &&
 558        git remote add remote_in_config_1 git://remote_1 &&
 559        test_when_finished "git remote remove remote_in_config_2" &&
 560        git remote add remote_in_config_2 git://remote_2 &&
 561        (
 562                __git_remotes >actual
 563        ) &&
 564        test_cmp expect actual
 565'
 566
 567test_expect_success '__git_is_configured_remote' '
 568        test_when_finished "git remote remove remote_1" &&
 569        git remote add remote_1 git://remote_1 &&
 570        test_when_finished "git remote remove remote_2" &&
 571        git remote add remote_2 git://remote_2 &&
 572        (
 573                verbose __git_is_configured_remote remote_2 &&
 574                test_must_fail __git_is_configured_remote non-existent
 575        )
 576'
 577
 578test_expect_success 'setup for ref completion' '
 579        git commit --allow-empty -m initial &&
 580        git branch matching-branch &&
 581        git tag matching-tag &&
 582        (
 583                cd otherrepo &&
 584                git commit --allow-empty -m initial &&
 585                git branch -m master master-in-other &&
 586                git branch branch-in-other &&
 587                git tag tag-in-other
 588        ) &&
 589        git remote add other "$ROOT/otherrepo/.git" &&
 590        git fetch --no-tags other &&
 591        rm -f .git/FETCH_HEAD &&
 592        git init thirdrepo
 593'
 594
 595test_expect_success '__git_refs - simple' '
 596        cat >expected <<-EOF &&
 597        HEAD
 598        master
 599        matching-branch
 600        other/branch-in-other
 601        other/master-in-other
 602        matching-tag
 603        EOF
 604        (
 605                cur= &&
 606                __git_refs >"$actual"
 607        ) &&
 608        test_cmp expected "$actual"
 609'
 610
 611test_expect_success '__git_refs - full refs' '
 612        cat >expected <<-EOF &&
 613        refs/heads/master
 614        refs/heads/matching-branch
 615        refs/remotes/other/branch-in-other
 616        refs/remotes/other/master-in-other
 617        refs/tags/matching-tag
 618        EOF
 619        (
 620                cur=refs/heads/ &&
 621                __git_refs >"$actual"
 622        ) &&
 623        test_cmp expected "$actual"
 624'
 625
 626test_expect_success '__git_refs - repo given on the command line' '
 627        cat >expected <<-EOF &&
 628        HEAD
 629        branch-in-other
 630        master-in-other
 631        tag-in-other
 632        EOF
 633        (
 634                __git_dir="$ROOT/otherrepo/.git" &&
 635                cur= &&
 636                __git_refs >"$actual"
 637        ) &&
 638        test_cmp expected "$actual"
 639'
 640
 641test_expect_success '__git_refs - remote on local file system' '
 642        cat >expected <<-EOF &&
 643        HEAD
 644        branch-in-other
 645        master-in-other
 646        tag-in-other
 647        EOF
 648        (
 649                cur= &&
 650                __git_refs otherrepo >"$actual"
 651        ) &&
 652        test_cmp expected "$actual"
 653'
 654
 655test_expect_success '__git_refs - remote on local file system - full refs' '
 656        cat >expected <<-EOF &&
 657        refs/heads/branch-in-other
 658        refs/heads/master-in-other
 659        refs/tags/tag-in-other
 660        EOF
 661        (
 662                cur=refs/ &&
 663                __git_refs otherrepo >"$actual"
 664        ) &&
 665        test_cmp expected "$actual"
 666'
 667
 668test_expect_success '__git_refs - configured remote' '
 669        cat >expected <<-EOF &&
 670        HEAD
 671        branch-in-other
 672        master-in-other
 673        EOF
 674        (
 675                cur= &&
 676                __git_refs other >"$actual"
 677        ) &&
 678        test_cmp expected "$actual"
 679'
 680
 681test_expect_success '__git_refs - configured remote - full refs' '
 682        cat >expected <<-EOF &&
 683        HEAD
 684        refs/heads/branch-in-other
 685        refs/heads/master-in-other
 686        refs/tags/tag-in-other
 687        EOF
 688        (
 689                cur=refs/ &&
 690                __git_refs other >"$actual"
 691        ) &&
 692        test_cmp expected "$actual"
 693'
 694
 695test_expect_success '__git_refs - configured remote - repo given on the command line' '
 696        cat >expected <<-EOF &&
 697        HEAD
 698        branch-in-other
 699        master-in-other
 700        EOF
 701        (
 702                cd thirdrepo &&
 703                __git_dir="$ROOT/.git" &&
 704                cur= &&
 705                __git_refs other >"$actual"
 706        ) &&
 707        test_cmp expected "$actual"
 708'
 709
 710test_expect_success '__git_refs - configured remote - full refs - repo given on the command line' '
 711        cat >expected <<-EOF &&
 712        HEAD
 713        refs/heads/branch-in-other
 714        refs/heads/master-in-other
 715        refs/tags/tag-in-other
 716        EOF
 717        (
 718                cd thirdrepo &&
 719                __git_dir="$ROOT/.git" &&
 720                cur=refs/ &&
 721                __git_refs other >"$actual"
 722        ) &&
 723        test_cmp expected "$actual"
 724'
 725
 726test_expect_success '__git_refs - configured remote - remote name matches a directory' '
 727        cat >expected <<-EOF &&
 728        HEAD
 729        branch-in-other
 730        master-in-other
 731        EOF
 732        mkdir other &&
 733        test_when_finished "rm -rf other" &&
 734        (
 735                cur= &&
 736                __git_refs other >"$actual"
 737        ) &&
 738        test_cmp expected "$actual"
 739'
 740
 741test_expect_success '__git_refs - URL remote' '
 742        cat >expected <<-EOF &&
 743        HEAD
 744        branch-in-other
 745        master-in-other
 746        tag-in-other
 747        EOF
 748        (
 749                cur= &&
 750                __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
 751        ) &&
 752        test_cmp expected "$actual"
 753'
 754
 755test_expect_success '__git_refs - URL remote - full refs' '
 756        cat >expected <<-EOF &&
 757        HEAD
 758        refs/heads/branch-in-other
 759        refs/heads/master-in-other
 760        refs/tags/tag-in-other
 761        EOF
 762        (
 763                cur=refs/ &&
 764                __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
 765        ) &&
 766        test_cmp expected "$actual"
 767'
 768
 769test_expect_success '__git_refs - non-existing remote' '
 770        (
 771                cur= &&
 772                __git_refs non-existing >"$actual"
 773        ) &&
 774        test_must_be_empty "$actual"
 775'
 776
 777test_expect_success '__git_refs - non-existing remote - full refs' '
 778        (
 779                cur=refs/ &&
 780                __git_refs non-existing >"$actual"
 781        ) &&
 782        test_must_be_empty "$actual"
 783'
 784
 785test_expect_success '__git_refs - non-existing URL remote' '
 786        (
 787                cur= &&
 788                __git_refs "file://$ROOT/non-existing" >"$actual"
 789        ) &&
 790        test_must_be_empty "$actual"
 791'
 792
 793test_expect_success '__git_refs - non-existing URL remote - full refs' '
 794        (
 795                cur=refs/ &&
 796                __git_refs "file://$ROOT/non-existing" >"$actual"
 797        ) &&
 798        test_must_be_empty "$actual"
 799'
 800
 801test_expect_success '__git_refs - not in a git repository' '
 802        (
 803                GIT_CEILING_DIRECTORIES="$ROOT" &&
 804                export GIT_CEILING_DIRECTORIES &&
 805                cd subdir &&
 806                cur= &&
 807                __git_refs >"$actual"
 808        ) &&
 809        test_must_be_empty "$actual"
 810'
 811
 812test_expect_success '__git_refs - unique remote branches for git checkout DWIMery' '
 813        cat >expected <<-EOF &&
 814        HEAD
 815        master
 816        matching-branch
 817        other/ambiguous
 818        other/branch-in-other
 819        other/master-in-other
 820        remote/ambiguous
 821        remote/branch-in-remote
 822        matching-tag
 823        branch-in-other
 824        branch-in-remote
 825        master-in-other
 826        EOF
 827        for remote_ref in refs/remotes/other/ambiguous \
 828                refs/remotes/remote/ambiguous \
 829                refs/remotes/remote/branch-in-remote
 830        do
 831                git update-ref $remote_ref master &&
 832                test_when_finished "git update-ref -d $remote_ref"
 833        done &&
 834        (
 835                cur= &&
 836                __git_refs "" 1 >"$actual"
 837        ) &&
 838        test_cmp expected "$actual"
 839'
 840
 841test_expect_success '__git_refs - after --opt=' '
 842        cat >expected <<-EOF &&
 843        HEAD
 844        master
 845        matching-branch
 846        other/branch-in-other
 847        other/master-in-other
 848        matching-tag
 849        EOF
 850        (
 851                cur="--opt=" &&
 852                __git_refs "" "" "" "" >"$actual"
 853        ) &&
 854        test_cmp expected "$actual"
 855'
 856
 857test_expect_success '__git_refs - after --opt= - full refs' '
 858        cat >expected <<-EOF &&
 859        refs/heads/master
 860        refs/heads/matching-branch
 861        refs/remotes/other/branch-in-other
 862        refs/remotes/other/master-in-other
 863        refs/tags/matching-tag
 864        EOF
 865        (
 866                cur="--opt=refs/" &&
 867                __git_refs "" "" "" refs/ >"$actual"
 868        ) &&
 869        test_cmp expected "$actual"
 870'
 871
 872test_expect_success '__git refs - exluding refs' '
 873        cat >expected <<-EOF &&
 874        ^HEAD
 875        ^master
 876        ^matching-branch
 877        ^other/branch-in-other
 878        ^other/master-in-other
 879        ^matching-tag
 880        EOF
 881        (
 882                cur=^ &&
 883                __git_refs >"$actual"
 884        ) &&
 885        test_cmp expected "$actual"
 886'
 887
 888test_expect_success '__git refs - exluding full refs' '
 889        cat >expected <<-EOF &&
 890        ^refs/heads/master
 891        ^refs/heads/matching-branch
 892        ^refs/remotes/other/branch-in-other
 893        ^refs/remotes/other/master-in-other
 894        ^refs/tags/matching-tag
 895        EOF
 896        (
 897                cur=^refs/ &&
 898                __git_refs >"$actual"
 899        ) &&
 900        test_cmp expected "$actual"
 901'
 902
 903test_expect_success 'setup for filtering matching refs' '
 904        git branch matching/branch &&
 905        git tag matching/tag &&
 906        git -C otherrepo branch matching/branch-in-other &&
 907        git fetch --no-tags other &&
 908        rm -f .git/FETCH_HEAD
 909'
 910
 911test_expect_success '__git_refs - dont filter refs unless told so' '
 912        cat >expected <<-EOF &&
 913        HEAD
 914        master
 915        matching-branch
 916        matching/branch
 917        other/branch-in-other
 918        other/master-in-other
 919        other/matching/branch-in-other
 920        matching-tag
 921        matching/tag
 922        EOF
 923        (
 924                cur=master &&
 925                __git_refs >"$actual"
 926        ) &&
 927        test_cmp expected "$actual"
 928'
 929
 930test_expect_success '__git_refs - only matching refs' '
 931        cat >expected <<-EOF &&
 932        matching-branch
 933        matching/branch
 934        matching-tag
 935        matching/tag
 936        EOF
 937        (
 938                cur=mat &&
 939                __git_refs "" "" "" "$cur" >"$actual"
 940        ) &&
 941        test_cmp expected "$actual"
 942'
 943
 944test_expect_success '__git_refs - only matching refs - full refs' '
 945        cat >expected <<-EOF &&
 946        refs/heads/matching-branch
 947        refs/heads/matching/branch
 948        EOF
 949        (
 950                cur=refs/heads/mat &&
 951                __git_refs "" "" "" "$cur" >"$actual"
 952        ) &&
 953        test_cmp expected "$actual"
 954'
 955
 956test_expect_success '__git_refs - only matching refs - remote on local file system' '
 957        cat >expected <<-EOF &&
 958        master-in-other
 959        matching/branch-in-other
 960        EOF
 961        (
 962                cur=ma &&
 963                __git_refs otherrepo "" "" "$cur" >"$actual"
 964        ) &&
 965        test_cmp expected "$actual"
 966'
 967
 968test_expect_success '__git_refs - only matching refs - configured remote' '
 969        cat >expected <<-EOF &&
 970        master-in-other
 971        matching/branch-in-other
 972        EOF
 973        (
 974                cur=ma &&
 975                __git_refs other "" "" "$cur" >"$actual"
 976        ) &&
 977        test_cmp expected "$actual"
 978'
 979
 980test_expect_success '__git_refs - only matching refs - remote - full refs' '
 981        cat >expected <<-EOF &&
 982        refs/heads/master-in-other
 983        refs/heads/matching/branch-in-other
 984        EOF
 985        (
 986                cur=refs/heads/ma &&
 987                __git_refs other "" "" "$cur" >"$actual"
 988        ) &&
 989        test_cmp expected "$actual"
 990'
 991
 992test_expect_success '__git_refs - only matching refs - checkout DWIMery' '
 993        cat >expected <<-EOF &&
 994        matching-branch
 995        matching/branch
 996        matching-tag
 997        matching/tag
 998        matching/branch-in-other
 999        EOF
1000        for remote_ref in refs/remotes/other/ambiguous \
1001                refs/remotes/remote/ambiguous \
1002                refs/remotes/remote/branch-in-remote
1003        do
1004                git update-ref $remote_ref master &&
1005                test_when_finished "git update-ref -d $remote_ref"
1006        done &&
1007        (
1008                cur=mat &&
1009                __git_refs "" 1 "" "$cur" >"$actual"
1010        ) &&
1011        test_cmp expected "$actual"
1012'
1013
1014test_expect_success 'teardown after filtering matching refs' '
1015        git branch -d matching/branch &&
1016        git tag -d matching/tag &&
1017        git update-ref -d refs/remotes/other/matching/branch-in-other &&
1018        git -C otherrepo branch -D matching/branch-in-other
1019'
1020
1021test_expect_success '__git_refs - for-each-ref format specifiers in prefix' '
1022        cat >expected <<-EOF &&
1023        evil-%%-%42-%(refname)..master
1024        EOF
1025        (
1026                cur="evil-%%-%42-%(refname)..mas" &&
1027                __git_refs "" "" "evil-%%-%42-%(refname).." mas >"$actual"
1028        ) &&
1029        test_cmp expected "$actual"
1030'
1031
1032test_expect_success '__git_complete_refs - simple' '
1033        sed -e "s/Z$//" >expected <<-EOF &&
1034        HEAD Z
1035        master Z
1036        matching-branch Z
1037        other/branch-in-other Z
1038        other/master-in-other Z
1039        matching-tag Z
1040        EOF
1041        (
1042                cur= &&
1043                __git_complete_refs &&
1044                print_comp
1045        ) &&
1046        test_cmp expected out
1047'
1048
1049test_expect_success '__git_complete_refs - matching' '
1050        sed -e "s/Z$//" >expected <<-EOF &&
1051        matching-branch Z
1052        matching-tag Z
1053        EOF
1054        (
1055                cur=mat &&
1056                __git_complete_refs &&
1057                print_comp
1058        ) &&
1059        test_cmp expected out
1060'
1061
1062test_expect_success '__git_complete_refs - remote' '
1063        sed -e "s/Z$//" >expected <<-EOF &&
1064        HEAD Z
1065        branch-in-other Z
1066        master-in-other Z
1067        EOF
1068        (
1069                cur=
1070                __git_complete_refs --remote=other &&
1071                print_comp
1072        ) &&
1073        test_cmp expected out
1074'
1075
1076test_expect_success '__git_complete_refs - track' '
1077        sed -e "s/Z$//" >expected <<-EOF &&
1078        HEAD Z
1079        master Z
1080        matching-branch Z
1081        other/branch-in-other Z
1082        other/master-in-other Z
1083        matching-tag Z
1084        branch-in-other Z
1085        master-in-other Z
1086        EOF
1087        (
1088                cur=
1089                __git_complete_refs --track &&
1090                print_comp
1091        ) &&
1092        test_cmp expected out
1093'
1094
1095test_expect_success '__git_complete_refs - current word' '
1096        sed -e "s/Z$//" >expected <<-EOF &&
1097        matching-branch Z
1098        matching-tag Z
1099        EOF
1100        (
1101                cur="--option=mat" &&
1102                __git_complete_refs --cur="${cur#*=}" &&
1103                print_comp
1104        ) &&
1105        test_cmp expected out
1106'
1107
1108test_expect_success '__git_complete_refs - prefix' '
1109        sed -e "s/Z$//" >expected <<-EOF &&
1110        v1.0..matching-branch Z
1111        v1.0..matching-tag Z
1112        EOF
1113        (
1114                cur=v1.0..mat &&
1115                __git_complete_refs --pfx=v1.0.. --cur=mat &&
1116                print_comp
1117        ) &&
1118        test_cmp expected out
1119'
1120
1121test_expect_success '__git_complete_refs - suffix' '
1122        cat >expected <<-EOF &&
1123        HEAD.
1124        master.
1125        matching-branch.
1126        other/branch-in-other.
1127        other/master-in-other.
1128        matching-tag.
1129        EOF
1130        (
1131                cur= &&
1132                __git_complete_refs --sfx=. &&
1133                print_comp
1134        ) &&
1135        test_cmp expected out
1136'
1137
1138test_expect_success '__git_complete_fetch_refspecs - simple' '
1139        sed -e "s/Z$//" >expected <<-EOF &&
1140        HEAD:HEAD Z
1141        branch-in-other:branch-in-other Z
1142        master-in-other:master-in-other Z
1143        EOF
1144        (
1145                cur= &&
1146                __git_complete_fetch_refspecs other &&
1147                print_comp
1148        ) &&
1149        test_cmp expected out
1150'
1151
1152test_expect_success '__git_complete_fetch_refspecs - matching' '
1153        sed -e "s/Z$//" >expected <<-EOF &&
1154        branch-in-other:branch-in-other Z
1155        EOF
1156        (
1157                cur=br &&
1158                __git_complete_fetch_refspecs other "" br &&
1159                print_comp
1160        ) &&
1161        test_cmp expected out
1162'
1163
1164test_expect_success '__git_complete_fetch_refspecs - prefix' '
1165        sed -e "s/Z$//" >expected <<-EOF &&
1166        +HEAD:HEAD Z
1167        +branch-in-other:branch-in-other Z
1168        +master-in-other:master-in-other Z
1169        EOF
1170        (
1171                cur="+" &&
1172                __git_complete_fetch_refspecs other "+" ""  &&
1173                print_comp
1174        ) &&
1175        test_cmp expected out
1176'
1177
1178test_expect_success '__git_complete_fetch_refspecs - fully qualified' '
1179        sed -e "s/Z$//" >expected <<-EOF &&
1180        refs/heads/branch-in-other:refs/heads/branch-in-other Z
1181        refs/heads/master-in-other:refs/heads/master-in-other Z
1182        refs/tags/tag-in-other:refs/tags/tag-in-other Z
1183        EOF
1184        (
1185                cur=refs/ &&
1186                __git_complete_fetch_refspecs other "" refs/ &&
1187                print_comp
1188        ) &&
1189        test_cmp expected out
1190'
1191
1192test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '
1193        sed -e "s/Z$//" >expected <<-EOF &&
1194        +refs/heads/branch-in-other:refs/heads/branch-in-other Z
1195        +refs/heads/master-in-other:refs/heads/master-in-other Z
1196        +refs/tags/tag-in-other:refs/tags/tag-in-other Z
1197        EOF
1198        (
1199                cur=+refs/ &&
1200                __git_complete_fetch_refspecs other + refs/ &&
1201                print_comp
1202        ) &&
1203        test_cmp expected out
1204'
1205
1206test_expect_success 'teardown after ref completion' '
1207        git branch -d matching-branch &&
1208        git tag -d matching-tag &&
1209        git remote remove other
1210'
1211
1212
1213test_path_completion ()
1214{
1215        test $# = 2 || error "bug in the test script: not 2 parameters to test_path_completion"
1216
1217        local cur="$1" expected="$2"
1218        echo "$expected" >expected &&
1219        (
1220                # In the following tests calling this function we only
1221                # care about how __git_complete_index_file() deals with
1222                # unusual characters in path names.  By requesting only
1223                # untracked files we dont have to bother adding any
1224                # paths to the index in those tests.
1225                __git_complete_index_file --others &&
1226                print_comp
1227        ) &&
1228        test_cmp expected out
1229}
1230
1231test_expect_success 'setup for path completion tests' '
1232        mkdir simple-dir \
1233              "spaces in dir" \
1234              árvíztűrő &&
1235        touch simple-dir/simple-file \
1236              "spaces in dir/spaces in file" \
1237              "árvíztűrő/Сайн яваарай" &&
1238        if test_have_prereq !MINGW &&
1239           mkdir BS\\dir \
1240                 '$'separators\034in\035dir'' &&
1241           touch BS\\dir/DQ\"file \
1242                 '$'separators\034in\035dir/sep\036in\037file''
1243        then
1244                test_set_prereq FUNNYNAMES
1245        else
1246                rm -rf BS\\dir '$'separators\034in\035dir''
1247        fi
1248'
1249
1250test_expect_success '__git_complete_index_file - simple' '
1251        test_path_completion simple simple-dir &&  # Bash is supposed to
1252                                                   # add the trailing /.
1253        test_path_completion simple-dir/simple simple-dir/simple-file
1254'
1255
1256test_expect_success \
1257    '__git_complete_index_file - escaped characters on cmdline' '
1258        test_path_completion spac "spaces in dir" &&  # Bash will turn this
1259                                                      # into "spaces\ in\ dir"
1260        test_path_completion "spaces\\ i" \
1261                             "spaces in dir" &&
1262        test_path_completion "spaces\\ in\\ dir/s" \
1263                             "spaces in dir/spaces in file" &&
1264        test_path_completion "spaces\\ in\\ dir/spaces\\ i" \
1265                             "spaces in dir/spaces in file"
1266'
1267
1268test_expect_success \
1269    '__git_complete_index_file - quoted characters on cmdline' '
1270        # Testing with an opening but without a corresponding closing
1271        # double quote is important.
1272        test_path_completion \"spac "spaces in dir" &&
1273        test_path_completion "\"spaces i" \
1274                             "spaces in dir" &&
1275        test_path_completion "\"spaces in dir/s" \
1276                             "spaces in dir/spaces in file" &&
1277        test_path_completion "\"spaces in dir/spaces i" \
1278                             "spaces in dir/spaces in file"
1279'
1280
1281test_expect_success '__git_complete_index_file - UTF-8 in ls-files output' '
1282        test_path_completion á árvíztűrő &&
1283        test_path_completion árvíztűrő/С "árvíztűrő/Сайн яваарай"
1284'
1285
1286test_expect_success FUNNYNAMES \
1287    '__git_complete_index_file - C-style escapes in ls-files output' '
1288        test_path_completion BS \
1289                             BS\\dir &&
1290        test_path_completion BS\\\\d \
1291                             BS\\dir &&
1292        test_path_completion BS\\\\dir/DQ \
1293                             BS\\dir/DQ\"file &&
1294        test_path_completion BS\\\\dir/DQ\\\"f \
1295                             BS\\dir/DQ\"file
1296'
1297
1298test_expect_success FUNNYNAMES \
1299    '__git_complete_index_file - \nnn-escaped characters in ls-files output' '
1300        test_path_completion sep '$'separators\034in\035dir'' &&
1301        test_path_completion '$'separators\034i'' \
1302                             '$'separators\034in\035dir'' &&
1303        test_path_completion '$'separators\034in\035dir/sep'' \
1304                             '$'separators\034in\035dir/sep\036in\037file'' &&
1305        test_path_completion '$'separators\034in\035dir/sep\036i'' \
1306                             '$'separators\034in\035dir/sep\036in\037file''
1307'
1308
1309test_expect_success FUNNYNAMES \
1310    '__git_complete_index_file - removing repeated quoted path components' '
1311        test_when_finished rm -r repeated-quoted &&
1312        mkdir repeated-quoted &&      # A directory whose name in itself
1313                                      # would not be quoted ...
1314        >repeated-quoted/0-file &&
1315        >repeated-quoted/1\"file &&   # ... but here the file makes the
1316                                      # dirname quoted ...
1317        >repeated-quoted/2-file &&
1318        >repeated-quoted/3\"file &&   # ... and here, too.
1319
1320        # Still, we shold only list the directory name only once.
1321        test_path_completion repeated repeated-quoted
1322'
1323
1324test_expect_success 'teardown after path completion tests' '
1325        rm -rf simple-dir "spaces in dir" árvíztűrő \
1326               BS\\dir '$'separators\034in\035dir''
1327'
1328
1329
1330test_expect_success '__git_get_config_variables' '
1331        cat >expect <<-EOF &&
1332        name-1
1333        name-2
1334        EOF
1335        test_config interesting.name-1 good &&
1336        test_config interesting.name-2 good &&
1337        test_config subsection.interesting.name-3 bad &&
1338        __git_get_config_variables interesting >actual &&
1339        test_cmp expect actual
1340'
1341
1342test_expect_success '__git_pretty_aliases' '
1343        cat >expect <<-EOF &&
1344        author
1345        hash
1346        EOF
1347        test_config pretty.author "%an %ae" &&
1348        test_config pretty.hash %H &&
1349        __git_pretty_aliases >actual &&
1350        test_cmp expect actual
1351'
1352
1353test_expect_success '__git_aliases' '
1354        cat >expect <<-EOF &&
1355        ci
1356        co
1357        EOF
1358        test_config alias.ci commit &&
1359        test_config alias.co checkout &&
1360        __git_aliases >actual &&
1361        test_cmp expect actual
1362'
1363
1364test_expect_success 'basic' '
1365        run_completion "git " &&
1366        # built-in
1367        grep -q "^add \$" out &&
1368        # script
1369        grep -q "^filter-branch \$" out &&
1370        # plumbing
1371        ! grep -q "^ls-files \$" out &&
1372
1373        run_completion "git f" &&
1374        ! grep -q -v "^f" out
1375'
1376
1377test_expect_success 'double dash "git" itself' '
1378        test_completion "git --" <<-\EOF
1379        --paginate Z
1380        --no-pager Z
1381        --git-dir=
1382        --bare Z
1383        --version Z
1384        --exec-path Z
1385        --exec-path=
1386        --html-path Z
1387        --man-path Z
1388        --info-path Z
1389        --work-tree=
1390        --namespace=
1391        --no-replace-objects Z
1392        --help Z
1393        EOF
1394'
1395
1396test_expect_success 'double dash "git checkout"' '
1397        test_completion "git checkout --" <<-\EOF
1398        --quiet Z
1399        --detach Z
1400        --track Z
1401        --orphan=Z
1402        --ours Z
1403        --theirs Z
1404        --merge Z
1405        --conflict=Z
1406        --patch Z
1407        --ignore-skip-worktree-bits Z
1408        --ignore-other-worktrees Z
1409        --recurse-submodules Z
1410        --progress Z
1411        --no-track Z
1412        --no-recurse-submodules Z
1413        EOF
1414'
1415
1416test_expect_success 'general options' '
1417        test_completion "git --ver" "--version " &&
1418        test_completion "git --hel" "--help " &&
1419        test_completion "git --exe" <<-\EOF &&
1420        --exec-path Z
1421        --exec-path=
1422        EOF
1423        test_completion "git --htm" "--html-path " &&
1424        test_completion "git --pag" "--paginate " &&
1425        test_completion "git --no-p" "--no-pager " &&
1426        test_completion "git --git" "--git-dir=" &&
1427        test_completion "git --wor" "--work-tree=" &&
1428        test_completion "git --nam" "--namespace=" &&
1429        test_completion "git --bar" "--bare " &&
1430        test_completion "git --inf" "--info-path " &&
1431        test_completion "git --no-r" "--no-replace-objects "
1432'
1433
1434test_expect_success 'general options plus command' '
1435        test_completion "git --version check" "checkout " &&
1436        test_completion "git --paginate check" "checkout " &&
1437        test_completion "git --git-dir=foo check" "checkout " &&
1438        test_completion "git --bare check" "checkout " &&
1439        test_completion "git --exec-path=foo check" "checkout " &&
1440        test_completion "git --html-path check" "checkout " &&
1441        test_completion "git --no-pager check" "checkout " &&
1442        test_completion "git --work-tree=foo check" "checkout " &&
1443        test_completion "git --namespace=foo check" "checkout " &&
1444        test_completion "git --paginate check" "checkout " &&
1445        test_completion "git --info-path check" "checkout " &&
1446        test_completion "git --no-replace-objects check" "checkout " &&
1447        test_completion "git --git-dir some/path check" "checkout " &&
1448        test_completion "git -c conf.var=value check" "checkout " &&
1449        test_completion "git -C some/path check" "checkout " &&
1450        test_completion "git --work-tree some/path check" "checkout " &&
1451        test_completion "git --namespace name/space check" "checkout "
1452'
1453
1454test_expect_success 'git --help completion' '
1455        test_completion "git --help ad" "add " &&
1456        test_completion "git --help core" "core-tutorial "
1457'
1458
1459test_expect_success 'setup for integration tests' '
1460        echo content >file1 &&
1461        echo more >file2 &&
1462        git add file1 file2 &&
1463        git commit -m one &&
1464        git branch mybranch &&
1465        git tag mytag
1466'
1467
1468test_expect_success 'checkout completes ref names' '
1469        test_completion "git checkout m" <<-\EOF
1470        master Z
1471        mybranch Z
1472        mytag Z
1473        EOF
1474'
1475
1476test_expect_success 'git -C <path> checkout uses the right repo' '
1477        test_completion "git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b" <<-\EOF
1478        branch-in-other Z
1479        EOF
1480'
1481
1482test_expect_success 'show completes all refs' '
1483        test_completion "git show m" <<-\EOF
1484        master Z
1485        mybranch Z
1486        mytag Z
1487        EOF
1488'
1489
1490test_expect_success '<ref>: completes paths' '
1491        test_completion "git show mytag:f" <<-\EOF
1492        file1 Z
1493        file2 Z
1494        EOF
1495'
1496
1497test_expect_success 'complete tree filename with spaces' '
1498        echo content >"name with spaces" &&
1499        git add "name with spaces" &&
1500        git commit -m spaces &&
1501        test_completion "git show HEAD:nam" <<-\EOF
1502        name with spaces Z
1503        EOF
1504'
1505
1506test_expect_success 'complete tree filename with metacharacters' '
1507        echo content >"name with \${meta}" &&
1508        git add "name with \${meta}" &&
1509        git commit -m meta &&
1510        test_completion "git show HEAD:nam" <<-\EOF
1511        name with ${meta} Z
1512        name with spaces Z
1513        EOF
1514'
1515
1516test_expect_success 'send-email' '
1517        test_completion "git send-email --cov" "--cover-letter " &&
1518        test_completion "git send-email ma" "master "
1519'
1520
1521test_expect_success 'complete files' '
1522        git init tmp && cd tmp &&
1523        test_when_finished "cd .. && rm -rf tmp" &&
1524
1525        echo "expected" > .gitignore &&
1526        echo "out" >> .gitignore &&
1527        echo "out_sorted" >> .gitignore &&
1528
1529        git add .gitignore &&
1530        test_completion "git commit " ".gitignore" &&
1531
1532        git commit -m ignore &&
1533
1534        touch new &&
1535        test_completion "git add " "new" &&
1536
1537        git add new &&
1538        git commit -a -m new &&
1539        test_completion "git add " "" &&
1540
1541        git mv new modified &&
1542        echo modify > modified &&
1543        test_completion "git add " "modified" &&
1544
1545        touch untracked &&
1546
1547        : TODO .gitignore should not be here &&
1548        test_completion "git rm " <<-\EOF &&
1549        .gitignore
1550        modified
1551        EOF
1552
1553        test_completion "git clean " "untracked" &&
1554
1555        : TODO .gitignore should not be here &&
1556        test_completion "git mv " <<-\EOF &&
1557        .gitignore
1558        modified
1559        EOF
1560
1561        mkdir dir &&
1562        touch dir/file-in-dir &&
1563        git add dir/file-in-dir &&
1564        git commit -m dir &&
1565
1566        mkdir untracked-dir &&
1567
1568        : TODO .gitignore should not be here &&
1569        test_completion "git mv modified " <<-\EOF &&
1570        .gitignore
1571        dir
1572        modified
1573        untracked
1574        untracked-dir
1575        EOF
1576
1577        test_completion "git commit " "modified" &&
1578
1579        : TODO .gitignore should not be here &&
1580        test_completion "git ls-files " <<-\EOF &&
1581        .gitignore
1582        dir
1583        modified
1584        EOF
1585
1586        touch momified &&
1587        test_completion "git add mom" "momified"
1588'
1589
1590test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
1591        test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
1592        test_completion "git co m" <<-\EOF
1593        master Z
1594        mybranch Z
1595        mytag Z
1596        EOF
1597'
1598
1599test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
1600        test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
1601        test_completion "git co m" <<-\EOF
1602        master Z
1603        mybranch Z
1604        mytag Z
1605        EOF
1606'
1607
1608test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
1609        test_config alias.co "!f() { : git checkout ; if ... } f" &&
1610        test_completion "git co m" <<-\EOF
1611        master Z
1612        mybranch Z
1613        mytag Z
1614        EOF
1615'
1616
1617test_expect_success 'completion without explicit _git_xxx function' '
1618        test_completion "git version --" <<-\EOF
1619        --build-options Z
1620        EOF
1621'
1622
1623test_expect_failure 'complete with tilde expansion' '
1624        git init tmp && cd tmp &&
1625        test_when_finished "cd .. && rm -rf tmp" &&
1626
1627        touch ~/tmp/file &&
1628
1629        test_completion "git add ~/tmp/" "~/tmp/file"
1630'
1631
1632test_expect_success 'setup other remote for remote reference completion' '
1633        git remote add other otherrepo &&
1634        git fetch other
1635'
1636
1637for flag in -d --delete
1638do
1639        test_expect_success "__git_complete_remote_or_refspec - push $flag other" '
1640                sed -e "s/Z$//" >expected <<-EOF &&
1641                master-in-other Z
1642                EOF
1643                (
1644                        words=(git push '$flag' other ma) &&
1645                        cword=${#words[@]} cur=${words[cword-1]} &&
1646                        __git_complete_remote_or_refspec &&
1647                        print_comp
1648                ) &&
1649                test_cmp expected out
1650        '
1651
1652        test_expect_failure "__git_complete_remote_or_refspec - push other $flag" '
1653                sed -e "s/Z$//" >expected <<-EOF &&
1654                master-in-other Z
1655                EOF
1656                (
1657                        words=(git push other '$flag' ma) &&
1658                        cword=${#words[@]} cur=${words[cword-1]} &&
1659                        __git_complete_remote_or_refspec &&
1660                        print_comp
1661                ) &&
1662                test_cmp expected out
1663        '
1664done
1665
1666test_expect_success 'sourcing the completion script clears cached commands' '
1667        __git_compute_all_commands &&
1668        verbose test -n "$__git_all_commands" &&
1669        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1670        verbose test -z "$__git_all_commands"
1671'
1672
1673test_expect_success 'sourcing the completion script clears cached porcelain commands' '
1674        __git_compute_porcelain_commands &&
1675        verbose test -n "$__git_porcelain_commands" &&
1676        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1677        verbose test -z "$__git_porcelain_commands"
1678'
1679
1680test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
1681        __git_compute_merge_strategies &&
1682        verbose test -n "$__git_merge_strategies" &&
1683        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1684        verbose test -z "$__git_merge_strategies"
1685'
1686
1687test_expect_success 'sourcing the completion script clears cached --options' '
1688        __gitcomp_builtin checkout &&
1689        verbose test -n "$__gitcomp_builtin_checkout" &&
1690        __gitcomp_builtin notes_edit &&
1691        verbose test -n "$__gitcomp_builtin_notes_edit" &&
1692        . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1693        verbose test -z "$__gitcomp_builtin_checkout" &&
1694        verbose test -z "$__gitcomp_builtin_notes_edit"
1695'
1696
1697test_done