Merge branch 'ab/get-short-oid'
[git] / t / t9902-completion.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2012 Felipe Contreras
4 #
5
6 test_description='test bash completion'
7
8 . ./lib-bash.sh
9
10 complete ()
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
33 GIT_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
61 print_comp ()
62 {
63         local IFS=$'\n'
64         echo "${COMPREPLY[*]}" > out
65 }
66
67 run_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
81 test_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().
98 test_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
113 test_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
124 invalid_variable_name='${foo.bar}'
125
126 actual="$TRASH_DIRECTORY/actual"
127
128 if test_have_prereq MINGW
129 then
130         ROOT="$(pwd -W)"
131 else
132         ROOT="$(pwd)"
133 fi
134
135 test_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
141 test_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
151 test_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
160 test_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
170 test_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
180 test_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
190 test_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
201 test_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
213 test_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
224 test_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
236 test_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
248 test_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
261 test_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
271 test_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
282 test_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
293 test_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
302 test_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
311 test_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
321 test_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
333 test_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
345 test_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
359 test_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
370 test_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
380 test_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
388 test_expect_success '__gitdir - repo as argument' '
389         echo "otherrepo/.git" >expected &&
390         (
391                 __gitdir "otherrepo" >"$actual"
392         ) &&
393         test_cmp expected "$actual"
394 '
395
396 test_expect_success '__gitdir - remote as argument' '
397         echo "remote" >expected &&
398         (
399                 __gitdir "remote" >"$actual"
400         ) &&
401         test_cmp expected "$actual"
402 '
403
404
405 test_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
412 test_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
419 test_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
426 test_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
432 test_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
438 test_expect_success '__git_dequote - open double quote' '
439         __git_dequote "\"open double quote" &&
440         verbose test "open double quote" = "$dequoted_word"
441 '
442
443
444 test_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
460 test_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
469 test_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
479 test_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
487 test_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
495 test_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
503 test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
504         __gitcomp "$invalid_variable_name"
505 '
506
507 read -r -d "" refs <<-\EOF
508 maint
509 master
510 next
511 pu
512 EOF
513
514 test_expect_success '__gitcomp_nl - trailing space' '
515         test_gitcomp_nl "m" "$refs" <<-EOF
516         maint Z
517         master Z
518         EOF
519 '
520
521 test_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
528 test_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
535 test_expect_success '__gitcomp_nl - no suffix' '
536         test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
537         maintZ
538         masterZ
539         EOF
540 '
541
542 test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
543         __gitcomp_nl "$invalid_variable_name"
544 '
545
546 test_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
567 test_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
578 test_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
595 test_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
611 test_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
626 test_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
641 test_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
655 test_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
668 test_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
681 test_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
695 test_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
710 test_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
726 test_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
741 test_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
755 test_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
769 test_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
777 test_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
785 test_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
793 test_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
801 test_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
812 test_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
841 test_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
857 test_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
872 test_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
888 test_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
903 test_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
911 test_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
930 test_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
944 test_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
956 test_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
968 test_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
980 test_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
992 test_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
1014 test_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
1021 test_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
1032 test_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
1049 test_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
1062 test_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
1076 test_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
1095 test_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
1108 test_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
1121 test_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
1138 test_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
1152 test_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
1164 test_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
1178 test_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
1192 test_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
1206 test_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
1213 test_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
1231 test_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
1250 test_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
1256 test_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
1268 test_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
1281 test_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
1286 test_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
1298 test_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
1309 test_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
1324 test_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
1330 test_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
1342 test_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
1353 test_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
1364 test_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
1377 test_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
1396 test_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
1416 test_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
1434 test_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
1454 test_expect_success 'git --help completion' '
1455         test_completion "git --help ad" "add " &&
1456         test_completion "git --help core" "core-tutorial "
1457 '
1458
1459 test_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
1468 test_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
1476 test_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
1482 test_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
1490 test_expect_success '<ref>: completes paths' '
1491         test_completion "git show mytag:f" <<-\EOF
1492         file1 Z
1493         file2 Z
1494         EOF
1495 '
1496
1497 test_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
1506 test_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
1516 test_expect_success 'send-email' '
1517         test_completion "git send-email --cov" "--cover-letter " &&
1518         test_completion "git send-email ma" "master "
1519 '
1520
1521 test_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
1590 test_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
1599 test_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
1608 test_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
1617 test_expect_success 'completion without explicit _git_xxx function' '
1618         test_completion "git version --" <<-\EOF
1619         --build-options Z
1620         EOF
1621 '
1622
1623 test_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
1632 test_expect_success 'setup other remote for remote reference completion' '
1633         git remote add other otherrepo &&
1634         git fetch other
1635 '
1636
1637 for flag in -d --delete
1638 do
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         '
1664 done
1665
1666 test_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
1673 test_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
1680 test_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
1687 test_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
1697 test_done