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