Merge branch 'ab/config-based-hooks-base' into seen
[git] / t / t9902-completion.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2012-2020 Felipe Contreras
4 #
5
6 test_description='test bash completion'
7
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 . ./lib-bash.sh
12
13 complete ()
14 {
15         # do nothing
16         return 0
17 }
18
19 # Be careful when updating these lists:
20 #
21 # (1) The build tree may have build artifact from different branch, or
22 #     the user's $PATH may have a random executable that may begin
23 #     with "git-check" that are not part of the subcommands this build
24 #     will ship, e.g.  "check-ignore".  The tests for completion for
25 #     subcommand names tests how "check" is expanded; we limit the
26 #     possible candidates to "checkout" and "check-attr" to make sure
27 #     "check-attr", which is known by the filter function as a
28 #     subcommand to be thrown out, while excluding other random files
29 #     that happen to begin with "check" to avoid letting them get in
30 #     the way.
31 #
32 # (2) A test makes sure that common subcommands are included in the
33 #     completion for "git <TAB>", and a plumbing is excluded.  "add",
34 #     "rebase" and "ls-files" are listed for this.
35
36 GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr rebase ls-files'
37 GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout rebase'
38
39 . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
40
41 # We don't need this function to actually join words or do anything special.
42 # Also, it's cleaner to avoid touching bash's internal completion variables.
43 # So let's override it with a minimal version for testing purposes.
44 _get_comp_words_by_ref ()
45 {
46         while [ $# -gt 0 ]; do
47                 case "$1" in
48                 cur)
49                         cur=${_words[_cword]}
50                         ;;
51                 prev)
52                         prev=${_words[_cword-1]}
53                         ;;
54                 words)
55                         words=("${_words[@]}")
56                         ;;
57                 cword)
58                         cword=$_cword
59                         ;;
60                 esac
61                 shift
62         done
63 }
64
65 print_comp ()
66 {
67         local IFS=$'\n'
68         echo "${COMPREPLY[*]}" > out
69 }
70
71 run_completion ()
72 {
73         local -a COMPREPLY _words
74         local _cword
75         _words=( $1 )
76         test "${1: -1}" = ' ' && _words[${#_words[@]}+1]=''
77         (( _cword = ${#_words[@]} - 1 ))
78         __git_wrap__git_main && print_comp
79 }
80
81 # Test high-level completion
82 # Arguments are:
83 # 1: typed text so far (cur)
84 # 2: expected completion
85 test_completion ()
86 {
87         if test $# -gt 1
88         then
89                 printf '%s\n' "$2" >expected
90         else
91                 sed -e 's/Z$//' |sort >expected
92         fi &&
93         run_completion "$1" &&
94         sort out >out_sorted &&
95         test_cmp expected out_sorted
96 }
97
98 # Test __gitcomp.
99 # The first argument is the typed text so far (cur); the rest are
100 # passed to __gitcomp.  Expected output comes is read from the
101 # standard input, like test_completion().
102 test_gitcomp ()
103 {
104         local -a COMPREPLY &&
105         sed -e 's/Z$//' >expected &&
106         local cur="$1" &&
107         shift &&
108         __gitcomp "$@" &&
109         print_comp &&
110         test_cmp expected out
111 }
112
113 # Test __gitcomp_nl
114 # Arguments are:
115 # 1: current word (cur)
116 # -: the rest are passed to __gitcomp_nl
117 test_gitcomp_nl ()
118 {
119         local -a COMPREPLY &&
120         sed -e 's/Z$//' >expected &&
121         local cur="$1" &&
122         shift &&
123         __gitcomp_nl "$@" &&
124         print_comp &&
125         test_cmp expected out
126 }
127
128 invalid_variable_name='${foo.bar}'
129
130 actual="$TRASH_DIRECTORY/actual"
131
132 if test_have_prereq MINGW
133 then
134         ROOT="$(pwd -W)"
135 else
136         ROOT="$(pwd)"
137 fi
138
139 test_expect_success 'setup for __git_find_repo_path/__gitdir tests' '
140         mkdir -p subdir/subsubdir &&
141         mkdir -p non-repo &&
142         git init -b main otherrepo
143 '
144
145 test_expect_success '__git_find_repo_path - from command line (through $__git_dir)' '
146         echo "$ROOT/otherrepo/.git" >expected &&
147         (
148                 __git_dir="$ROOT/otherrepo/.git" &&
149                 __git_find_repo_path &&
150                 echo "$__git_repo_path" >"$actual"
151         ) &&
152         test_cmp expected "$actual"
153 '
154
155 test_expect_success '__git_find_repo_path - .git directory in cwd' '
156         echo ".git" >expected &&
157         (
158                 __git_find_repo_path &&
159                 echo "$__git_repo_path" >"$actual"
160         ) &&
161         test_cmp expected "$actual"
162 '
163
164 test_expect_success '__git_find_repo_path - .git directory in parent' '
165         echo "$ROOT/.git" >expected &&
166         (
167                 cd subdir/subsubdir &&
168                 __git_find_repo_path &&
169                 echo "$__git_repo_path" >"$actual"
170         ) &&
171         test_cmp expected "$actual"
172 '
173
174 test_expect_success '__git_find_repo_path - cwd is a .git directory' '
175         echo "." >expected &&
176         (
177                 cd .git &&
178                 __git_find_repo_path &&
179                 echo "$__git_repo_path" >"$actual"
180         ) &&
181         test_cmp expected "$actual"
182 '
183
184 test_expect_success '__git_find_repo_path - parent is a .git directory' '
185         echo "$ROOT/.git" >expected &&
186         (
187                 cd .git/objects &&
188                 __git_find_repo_path &&
189                 echo "$__git_repo_path" >"$actual"
190         ) &&
191         test_cmp expected "$actual"
192 '
193
194 test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in cwd' '
195         echo "$ROOT/otherrepo/.git" >expected &&
196         (
197                 GIT_DIR="$ROOT/otherrepo/.git" &&
198                 export GIT_DIR &&
199                 __git_find_repo_path &&
200                 echo "$__git_repo_path" >"$actual"
201         ) &&
202         test_cmp expected "$actual"
203 '
204
205 test_expect_success '__git_find_repo_path - $GIT_DIR set while .git directory in parent' '
206         echo "$ROOT/otherrepo/.git" >expected &&
207         (
208                 GIT_DIR="$ROOT/otherrepo/.git" &&
209                 export GIT_DIR &&
210                 cd subdir &&
211                 __git_find_repo_path &&
212                 echo "$__git_repo_path" >"$actual"
213         ) &&
214         test_cmp expected "$actual"
215 '
216
217 test_expect_success '__git_find_repo_path - from command line while "git -C"' '
218         echo "$ROOT/.git" >expected &&
219         (
220                 __git_dir="$ROOT/.git" &&
221                 __git_C_args=(-C otherrepo) &&
222                 __git_find_repo_path &&
223                 echo "$__git_repo_path" >"$actual"
224         ) &&
225         test_cmp expected "$actual"
226 '
227
228 test_expect_success '__git_find_repo_path - relative dir from command line and "git -C"' '
229         echo "$ROOT/otherrepo/.git" >expected &&
230         (
231                 cd subdir &&
232                 __git_dir="otherrepo/.git" &&
233                 __git_C_args=(-C ..) &&
234                 __git_find_repo_path &&
235                 echo "$__git_repo_path" >"$actual"
236         ) &&
237         test_cmp expected "$actual"
238 '
239
240 test_expect_success '__git_find_repo_path - $GIT_DIR set while "git -C"' '
241         echo "$ROOT/.git" >expected &&
242         (
243                 GIT_DIR="$ROOT/.git" &&
244                 export GIT_DIR &&
245                 __git_C_args=(-C otherrepo) &&
246                 __git_find_repo_path &&
247                 echo "$__git_repo_path" >"$actual"
248         ) &&
249         test_cmp expected "$actual"
250 '
251
252 test_expect_success '__git_find_repo_path - relative dir in $GIT_DIR and "git -C"' '
253         echo "$ROOT/otherrepo/.git" >expected &&
254         (
255                 cd subdir &&
256                 GIT_DIR="otherrepo/.git" &&
257                 export GIT_DIR &&
258                 __git_C_args=(-C ..) &&
259                 __git_find_repo_path &&
260                 echo "$__git_repo_path" >"$actual"
261         ) &&
262         test_cmp expected "$actual"
263 '
264
265 test_expect_success '__git_find_repo_path - "git -C" while .git directory in cwd' '
266         echo "$ROOT/otherrepo/.git" >expected &&
267         (
268                 __git_C_args=(-C otherrepo) &&
269                 __git_find_repo_path &&
270                 echo "$__git_repo_path" >"$actual"
271         ) &&
272         test_cmp expected "$actual"
273 '
274
275 test_expect_success '__git_find_repo_path - "git -C" while cwd is a .git directory' '
276         echo "$ROOT/otherrepo/.git" >expected &&
277         (
278                 cd .git &&
279                 __git_C_args=(-C .. -C otherrepo) &&
280                 __git_find_repo_path &&
281                 echo "$__git_repo_path" >"$actual"
282         ) &&
283         test_cmp expected "$actual"
284 '
285
286 test_expect_success '__git_find_repo_path - "git -C" while .git directory in parent' '
287         echo "$ROOT/otherrepo/.git" >expected &&
288         (
289                 cd subdir &&
290                 __git_C_args=(-C .. -C otherrepo) &&
291                 __git_find_repo_path &&
292                 echo "$__git_repo_path" >"$actual"
293         ) &&
294         test_cmp expected "$actual"
295 '
296
297 test_expect_success '__git_find_repo_path - non-existing path in "git -C"' '
298         (
299                 __git_C_args=(-C non-existing) &&
300                 test_must_fail __git_find_repo_path &&
301                 printf "$__git_repo_path" >"$actual"
302         ) &&
303         test_must_be_empty "$actual"
304 '
305
306 test_expect_success '__git_find_repo_path - non-existing path in $__git_dir' '
307         (
308                 __git_dir="non-existing" &&
309                 test_must_fail __git_find_repo_path &&
310                 printf "$__git_repo_path" >"$actual"
311         ) &&
312         test_must_be_empty "$actual"
313 '
314
315 test_expect_success '__git_find_repo_path - non-existing $GIT_DIR' '
316         (
317                 GIT_DIR="$ROOT/non-existing" &&
318                 export GIT_DIR &&
319                 test_must_fail __git_find_repo_path &&
320                 printf "$__git_repo_path" >"$actual"
321         ) &&
322         test_must_be_empty "$actual"
323 '
324
325 test_expect_success '__git_find_repo_path - gitfile in cwd' '
326         echo "$ROOT/otherrepo/.git" >expected &&
327         echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
328         test_when_finished "rm -f subdir/.git" &&
329         (
330                 cd subdir &&
331                 __git_find_repo_path &&
332                 echo "$__git_repo_path" >"$actual"
333         ) &&
334         test_cmp expected "$actual"
335 '
336
337 test_expect_success '__git_find_repo_path - gitfile in parent' '
338         echo "$ROOT/otherrepo/.git" >expected &&
339         echo "gitdir: $ROOT/otherrepo/.git" >subdir/.git &&
340         test_when_finished "rm -f subdir/.git" &&
341         (
342                 cd subdir/subsubdir &&
343                 __git_find_repo_path &&
344                 echo "$__git_repo_path" >"$actual"
345         ) &&
346         test_cmp expected "$actual"
347 '
348
349 test_expect_success SYMLINKS '__git_find_repo_path - resulting path avoids symlinks' '
350         echo "$ROOT/otherrepo/.git" >expected &&
351         mkdir otherrepo/dir &&
352         test_when_finished "rm -rf otherrepo/dir" &&
353         ln -s otherrepo/dir link &&
354         test_when_finished "rm -f link" &&
355         (
356                 cd link &&
357                 __git_find_repo_path &&
358                 echo "$__git_repo_path" >"$actual"
359         ) &&
360         test_cmp expected "$actual"
361 '
362
363 test_expect_success '__git_find_repo_path - not a git repository' '
364         (
365                 cd non-repo &&
366                 GIT_CEILING_DIRECTORIES="$ROOT" &&
367                 export GIT_CEILING_DIRECTORIES &&
368                 test_must_fail __git_find_repo_path &&
369                 printf "$__git_repo_path" >"$actual"
370         ) &&
371         test_must_be_empty "$actual"
372 '
373
374 test_expect_success '__gitdir - finds repo' '
375         echo "$ROOT/.git" >expected &&
376         (
377                 cd subdir/subsubdir &&
378                 __gitdir >"$actual"
379         ) &&
380         test_cmp expected "$actual"
381 '
382
383
384 test_expect_success '__gitdir - returns error when cannot find repo' '
385         (
386                 __git_dir="non-existing" &&
387                 test_must_fail __gitdir >"$actual"
388         ) &&
389         test_must_be_empty "$actual"
390 '
391
392 test_expect_success '__gitdir - repo as argument' '
393         echo "otherrepo/.git" >expected &&
394         (
395                 __gitdir "otherrepo" >"$actual"
396         ) &&
397         test_cmp expected "$actual"
398 '
399
400 test_expect_success '__gitdir - remote as argument' '
401         echo "remote" >expected &&
402         (
403                 __gitdir "remote" >"$actual"
404         ) &&
405         test_cmp expected "$actual"
406 '
407
408
409 test_expect_success '__git_dequote - plain unquoted word' '
410         __git_dequote unquoted-word &&
411         verbose test unquoted-word = "$dequoted_word"
412 '
413
414 # input:    b\a\c\k\'\\\"s\l\a\s\h\es
415 # expected: back'\"slashes
416 test_expect_success '__git_dequote - backslash escaped' '
417         __git_dequote "b\a\c\k\\'\''\\\\\\\"s\l\a\s\h\es" &&
418         verbose test "back'\''\\\"slashes" = "$dequoted_word"
419 '
420
421 # input:    sin'gle\' '"quo'ted
422 # expected: single\ "quoted
423 test_expect_success '__git_dequote - single quoted' '
424         __git_dequote "'"sin'gle\\\\' '\\\"quo'ted"'" &&
425         verbose test '\''single\ "quoted'\'' = "$dequoted_word"
426 '
427
428 # input:    dou"ble\\" "\"\quot"ed
429 # expected: double\ "\quoted
430 test_expect_success '__git_dequote - double quoted' '
431         __git_dequote '\''dou"ble\\" "\"\quot"ed'\'' &&
432         verbose test '\''double\ "\quoted'\'' = "$dequoted_word"
433 '
434
435 # input: 'open single quote
436 test_expect_success '__git_dequote - open single quote' '
437         __git_dequote "'\''open single quote" &&
438         verbose test "open single quote" = "$dequoted_word"
439 '
440
441 # input: "open double quote
442 test_expect_success '__git_dequote - open double quote' '
443         __git_dequote "\"open double quote" &&
444         verbose test "open double quote" = "$dequoted_word"
445 '
446
447
448 test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
449         sed -e "s/Z$//g" >expected <<-EOF &&
450         with-trailing-space Z
451         without-trailing-spaceZ
452         --option Z
453         --option=Z
454         $invalid_variable_name Z
455         EOF
456         (
457                 cur=should_be_ignored &&
458                 __gitcomp_direct "$(cat expected)" &&
459                 print_comp
460         ) &&
461         test_cmp expected out
462 '
463
464 test_expect_success '__gitcomp - trailing space - options' '
465         test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
466                 --reset-author" <<-EOF
467         --reuse-message=Z
468         --reedit-message=Z
469         --reset-author Z
470         EOF
471 '
472
473 test_expect_success '__gitcomp - trailing space - config keys' '
474         test_gitcomp "br" "branch. branch.autosetupmerge
475                 branch.autosetuprebase browser." <<-\EOF
476         branch.Z
477         branch.autosetupmerge Z
478         branch.autosetuprebase Z
479         browser.Z
480         EOF
481 '
482
483 test_expect_success '__gitcomp - option parameter' '
484         test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
485                 "" "re" <<-\EOF
486         recursive Z
487         resolve Z
488         EOF
489 '
490
491 test_expect_success '__gitcomp - prefix' '
492         test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
493                 "branch.maint." "me" <<-\EOF
494         branch.maint.merge Z
495         branch.maint.mergeoptions Z
496         EOF
497 '
498
499 test_expect_success '__gitcomp - suffix' '
500         test_gitcomp "branch.me" "master maint next seen" "branch." \
501                 "ma" "." <<-\EOF
502         branch.master.Z
503         branch.maint.Z
504         EOF
505 '
506
507 test_expect_success '__gitcomp - ignore optional negative options' '
508         test_gitcomp "--" "--abc --def --no-one -- --no-two" <<-\EOF
509         --abc Z
510         --def Z
511         --no-one Z
512         --no-... Z
513         EOF
514 '
515
516 test_expect_success '__gitcomp - ignore/narrow optional negative options' '
517         test_gitcomp "--a" "--abc --abcdef --no-one -- --no-two" <<-\EOF
518         --abc Z
519         --abcdef Z
520         EOF
521 '
522
523 test_expect_success '__gitcomp - ignore/narrow optional negative options' '
524         test_gitcomp "--n" "--abc --def --no-one -- --no-two" <<-\EOF
525         --no-one Z
526         --no-... Z
527         EOF
528 '
529
530 test_expect_success '__gitcomp - expand all negative options' '
531         test_gitcomp "--no-" "--abc --def --no-one -- --no-two" <<-\EOF
532         --no-one Z
533         --no-two Z
534         EOF
535 '
536
537 test_expect_success '__gitcomp - expand/narrow all negative options' '
538         test_gitcomp "--no-o" "--abc --def --no-one -- --no-two" <<-\EOF
539         --no-one Z
540         EOF
541 '
542
543 test_expect_success '__gitcomp - equal skip' '
544         test_gitcomp "--option=" "--option=" <<-\EOF &&
545
546         EOF
547         test_gitcomp "option=" "option=" <<-\EOF
548
549         EOF
550 '
551
552 test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
553         __gitcomp "$invalid_variable_name"
554 '
555
556 read -r -d "" refs <<-\EOF
557 main
558 maint
559 next
560 seen
561 EOF
562
563 test_expect_success '__gitcomp_nl - trailing space' '
564         test_gitcomp_nl "m" "$refs" <<-EOF
565         main Z
566         maint Z
567         EOF
568 '
569
570 test_expect_success '__gitcomp_nl - prefix' '
571         test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
572         --fixup=main Z
573         --fixup=maint Z
574         EOF
575 '
576
577 test_expect_success '__gitcomp_nl - suffix' '
578         test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
579         branch.main.Z
580         branch.maint.Z
581         EOF
582 '
583
584 test_expect_success '__gitcomp_nl - no suffix' '
585         test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
586         mainZ
587         maintZ
588         EOF
589 '
590
591 test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
592         __gitcomp_nl "$invalid_variable_name"
593 '
594
595 test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '
596         cat >expect <<-EOF &&
597         remote_from_file_1
598         remote_from_file_2
599         remote_in_config_1
600         remote_in_config_2
601         EOF
602         test_when_finished "rm -rf .git/remotes" &&
603         mkdir -p .git/remotes &&
604         >.git/remotes/remote_from_file_1 &&
605         >.git/remotes/remote_from_file_2 &&
606         test_when_finished "git remote remove remote_in_config_1" &&
607         git remote add remote_in_config_1 git://remote_1 &&
608         test_when_finished "git remote remove remote_in_config_2" &&
609         git remote add remote_in_config_2 git://remote_2 &&
610         (
611                 __git_remotes >actual
612         ) &&
613         test_cmp expect actual
614 '
615
616 test_expect_success '__git_is_configured_remote' '
617         test_when_finished "git remote remove remote_1" &&
618         git remote add remote_1 git://remote_1 &&
619         test_when_finished "git remote remove remote_2" &&
620         git remote add remote_2 git://remote_2 &&
621         (
622                 verbose __git_is_configured_remote remote_2 &&
623                 test_must_fail __git_is_configured_remote non-existent
624         )
625 '
626
627 test_expect_success 'setup for ref completion' '
628         git commit --allow-empty -m initial &&
629         git branch -M main &&
630         git branch matching-branch &&
631         git tag matching-tag &&
632         (
633                 cd otherrepo &&
634                 git commit --allow-empty -m initial &&
635                 git branch -m main main-in-other &&
636                 git branch branch-in-other &&
637                 git tag tag-in-other
638         ) &&
639         git remote add other "$ROOT/otherrepo/.git" &&
640         git fetch --no-tags other &&
641         rm -f .git/FETCH_HEAD &&
642         git init thirdrepo
643 '
644
645 test_expect_success '__git_refs - simple' '
646         cat >expected <<-EOF &&
647         HEAD
648         main
649         matching-branch
650         other/branch-in-other
651         other/main-in-other
652         matching-tag
653         EOF
654         (
655                 cur= &&
656                 __git_refs >"$actual"
657         ) &&
658         test_cmp expected "$actual"
659 '
660
661 test_expect_success '__git_refs - full refs' '
662         cat >expected <<-EOF &&
663         refs/heads/main
664         refs/heads/matching-branch
665         refs/remotes/other/branch-in-other
666         refs/remotes/other/main-in-other
667         refs/tags/matching-tag
668         EOF
669         (
670                 cur=refs/heads/ &&
671                 __git_refs >"$actual"
672         ) &&
673         test_cmp expected "$actual"
674 '
675
676 test_expect_success '__git_refs - repo given on the command line' '
677         cat >expected <<-EOF &&
678         HEAD
679         branch-in-other
680         main-in-other
681         tag-in-other
682         EOF
683         (
684                 __git_dir="$ROOT/otherrepo/.git" &&
685                 cur= &&
686                 __git_refs >"$actual"
687         ) &&
688         test_cmp expected "$actual"
689 '
690
691 test_expect_success '__git_refs - remote on local file system' '
692         cat >expected <<-EOF &&
693         HEAD
694         branch-in-other
695         main-in-other
696         tag-in-other
697         EOF
698         (
699                 cur= &&
700                 __git_refs otherrepo >"$actual"
701         ) &&
702         test_cmp expected "$actual"
703 '
704
705 test_expect_success '__git_refs - remote on local file system - full refs' '
706         cat >expected <<-EOF &&
707         refs/heads/branch-in-other
708         refs/heads/main-in-other
709         refs/tags/tag-in-other
710         EOF
711         (
712                 cur=refs/ &&
713                 __git_refs otherrepo >"$actual"
714         ) &&
715         test_cmp expected "$actual"
716 '
717
718 test_expect_success '__git_refs - configured remote' '
719         cat >expected <<-EOF &&
720         HEAD
721         branch-in-other
722         main-in-other
723         EOF
724         (
725                 cur= &&
726                 __git_refs other >"$actual"
727         ) &&
728         test_cmp expected "$actual"
729 '
730
731 test_expect_success '__git_refs - configured remote - full refs' '
732         cat >expected <<-EOF &&
733         HEAD
734         refs/heads/branch-in-other
735         refs/heads/main-in-other
736         refs/tags/tag-in-other
737         EOF
738         (
739                 cur=refs/ &&
740                 __git_refs other >"$actual"
741         ) &&
742         test_cmp expected "$actual"
743 '
744
745 test_expect_success '__git_refs - configured remote - repo given on the command line' '
746         cat >expected <<-EOF &&
747         HEAD
748         branch-in-other
749         main-in-other
750         EOF
751         (
752                 cd thirdrepo &&
753                 __git_dir="$ROOT/.git" &&
754                 cur= &&
755                 __git_refs other >"$actual"
756         ) &&
757         test_cmp expected "$actual"
758 '
759
760 test_expect_success '__git_refs - configured remote - full refs - repo given on the command line' '
761         cat >expected <<-EOF &&
762         HEAD
763         refs/heads/branch-in-other
764         refs/heads/main-in-other
765         refs/tags/tag-in-other
766         EOF
767         (
768                 cd thirdrepo &&
769                 __git_dir="$ROOT/.git" &&
770                 cur=refs/ &&
771                 __git_refs other >"$actual"
772         ) &&
773         test_cmp expected "$actual"
774 '
775
776 test_expect_success '__git_refs - configured remote - remote name matches a directory' '
777         cat >expected <<-EOF &&
778         HEAD
779         branch-in-other
780         main-in-other
781         EOF
782         mkdir other &&
783         test_when_finished "rm -rf other" &&
784         (
785                 cur= &&
786                 __git_refs other >"$actual"
787         ) &&
788         test_cmp expected "$actual"
789 '
790
791 test_expect_success '__git_refs - URL remote' '
792         cat >expected <<-EOF &&
793         HEAD
794         branch-in-other
795         main-in-other
796         tag-in-other
797         EOF
798         (
799                 cur= &&
800                 __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
801         ) &&
802         test_cmp expected "$actual"
803 '
804
805 test_expect_success '__git_refs - URL remote - full refs' '
806         cat >expected <<-EOF &&
807         HEAD
808         refs/heads/branch-in-other
809         refs/heads/main-in-other
810         refs/tags/tag-in-other
811         EOF
812         (
813                 cur=refs/ &&
814                 __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
815         ) &&
816         test_cmp expected "$actual"
817 '
818
819 test_expect_success '__git_refs - non-existing remote' '
820         (
821                 cur= &&
822                 __git_refs non-existing >"$actual"
823         ) &&
824         test_must_be_empty "$actual"
825 '
826
827 test_expect_success '__git_refs - non-existing remote - full refs' '
828         (
829                 cur=refs/ &&
830                 __git_refs non-existing >"$actual"
831         ) &&
832         test_must_be_empty "$actual"
833 '
834
835 test_expect_success '__git_refs - non-existing URL remote' '
836         (
837                 cur= &&
838                 __git_refs "file://$ROOT/non-existing" >"$actual"
839         ) &&
840         test_must_be_empty "$actual"
841 '
842
843 test_expect_success '__git_refs - non-existing URL remote - full refs' '
844         (
845                 cur=refs/ &&
846                 __git_refs "file://$ROOT/non-existing" >"$actual"
847         ) &&
848         test_must_be_empty "$actual"
849 '
850
851 test_expect_success '__git_refs - not in a git repository' '
852         (
853                 GIT_CEILING_DIRECTORIES="$ROOT" &&
854                 export GIT_CEILING_DIRECTORIES &&
855                 cd subdir &&
856                 cur= &&
857                 __git_refs >"$actual"
858         ) &&
859         test_must_be_empty "$actual"
860 '
861
862 test_expect_success '__git_refs - unique remote branches for git checkout DWIMery' '
863         cat >expected <<-EOF &&
864         HEAD
865         main
866         matching-branch
867         other/ambiguous
868         other/branch-in-other
869         other/main-in-other
870         remote/ambiguous
871         remote/branch-in-remote
872         matching-tag
873         branch-in-other
874         branch-in-remote
875         main-in-other
876         EOF
877         for remote_ref in refs/remotes/other/ambiguous \
878                 refs/remotes/remote/ambiguous \
879                 refs/remotes/remote/branch-in-remote
880         do
881                 git update-ref $remote_ref main &&
882                 test_when_finished "git update-ref -d $remote_ref"
883         done &&
884         (
885                 cur= &&
886                 __git_refs "" 1 >"$actual"
887         ) &&
888         test_cmp expected "$actual"
889 '
890
891 test_expect_success '__git_refs - after --opt=' '
892         cat >expected <<-EOF &&
893         HEAD
894         main
895         matching-branch
896         other/branch-in-other
897         other/main-in-other
898         matching-tag
899         EOF
900         (
901                 cur="--opt=" &&
902                 __git_refs "" "" "" "" >"$actual"
903         ) &&
904         test_cmp expected "$actual"
905 '
906
907 test_expect_success '__git_refs - after --opt= - full refs' '
908         cat >expected <<-EOF &&
909         refs/heads/main
910         refs/heads/matching-branch
911         refs/remotes/other/branch-in-other
912         refs/remotes/other/main-in-other
913         refs/tags/matching-tag
914         EOF
915         (
916                 cur="--opt=refs/" &&
917                 __git_refs "" "" "" refs/ >"$actual"
918         ) &&
919         test_cmp expected "$actual"
920 '
921
922 test_expect_success '__git refs - excluding refs' '
923         cat >expected <<-EOF &&
924         ^HEAD
925         ^main
926         ^matching-branch
927         ^other/branch-in-other
928         ^other/main-in-other
929         ^matching-tag
930         EOF
931         (
932                 cur=^ &&
933                 __git_refs >"$actual"
934         ) &&
935         test_cmp expected "$actual"
936 '
937
938 test_expect_success '__git refs - excluding full refs' '
939         cat >expected <<-EOF &&
940         ^refs/heads/main
941         ^refs/heads/matching-branch
942         ^refs/remotes/other/branch-in-other
943         ^refs/remotes/other/main-in-other
944         ^refs/tags/matching-tag
945         EOF
946         (
947                 cur=^refs/ &&
948                 __git_refs >"$actual"
949         ) &&
950         test_cmp expected "$actual"
951 '
952
953 test_expect_success 'setup for filtering matching refs' '
954         git branch matching/branch &&
955         git tag matching/tag &&
956         git -C otherrepo branch matching/branch-in-other &&
957         git fetch --no-tags other &&
958         rm -f .git/FETCH_HEAD
959 '
960
961 test_expect_success '__git_refs - do not filter refs unless told so' '
962         cat >expected <<-EOF &&
963         HEAD
964         main
965         matching-branch
966         matching/branch
967         other/branch-in-other
968         other/main-in-other
969         other/matching/branch-in-other
970         matching-tag
971         matching/tag
972         EOF
973         (
974                 cur=main &&
975                 __git_refs >"$actual"
976         ) &&
977         test_cmp expected "$actual"
978 '
979
980 test_expect_success '__git_refs - only matching refs' '
981         cat >expected <<-EOF &&
982         matching-branch
983         matching/branch
984         matching-tag
985         matching/tag
986         EOF
987         (
988                 cur=mat &&
989                 __git_refs "" "" "" "$cur" >"$actual"
990         ) &&
991         test_cmp expected "$actual"
992 '
993
994 test_expect_success '__git_refs - only matching refs - full refs' '
995         cat >expected <<-EOF &&
996         refs/heads/matching-branch
997         refs/heads/matching/branch
998         EOF
999         (
1000                 cur=refs/heads/mat &&
1001                 __git_refs "" "" "" "$cur" >"$actual"
1002         ) &&
1003         test_cmp expected "$actual"
1004 '
1005
1006 test_expect_success '__git_refs - only matching refs - remote on local file system' '
1007         cat >expected <<-EOF &&
1008         main-in-other
1009         matching/branch-in-other
1010         EOF
1011         (
1012                 cur=ma &&
1013                 __git_refs otherrepo "" "" "$cur" >"$actual"
1014         ) &&
1015         test_cmp expected "$actual"
1016 '
1017
1018 test_expect_success '__git_refs - only matching refs - configured remote' '
1019         cat >expected <<-EOF &&
1020         main-in-other
1021         matching/branch-in-other
1022         EOF
1023         (
1024                 cur=ma &&
1025                 __git_refs other "" "" "$cur" >"$actual"
1026         ) &&
1027         test_cmp expected "$actual"
1028 '
1029
1030 test_expect_success '__git_refs - only matching refs - remote - full refs' '
1031         cat >expected <<-EOF &&
1032         refs/heads/main-in-other
1033         refs/heads/matching/branch-in-other
1034         EOF
1035         (
1036                 cur=refs/heads/ma &&
1037                 __git_refs other "" "" "$cur" >"$actual"
1038         ) &&
1039         test_cmp expected "$actual"
1040 '
1041
1042 test_expect_success '__git_refs - only matching refs - checkout DWIMery' '
1043         cat >expected <<-EOF &&
1044         matching-branch
1045         matching/branch
1046         matching-tag
1047         matching/tag
1048         matching/branch-in-other
1049         EOF
1050         for remote_ref in refs/remotes/other/ambiguous \
1051                 refs/remotes/remote/ambiguous \
1052                 refs/remotes/remote/branch-in-remote
1053         do
1054                 git update-ref $remote_ref main &&
1055                 test_when_finished "git update-ref -d $remote_ref"
1056         done &&
1057         (
1058                 cur=mat &&
1059                 __git_refs "" 1 "" "$cur" >"$actual"
1060         ) &&
1061         test_cmp expected "$actual"
1062 '
1063
1064 test_expect_success 'teardown after filtering matching refs' '
1065         git branch -d matching/branch &&
1066         git tag -d matching/tag &&
1067         git update-ref -d refs/remotes/other/matching/branch-in-other &&
1068         git -C otherrepo branch -D matching/branch-in-other
1069 '
1070
1071 test_expect_success '__git_refs - for-each-ref format specifiers in prefix' '
1072         cat >expected <<-EOF &&
1073         evil-%%-%42-%(refname)..main
1074         EOF
1075         (
1076                 cur="evil-%%-%42-%(refname)..mai" &&
1077                 __git_refs "" "" "evil-%%-%42-%(refname).." mai >"$actual"
1078         ) &&
1079         test_cmp expected "$actual"
1080 '
1081
1082 test_expect_success '__git_complete_refs - simple' '
1083         sed -e "s/Z$//" >expected <<-EOF &&
1084         HEAD Z
1085         main Z
1086         matching-branch Z
1087         other/branch-in-other Z
1088         other/main-in-other Z
1089         matching-tag Z
1090         EOF
1091         (
1092                 cur= &&
1093                 __git_complete_refs &&
1094                 print_comp
1095         ) &&
1096         test_cmp expected out
1097 '
1098
1099 test_expect_success '__git_complete_refs - matching' '
1100         sed -e "s/Z$//" >expected <<-EOF &&
1101         matching-branch Z
1102         matching-tag Z
1103         EOF
1104         (
1105                 cur=mat &&
1106                 __git_complete_refs &&
1107                 print_comp
1108         ) &&
1109         test_cmp expected out
1110 '
1111
1112 test_expect_success '__git_complete_refs - remote' '
1113         sed -e "s/Z$//" >expected <<-EOF &&
1114         HEAD Z
1115         branch-in-other Z
1116         main-in-other Z
1117         EOF
1118         (
1119                 cur= &&
1120                 __git_complete_refs --remote=other &&
1121                 print_comp
1122         ) &&
1123         test_cmp expected out
1124 '
1125
1126 test_expect_success '__git_complete_refs - track' '
1127         sed -e "s/Z$//" >expected <<-EOF &&
1128         HEAD Z
1129         main Z
1130         matching-branch Z
1131         other/branch-in-other Z
1132         other/main-in-other Z
1133         matching-tag Z
1134         branch-in-other Z
1135         main-in-other Z
1136         EOF
1137         (
1138                 cur= &&
1139                 __git_complete_refs --track &&
1140                 print_comp
1141         ) &&
1142         test_cmp expected out
1143 '
1144
1145 test_expect_success '__git_complete_refs - current word' '
1146         sed -e "s/Z$//" >expected <<-EOF &&
1147         matching-branch Z
1148         matching-tag Z
1149         EOF
1150         (
1151                 cur="--option=mat" &&
1152                 __git_complete_refs --cur="${cur#*=}" &&
1153                 print_comp
1154         ) &&
1155         test_cmp expected out
1156 '
1157
1158 test_expect_success '__git_complete_refs - prefix' '
1159         sed -e "s/Z$//" >expected <<-EOF &&
1160         v1.0..matching-branch Z
1161         v1.0..matching-tag Z
1162         EOF
1163         (
1164                 cur=v1.0..mat &&
1165                 __git_complete_refs --pfx=v1.0.. --cur=mat &&
1166                 print_comp
1167         ) &&
1168         test_cmp expected out
1169 '
1170
1171 test_expect_success '__git_complete_refs - suffix' '
1172         cat >expected <<-EOF &&
1173         HEAD.
1174         main.
1175         matching-branch.
1176         other/branch-in-other.
1177         other/main-in-other.
1178         matching-tag.
1179         EOF
1180         (
1181                 cur= &&
1182                 __git_complete_refs --sfx=. &&
1183                 print_comp
1184         ) &&
1185         test_cmp expected out
1186 '
1187
1188 test_expect_success '__git_complete_fetch_refspecs - simple' '
1189         sed -e "s/Z$//" >expected <<-EOF &&
1190         HEAD:HEAD Z
1191         branch-in-other:branch-in-other Z
1192         main-in-other:main-in-other Z
1193         EOF
1194         (
1195                 cur= &&
1196                 __git_complete_fetch_refspecs other &&
1197                 print_comp
1198         ) &&
1199         test_cmp expected out
1200 '
1201
1202 test_expect_success '__git_complete_fetch_refspecs - matching' '
1203         sed -e "s/Z$//" >expected <<-EOF &&
1204         branch-in-other:branch-in-other Z
1205         EOF
1206         (
1207                 cur=br &&
1208                 __git_complete_fetch_refspecs other "" br &&
1209                 print_comp
1210         ) &&
1211         test_cmp expected out
1212 '
1213
1214 test_expect_success '__git_complete_fetch_refspecs - prefix' '
1215         sed -e "s/Z$//" >expected <<-EOF &&
1216         +HEAD:HEAD Z
1217         +branch-in-other:branch-in-other Z
1218         +main-in-other:main-in-other Z
1219         EOF
1220         (
1221                 cur="+" &&
1222                 __git_complete_fetch_refspecs other "+" ""  &&
1223                 print_comp
1224         ) &&
1225         test_cmp expected out
1226 '
1227
1228 test_expect_success '__git_complete_fetch_refspecs - fully qualified' '
1229         sed -e "s/Z$//" >expected <<-EOF &&
1230         refs/heads/branch-in-other:refs/heads/branch-in-other Z
1231         refs/heads/main-in-other:refs/heads/main-in-other Z
1232         refs/tags/tag-in-other:refs/tags/tag-in-other Z
1233         EOF
1234         (
1235                 cur=refs/ &&
1236                 __git_complete_fetch_refspecs other "" refs/ &&
1237                 print_comp
1238         ) &&
1239         test_cmp expected out
1240 '
1241
1242 test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '
1243         sed -e "s/Z$//" >expected <<-EOF &&
1244         +refs/heads/branch-in-other:refs/heads/branch-in-other Z
1245         +refs/heads/main-in-other:refs/heads/main-in-other Z
1246         +refs/tags/tag-in-other:refs/tags/tag-in-other Z
1247         EOF
1248         (
1249                 cur=+refs/ &&
1250                 __git_complete_fetch_refspecs other + refs/ &&
1251                 print_comp
1252         ) &&
1253         test_cmp expected out
1254 '
1255
1256 test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' '
1257         test_completion "git switch " <<-\EOF
1258         branch-in-other Z
1259         main Z
1260         main-in-other Z
1261         matching-branch Z
1262         EOF
1263 '
1264
1265 test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' '
1266         test_completion "git checkout " <<-\EOF
1267         HEAD Z
1268         branch-in-other Z
1269         main Z
1270         main-in-other Z
1271         matching-branch Z
1272         matching-tag Z
1273         other/branch-in-other Z
1274         other/main-in-other Z
1275         EOF
1276 '
1277
1278 test_expect_success 'git switch - with --no-guess, complete only local branches' '
1279         test_completion "git switch --no-guess " <<-\EOF
1280         main Z
1281         matching-branch Z
1282         EOF
1283 '
1284
1285 test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' '
1286         GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch " <<-\EOF
1287         main Z
1288         matching-branch Z
1289         EOF
1290 '
1291
1292 test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '
1293         GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git switch --guess " <<-\EOF
1294         branch-in-other Z
1295         main Z
1296         main-in-other Z
1297         matching-branch Z
1298         EOF
1299 '
1300
1301 test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '
1302         test_completion "git switch --no-guess --guess " <<-\EOF
1303         branch-in-other Z
1304         main Z
1305         main-in-other Z
1306         matching-branch Z
1307         EOF
1308 '
1309
1310 test_expect_success 'git switch - a later --no-guess overrides previous --guess, complete only local branches' '
1311         test_completion "git switch --guess --no-guess " <<-\EOF
1312         main Z
1313         matching-branch Z
1314         EOF
1315 '
1316
1317 test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' '
1318         GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout " <<-\EOF
1319         HEAD Z
1320         main Z
1321         matching-branch Z
1322         matching-tag Z
1323         other/branch-in-other Z
1324         other/main-in-other Z
1325         EOF
1326 '
1327
1328 test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '
1329         GIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion "git checkout --guess " <<-\EOF
1330         HEAD Z
1331         branch-in-other Z
1332         main Z
1333         main-in-other Z
1334         matching-branch Z
1335         matching-tag Z
1336         other/branch-in-other Z
1337         other/main-in-other Z
1338         EOF
1339 '
1340
1341 test_expect_success 'git checkout - with --no-guess, only completes refs' '
1342         test_completion "git checkout --no-guess " <<-\EOF
1343         HEAD Z
1344         main Z
1345         matching-branch Z
1346         matching-tag Z
1347         other/branch-in-other Z
1348         other/main-in-other Z
1349         EOF
1350 '
1351
1352 test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '
1353         test_completion "git checkout --no-guess --guess " <<-\EOF
1354         HEAD Z
1355         branch-in-other Z
1356         main Z
1357         main-in-other Z
1358         matching-branch Z
1359         matching-tag Z
1360         other/branch-in-other Z
1361         other/main-in-other Z
1362         EOF
1363 '
1364
1365 test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' '
1366         test_completion "git checkout --guess --no-guess " <<-\EOF
1367         HEAD Z
1368         main Z
1369         matching-branch Z
1370         matching-tag Z
1371         other/branch-in-other Z
1372         other/main-in-other Z
1373         EOF
1374 '
1375
1376 test_expect_success 'git checkout - with checkout.guess = false, only completes refs' '
1377         test_config checkout.guess false &&
1378         test_completion "git checkout " <<-\EOF
1379         HEAD Z
1380         main Z
1381         matching-branch Z
1382         matching-tag Z
1383         other/branch-in-other Z
1384         other/main-in-other Z
1385         EOF
1386 '
1387
1388 test_expect_success 'git checkout - with checkout.guess = true, completes refs and unique remote branches for DWIM' '
1389         test_config checkout.guess true &&
1390         test_completion "git checkout " <<-\EOF
1391         HEAD Z
1392         branch-in-other Z
1393         main Z
1394         main-in-other Z
1395         matching-branch Z
1396         matching-tag Z
1397         other/branch-in-other Z
1398         other/main-in-other Z
1399         EOF
1400 '
1401
1402 test_expect_success 'git checkout - a later --guess overrides previous checkout.guess = false, complete refs and unique remote branches for DWIM' '
1403         test_config checkout.guess false &&
1404         test_completion "git checkout --guess " <<-\EOF
1405         HEAD Z
1406         branch-in-other Z
1407         main Z
1408         main-in-other Z
1409         matching-branch Z
1410         matching-tag Z
1411         other/branch-in-other Z
1412         other/main-in-other Z
1413         EOF
1414 '
1415
1416 test_expect_success 'git checkout - a later --no-guess overrides previous checkout.guess = true, complete only refs' '
1417         test_config checkout.guess true &&
1418         test_completion "git checkout --no-guess " <<-\EOF
1419         HEAD Z
1420         main Z
1421         matching-branch Z
1422         matching-tag Z
1423         other/branch-in-other Z
1424         other/main-in-other Z
1425         EOF
1426 '
1427
1428 test_expect_success 'git switch - with --detach, complete all references' '
1429         test_completion "git switch --detach " <<-\EOF
1430         HEAD Z
1431         main Z
1432         matching-branch Z
1433         matching-tag Z
1434         other/branch-in-other Z
1435         other/main-in-other Z
1436         EOF
1437 '
1438
1439 test_expect_success 'git checkout - with --detach, complete only references' '
1440         test_completion "git checkout --detach " <<-\EOF
1441         HEAD Z
1442         main Z
1443         matching-branch Z
1444         matching-tag Z
1445         other/branch-in-other Z
1446         other/main-in-other Z
1447         EOF
1448 '
1449
1450 test_expect_success 'git switch - with -d, complete all references' '
1451         test_completion "git switch -d " <<-\EOF
1452         HEAD Z
1453         main Z
1454         matching-branch Z
1455         matching-tag Z
1456         other/branch-in-other Z
1457         other/main-in-other Z
1458         EOF
1459 '
1460
1461 test_expect_success 'git checkout - with -d, complete only references' '
1462         test_completion "git checkout -d " <<-\EOF
1463         HEAD Z
1464         main Z
1465         matching-branch Z
1466         matching-tag Z
1467         other/branch-in-other Z
1468         other/main-in-other Z
1469         EOF
1470 '
1471
1472 test_expect_success 'git switch - with --track, complete only remote branches' '
1473         test_completion "git switch --track " <<-\EOF
1474         other/branch-in-other Z
1475         other/main-in-other Z
1476         EOF
1477 '
1478
1479 test_expect_success 'git checkout - with --track, complete only remote branches' '
1480         test_completion "git checkout --track " <<-\EOF
1481         other/branch-in-other Z
1482         other/main-in-other Z
1483         EOF
1484 '
1485
1486 test_expect_success 'git switch - with --no-track, complete only local branch names' '
1487         test_completion "git switch --no-track " <<-\EOF
1488         main Z
1489         matching-branch Z
1490         EOF
1491 '
1492
1493 test_expect_success 'git checkout - with --no-track, complete only local references' '
1494         test_completion "git checkout --no-track " <<-\EOF
1495         HEAD Z
1496         main Z
1497         matching-branch Z
1498         matching-tag Z
1499         other/branch-in-other Z
1500         other/main-in-other Z
1501         EOF
1502 '
1503
1504 test_expect_success 'git switch - with -c, complete all references' '
1505         test_completion "git switch -c new-branch " <<-\EOF
1506         HEAD Z
1507         main Z
1508         matching-branch Z
1509         matching-tag Z
1510         other/branch-in-other Z
1511         other/main-in-other Z
1512         EOF
1513 '
1514
1515 test_expect_success 'git switch - with -C, complete all references' '
1516         test_completion "git switch -C new-branch " <<-\EOF
1517         HEAD Z
1518         main Z
1519         matching-branch Z
1520         matching-tag Z
1521         other/branch-in-other Z
1522         other/main-in-other Z
1523         EOF
1524 '
1525
1526 test_expect_success 'git switch - with -c and --track, complete all references' '
1527         test_completion "git switch -c new-branch --track " <<-EOF
1528         HEAD Z
1529         main Z
1530         matching-branch Z
1531         matching-tag Z
1532         other/branch-in-other Z
1533         other/main-in-other Z
1534         EOF
1535 '
1536
1537 test_expect_success 'git switch - with -C and --track, complete all references' '
1538         test_completion "git switch -C new-branch --track " <<-EOF
1539         HEAD Z
1540         main Z
1541         matching-branch Z
1542         matching-tag Z
1543         other/branch-in-other Z
1544         other/main-in-other Z
1545         EOF
1546 '
1547
1548 test_expect_success 'git switch - with -c and --no-track, complete all references' '
1549         test_completion "git switch -c new-branch --no-track " <<-\EOF
1550         HEAD Z
1551         main Z
1552         matching-branch Z
1553         matching-tag Z
1554         other/branch-in-other Z
1555         other/main-in-other Z
1556         EOF
1557 '
1558
1559 test_expect_success 'git switch - with -C and --no-track, complete all references' '
1560         test_completion "git switch -C new-branch --no-track " <<-\EOF
1561         HEAD Z
1562         main Z
1563         matching-branch Z
1564         matching-tag Z
1565         other/branch-in-other Z
1566         other/main-in-other Z
1567         EOF
1568 '
1569
1570 test_expect_success 'git checkout - with -b, complete all references' '
1571         test_completion "git checkout -b new-branch " <<-\EOF
1572         HEAD Z
1573         main Z
1574         matching-branch Z
1575         matching-tag Z
1576         other/branch-in-other Z
1577         other/main-in-other Z
1578         EOF
1579 '
1580
1581 test_expect_success 'git checkout - with -B, complete all references' '
1582         test_completion "git checkout -B new-branch " <<-\EOF
1583         HEAD Z
1584         main Z
1585         matching-branch Z
1586         matching-tag Z
1587         other/branch-in-other Z
1588         other/main-in-other Z
1589         EOF
1590 '
1591
1592 test_expect_success 'git checkout - with -b and --track, complete all references' '
1593         test_completion "git checkout -b new-branch --track " <<-EOF
1594         HEAD Z
1595         main Z
1596         matching-branch Z
1597         matching-tag Z
1598         other/branch-in-other Z
1599         other/main-in-other Z
1600         EOF
1601 '
1602
1603 test_expect_success 'git checkout - with -B and --track, complete all references' '
1604         test_completion "git checkout -B new-branch --track " <<-EOF
1605         HEAD Z
1606         main Z
1607         matching-branch Z
1608         matching-tag Z
1609         other/branch-in-other Z
1610         other/main-in-other Z
1611         EOF
1612 '
1613
1614 test_expect_success 'git checkout - with -b and --no-track, complete all references' '
1615         test_completion "git checkout -b new-branch --no-track " <<-\EOF
1616         HEAD Z
1617         main Z
1618         matching-branch Z
1619         matching-tag Z
1620         other/branch-in-other Z
1621         other/main-in-other Z
1622         EOF
1623 '
1624
1625 test_expect_success 'git checkout - with -B and --no-track, complete all references' '
1626         test_completion "git checkout -B new-branch --no-track " <<-\EOF
1627         HEAD Z
1628         main Z
1629         matching-branch Z
1630         matching-tag Z
1631         other/branch-in-other Z
1632         other/main-in-other Z
1633         EOF
1634 '
1635
1636 test_expect_success 'git switch - for -c, complete local branches and unique remote branches' '
1637         test_completion "git switch -c " <<-\EOF
1638         branch-in-other Z
1639         main Z
1640         main-in-other Z
1641         matching-branch Z
1642         EOF
1643 '
1644
1645 test_expect_success 'git switch - for -C, complete local branches and unique remote branches' '
1646         test_completion "git switch -C " <<-\EOF
1647         branch-in-other Z
1648         main Z
1649         main-in-other Z
1650         matching-branch Z
1651         EOF
1652 '
1653
1654 test_expect_success 'git switch - for -c with --no-guess, complete local branches only' '
1655         test_completion "git switch --no-guess -c " <<-\EOF
1656         main Z
1657         matching-branch Z
1658         EOF
1659 '
1660
1661 test_expect_success 'git switch - for -C with --no-guess, complete local branches only' '
1662         test_completion "git switch --no-guess -C " <<-\EOF
1663         main Z
1664         matching-branch Z
1665         EOF
1666 '
1667
1668 test_expect_success 'git switch - for -c with --no-track, complete local branches only' '
1669         test_completion "git switch --no-track -c " <<-\EOF
1670         main Z
1671         matching-branch Z
1672         EOF
1673 '
1674
1675 test_expect_success 'git switch - for -C with --no-track, complete local branches only' '
1676         test_completion "git switch --no-track -C " <<-\EOF
1677         main Z
1678         matching-branch Z
1679         EOF
1680 '
1681
1682 test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' '
1683         test_completion "git checkout -b " <<-\EOF
1684         branch-in-other Z
1685         main Z
1686         main-in-other Z
1687         matching-branch Z
1688         EOF
1689 '
1690
1691 test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' '
1692         test_completion "git checkout -B " <<-\EOF
1693         branch-in-other Z
1694         main Z
1695         main-in-other Z
1696         matching-branch Z
1697         EOF
1698 '
1699
1700 test_expect_success 'git checkout - for -b with --no-guess, complete local branches only' '
1701         test_completion "git checkout --no-guess -b " <<-\EOF
1702         main Z
1703         matching-branch Z
1704         EOF
1705 '
1706
1707 test_expect_success 'git checkout - for -B with --no-guess, complete local branches only' '
1708         test_completion "git checkout --no-guess -B " <<-\EOF
1709         main Z
1710         matching-branch Z
1711         EOF
1712 '
1713
1714 test_expect_success 'git checkout - for -b with --no-track, complete local branches only' '
1715         test_completion "git checkout --no-track -b " <<-\EOF
1716         main Z
1717         matching-branch Z
1718         EOF
1719 '
1720
1721 test_expect_success 'git checkout - for -B with --no-track, complete local branches only' '
1722         test_completion "git checkout --no-track -B " <<-\EOF
1723         main Z
1724         matching-branch Z
1725         EOF
1726 '
1727
1728 test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' '
1729         test_completion "git switch --orphan " <<-\EOF
1730         branch-in-other Z
1731         main Z
1732         main-in-other Z
1733         matching-branch Z
1734         EOF
1735 '
1736
1737 test_expect_success 'git switch - --orphan with branch already provided completes nothing else' '
1738         test_completion "git switch --orphan main " <<-\EOF
1739
1740         EOF
1741 '
1742
1743 test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' '
1744         test_completion "git checkout --orphan " <<-\EOF
1745         branch-in-other Z
1746         main Z
1747         main-in-other Z
1748         matching-branch Z
1749         EOF
1750 '
1751
1752 test_expect_success 'git checkout - --orphan with branch already provided completes local refs for a start-point' '
1753         test_completion "git checkout --orphan main " <<-\EOF
1754         HEAD Z
1755         main Z
1756         matching-branch Z
1757         matching-tag Z
1758         other/branch-in-other Z
1759         other/main-in-other Z
1760         EOF
1761 '
1762
1763 test_expect_success 'teardown after ref completion' '
1764         git branch -d matching-branch &&
1765         git tag -d matching-tag &&
1766         git remote remove other
1767 '
1768
1769
1770 test_path_completion ()
1771 {
1772         test $# = 2 || BUG "not 2 parameters to test_path_completion"
1773
1774         local cur="$1" expected="$2"
1775         echo "$expected" >expected &&
1776         (
1777                 # In the following tests calling this function we only
1778                 # care about how __git_complete_index_file() deals with
1779                 # unusual characters in path names.  By requesting only
1780                 # untracked files we do not have to bother adding any
1781                 # paths to the index in those tests.
1782                 __git_complete_index_file --others &&
1783                 print_comp
1784         ) &&
1785         test_cmp expected out
1786 }
1787
1788 test_expect_success 'setup for path completion tests' '
1789         mkdir simple-dir \
1790               "spaces in dir" \
1791               árvíztűrő &&
1792         touch simple-dir/simple-file \
1793               "spaces in dir/spaces in file" \
1794               "árvíztűrő/Сайн яваарай" &&
1795         if test_have_prereq !MINGW &&
1796            mkdir BS\\dir \
1797                  '$'separators\034in\035dir'' &&
1798            touch BS\\dir/DQ\"file \
1799                  '$'separators\034in\035dir/sep\036in\037file''
1800         then
1801                 test_set_prereq FUNNIERNAMES
1802         else
1803                 rm -rf BS\\dir '$'separators\034in\035dir''
1804         fi
1805 '
1806
1807 test_expect_success '__git_complete_index_file - simple' '
1808         test_path_completion simple simple-dir &&  # Bash is supposed to
1809                                                    # add the trailing /.
1810         test_path_completion simple-dir/simple simple-dir/simple-file
1811 '
1812
1813 test_expect_success \
1814     '__git_complete_index_file - escaped characters on cmdline' '
1815         test_path_completion spac "spaces in dir" &&  # Bash will turn this
1816                                                       # into "spaces\ in\ dir"
1817         test_path_completion "spaces\\ i" \
1818                              "spaces in dir" &&
1819         test_path_completion "spaces\\ in\\ dir/s" \
1820                              "spaces in dir/spaces in file" &&
1821         test_path_completion "spaces\\ in\\ dir/spaces\\ i" \
1822                              "spaces in dir/spaces in file"
1823 '
1824
1825 test_expect_success \
1826     '__git_complete_index_file - quoted characters on cmdline' '
1827         # Testing with an opening but without a corresponding closing
1828         # double quote is important.
1829         test_path_completion \"spac "spaces in dir" &&
1830         test_path_completion "\"spaces i" \
1831                              "spaces in dir" &&
1832         test_path_completion "\"spaces in dir/s" \
1833                              "spaces in dir/spaces in file" &&
1834         test_path_completion "\"spaces in dir/spaces i" \
1835                              "spaces in dir/spaces in file"
1836 '
1837
1838 test_expect_success '__git_complete_index_file - UTF-8 in ls-files output' '
1839         test_path_completion á árvíztűrő &&
1840         test_path_completion árvíztűrő/С "árvíztűrő/Сайн яваарай"
1841 '
1842
1843 test_expect_success FUNNIERNAMES \
1844     '__git_complete_index_file - C-style escapes in ls-files output' '
1845         test_path_completion BS \
1846                              BS\\dir &&
1847         test_path_completion BS\\\\d \
1848                              BS\\dir &&
1849         test_path_completion BS\\\\dir/DQ \
1850                              BS\\dir/DQ\"file &&
1851         test_path_completion BS\\\\dir/DQ\\\"f \
1852                              BS\\dir/DQ\"file
1853 '
1854
1855 test_expect_success FUNNIERNAMES \
1856     '__git_complete_index_file - \nnn-escaped characters in ls-files output' '
1857         test_path_completion sep '$'separators\034in\035dir'' &&
1858         test_path_completion '$'separators\034i'' \
1859                              '$'separators\034in\035dir'' &&
1860         test_path_completion '$'separators\034in\035dir/sep'' \
1861                              '$'separators\034in\035dir/sep\036in\037file'' &&
1862         test_path_completion '$'separators\034in\035dir/sep\036i'' \
1863                              '$'separators\034in\035dir/sep\036in\037file''
1864 '
1865
1866 test_expect_success FUNNYNAMES \
1867     '__git_complete_index_file - removing repeated quoted path components' '
1868         test_when_finished rm -r repeated-quoted &&
1869         mkdir repeated-quoted &&      # A directory whose name in itself
1870                                       # would not be quoted ...
1871         >repeated-quoted/0-file &&
1872         >repeated-quoted/1\"file &&   # ... but here the file makes the
1873                                       # dirname quoted ...
1874         >repeated-quoted/2-file &&
1875         >repeated-quoted/3\"file &&   # ... and here, too.
1876
1877         # Still, we shold only list the directory name only once.
1878         test_path_completion repeated repeated-quoted
1879 '
1880
1881 test_expect_success 'teardown after path completion tests' '
1882         rm -rf simple-dir "spaces in dir" árvíztűrő \
1883                BS\\dir '$'separators\034in\035dir''
1884 '
1885
1886 test_expect_success '__git_find_on_cmdline - single match' '
1887         echo list >expect &&
1888         (
1889                 words=(git command --opt list) &&
1890                 cword=${#words[@]} &&
1891                 __git_cmd_idx=1 &&
1892                 __git_find_on_cmdline "add list remove" >actual
1893         ) &&
1894         test_cmp expect actual
1895 '
1896
1897 test_expect_success '__git_find_on_cmdline - multiple matches' '
1898         echo remove >expect &&
1899         (
1900                 words=(git command -o --opt remove list add) &&
1901                 cword=${#words[@]} &&
1902                 __git_cmd_idx=1 &&
1903                 __git_find_on_cmdline "add list remove" >actual
1904         ) &&
1905         test_cmp expect actual
1906 '
1907
1908 test_expect_success '__git_find_on_cmdline - no match' '
1909         (
1910                 words=(git command --opt branch) &&
1911                 cword=${#words[@]} &&
1912                 __git_cmd_idx=1 &&
1913                 __git_find_on_cmdline "add list remove" >actual
1914         ) &&
1915         test_must_be_empty actual
1916 '
1917
1918 test_expect_success '__git_find_on_cmdline - single match with index' '
1919         echo "3 list" >expect &&
1920         (
1921                 words=(git command --opt list) &&
1922                 cword=${#words[@]} &&
1923                 __git_cmd_idx=1 &&
1924                 __git_find_on_cmdline --show-idx "add list remove" >actual
1925         ) &&
1926         test_cmp expect actual
1927 '
1928
1929 test_expect_success '__git_find_on_cmdline - multiple matches with index' '
1930         echo "4 remove" >expect &&
1931         (
1932                 words=(git command -o --opt remove list add) &&
1933                 cword=${#words[@]} &&
1934                 __git_cmd_idx=1 &&
1935                 __git_find_on_cmdline --show-idx "add list remove" >actual
1936         ) &&
1937         test_cmp expect actual
1938 '
1939
1940 test_expect_success '__git_find_on_cmdline - no match with index' '
1941         (
1942                 words=(git command --opt branch) &&
1943                 cword=${#words[@]} &&
1944                 __git_cmd_idx=1 &&
1945                 __git_find_on_cmdline --show-idx "add list remove" >actual
1946         ) &&
1947         test_must_be_empty actual
1948 '
1949
1950 test_expect_success '__git_find_on_cmdline - ignores matches before command with index' '
1951         echo "6 remove" >expect &&
1952         (
1953                 words=(git -C remove command -o --opt remove list add) &&
1954                 cword=${#words[@]} &&
1955                 __git_cmd_idx=3 &&
1956                 __git_find_on_cmdline --show-idx "add list remove" >actual
1957         ) &&
1958         test_cmp expect actual
1959 '
1960
1961 test_expect_success '__git_get_config_variables' '
1962         cat >expect <<-EOF &&
1963         name-1
1964         name-2
1965         EOF
1966         test_config interesting.name-1 good &&
1967         test_config interesting.name-2 good &&
1968         test_config subsection.interesting.name-3 bad &&
1969         __git_get_config_variables interesting >actual &&
1970         test_cmp expect actual
1971 '
1972
1973 test_expect_success '__git_pretty_aliases' '
1974         cat >expect <<-EOF &&
1975         author
1976         hash
1977         EOF
1978         test_config pretty.author "%an %ae" &&
1979         test_config pretty.hash %H &&
1980         __git_pretty_aliases >actual &&
1981         test_cmp expect actual
1982 '
1983
1984 test_expect_success 'basic' '
1985         run_completion "git " &&
1986         # built-in
1987         grep -q "^add \$" out &&
1988         # script
1989         grep -q "^rebase \$" out &&
1990         # plumbing
1991         ! grep -q "^ls-files \$" out &&
1992
1993         run_completion "git r" &&
1994         ! grep -q -v "^r" out
1995 '
1996
1997 test_expect_success 'double dash "git" itself' '
1998         test_completion "git --" <<-\EOF
1999         --paginate Z
2000         --no-pager Z
2001         --git-dir=
2002         --bare Z
2003         --version Z
2004         --exec-path Z
2005         --exec-path=
2006         --html-path Z
2007         --man-path Z
2008         --info-path Z
2009         --work-tree=
2010         --namespace=
2011         --no-replace-objects Z
2012         --help Z
2013         EOF
2014 '
2015
2016 test_expect_success 'double dash "git checkout"' '
2017         test_completion "git checkout --" <<-\EOF
2018         --quiet Z
2019         --detach Z
2020         --track Z
2021         --orphan=Z
2022         --ours Z
2023         --theirs Z
2024         --merge Z
2025         --conflict=Z
2026         --patch Z
2027         --ignore-skip-worktree-bits Z
2028         --ignore-other-worktrees Z
2029         --recurse-submodules Z
2030         --progress Z
2031         --guess Z
2032         --no-guess Z
2033         --no-... Z
2034         --overlay Z
2035         --pathspec-file-nul Z
2036         --pathspec-from-file=Z
2037         EOF
2038 '
2039
2040 test_expect_success 'general options' '
2041         test_completion "git --ver" "--version " &&
2042         test_completion "git --hel" "--help " &&
2043         test_completion "git --exe" <<-\EOF &&
2044         --exec-path Z
2045         --exec-path=
2046         EOF
2047         test_completion "git --htm" "--html-path " &&
2048         test_completion "git --pag" "--paginate " &&
2049         test_completion "git --no-p" "--no-pager " &&
2050         test_completion "git --git" "--git-dir=" &&
2051         test_completion "git --wor" "--work-tree=" &&
2052         test_completion "git --nam" "--namespace=" &&
2053         test_completion "git --bar" "--bare " &&
2054         test_completion "git --inf" "--info-path " &&
2055         test_completion "git --no-r" "--no-replace-objects "
2056 '
2057
2058 test_expect_success 'general options plus command' '
2059         test_completion "git --version check" "checkout " &&
2060         test_completion "git --paginate check" "checkout " &&
2061         test_completion "git --git-dir=foo check" "checkout " &&
2062         test_completion "git --bare check" "checkout " &&
2063         test_completion "git --exec-path=foo check" "checkout " &&
2064         test_completion "git --html-path check" "checkout " &&
2065         test_completion "git --no-pager check" "checkout " &&
2066         test_completion "git --work-tree=foo check" "checkout " &&
2067         test_completion "git --namespace=foo check" "checkout " &&
2068         test_completion "git --paginate check" "checkout " &&
2069         test_completion "git --info-path check" "checkout " &&
2070         test_completion "git --no-replace-objects check" "checkout " &&
2071         test_completion "git --git-dir some/path check" "checkout " &&
2072         test_completion "git -c conf.var=value check" "checkout " &&
2073         test_completion "git -C some/path check" "checkout " &&
2074         test_completion "git --work-tree some/path check" "checkout " &&
2075         test_completion "git --namespace name/space check" "checkout "
2076 '
2077
2078 test_expect_success 'git --help completion' '
2079         test_completion "git --help ad" "add " &&
2080         test_completion "git --help core" "core-tutorial "
2081 '
2082
2083 test_expect_success 'completion.commands removes multiple commands' '
2084         test_config completion.commands "-cherry -mergetool" &&
2085         git --list-cmds=list-mainporcelain,list-complete,config >out &&
2086         ! grep -E "^(cherry|mergetool)$" out
2087 '
2088
2089 test_expect_success 'setup for integration tests' '
2090         echo content >file1 &&
2091         echo more >file2 &&
2092         git add file1 file2 &&
2093         git commit -m one &&
2094         git branch mybranch &&
2095         git tag mytag
2096 '
2097
2098 test_expect_success 'checkout completes ref names' '
2099         test_completion "git checkout m" <<-\EOF
2100         main Z
2101         mybranch Z
2102         mytag Z
2103         EOF
2104 '
2105
2106 test_expect_success 'git -C <path> checkout uses the right repo' '
2107         test_completion "git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b" <<-\EOF
2108         branch-in-other Z
2109         EOF
2110 '
2111
2112 test_expect_success 'show completes all refs' '
2113         test_completion "git show m" <<-\EOF
2114         main Z
2115         mybranch Z
2116         mytag Z
2117         EOF
2118 '
2119
2120 test_expect_success '<ref>: completes paths' '
2121         test_completion "git show mytag:f" <<-\EOF
2122         file1Z
2123         file2Z
2124         EOF
2125 '
2126
2127 test_expect_success 'complete tree filename with spaces' '
2128         echo content >"name with spaces" &&
2129         git add "name with spaces" &&
2130         git commit -m spaces &&
2131         test_completion "git show HEAD:nam" <<-\EOF
2132         name with spacesZ
2133         EOF
2134 '
2135
2136 test_expect_success 'complete tree filename with metacharacters' '
2137         echo content >"name with \${meta}" &&
2138         git add "name with \${meta}" &&
2139         git commit -m meta &&
2140         test_completion "git show HEAD:nam" <<-\EOF
2141         name with ${meta}Z
2142         name with spacesZ
2143         EOF
2144 '
2145
2146 test_expect_success PERL 'send-email' '
2147         test_completion "git send-email --cov" <<-\EOF &&
2148         --cover-from-description=Z
2149         --cover-letter Z
2150         EOF
2151         test_completion "git send-email ma" "main "
2152 '
2153
2154 test_expect_success 'complete files' '
2155         git init tmp && cd tmp &&
2156         test_when_finished "cd .. && rm -rf tmp" &&
2157
2158         echo "expected" > .gitignore &&
2159         echo "out" >> .gitignore &&
2160         echo "out_sorted" >> .gitignore &&
2161
2162         git add .gitignore &&
2163         test_completion "git commit " ".gitignore" &&
2164
2165         git commit -m ignore &&
2166
2167         touch new &&
2168         test_completion "git add " "new" &&
2169
2170         git add new &&
2171         git commit -a -m new &&
2172         test_completion "git add " "" &&
2173
2174         git mv new modified &&
2175         echo modify > modified &&
2176         test_completion "git add " "modified" &&
2177
2178         mkdir -p some/deep &&
2179         touch some/deep/path &&
2180         test_completion "git add some/" "some/deep" &&
2181         git clean -f some &&
2182
2183         touch untracked &&
2184
2185         : TODO .gitignore should not be here &&
2186         test_completion "git rm " <<-\EOF &&
2187         .gitignore
2188         modified
2189         EOF
2190
2191         test_completion "git clean " "untracked" &&
2192
2193         : TODO .gitignore should not be here &&
2194         test_completion "git mv " <<-\EOF &&
2195         .gitignore
2196         modified
2197         EOF
2198
2199         mkdir dir &&
2200         touch dir/file-in-dir &&
2201         git add dir/file-in-dir &&
2202         git commit -m dir &&
2203
2204         mkdir untracked-dir &&
2205
2206         : TODO .gitignore should not be here &&
2207         test_completion "git mv modified " <<-\EOF &&
2208         .gitignore
2209         dir
2210         modified
2211         untracked
2212         untracked-dir
2213         EOF
2214
2215         test_completion "git commit " "modified" &&
2216
2217         : TODO .gitignore should not be here &&
2218         test_completion "git ls-files " <<-\EOF &&
2219         .gitignore
2220         dir
2221         modified
2222         EOF
2223
2224         touch momified &&
2225         test_completion "git add mom" "momified"
2226 '
2227
2228 test_expect_success "simple alias" '
2229         test_config alias.co checkout &&
2230         test_completion "git co m" <<-\EOF
2231         main Z
2232         mybranch Z
2233         mytag Z
2234         EOF
2235 '
2236
2237 test_expect_success "recursive alias" '
2238         test_config alias.co checkout &&
2239         test_config alias.cod "co --detached" &&
2240         test_completion "git cod m" <<-\EOF
2241         main Z
2242         mybranch Z
2243         mytag Z
2244         EOF
2245 '
2246
2247 test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
2248         test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
2249         test_completion "git co m" <<-\EOF
2250         main Z
2251         mybranch Z
2252         mytag Z
2253         EOF
2254 '
2255
2256 test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
2257         test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
2258         test_completion "git co m" <<-\EOF
2259         main Z
2260         mybranch Z
2261         mytag Z
2262         EOF
2263 '
2264
2265 test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
2266         test_config alias.co "!f() { : git checkout ; if ... } f" &&
2267         test_completion "git co m" <<-\EOF
2268         main Z
2269         mybranch Z
2270         mytag Z
2271         EOF
2272 '
2273
2274 test_expect_success 'completion without explicit _git_xxx function' '
2275         test_completion "git version --" <<-\EOF
2276         --build-options Z
2277         --no-build-options Z
2278         EOF
2279 '
2280
2281 test_expect_failure 'complete with tilde expansion' '
2282         git init tmp && cd tmp &&
2283         test_when_finished "cd .. && rm -rf tmp" &&
2284
2285         touch ~/tmp/file &&
2286
2287         test_completion "git add ~/tmp/" "~/tmp/file"
2288 '
2289
2290 test_expect_success 'setup other remote for remote reference completion' '
2291         git remote add other otherrepo &&
2292         git fetch other
2293 '
2294
2295 for flag in -d --delete
2296 do
2297         test_expect_success "__git_complete_remote_or_refspec - push $flag other" '
2298                 sed -e "s/Z$//" >expected <<-EOF &&
2299                 main-in-other Z
2300                 EOF
2301                 (
2302                         words=(git push '$flag' other ma) &&
2303                         cword=${#words[@]} cur=${words[cword-1]} &&
2304                         __git_cmd_idx=1 &&
2305                         __git_complete_remote_or_refspec &&
2306                         print_comp
2307                 ) &&
2308                 test_cmp expected out
2309         '
2310
2311         test_expect_failure "__git_complete_remote_or_refspec - push other $flag" '
2312                 sed -e "s/Z$//" >expected <<-EOF &&
2313                 main-in-other Z
2314                 EOF
2315                 (
2316                         words=(git push other '$flag' ma) &&
2317                         cword=${#words[@]} cur=${words[cword-1]} &&
2318                         __git_cmd_idx=1 &&
2319                         __git_complete_remote_or_refspec &&
2320                         print_comp
2321                 ) &&
2322                 test_cmp expected out
2323         '
2324 done
2325
2326 test_expect_success 'git config - section' '
2327         test_completion "git config br" <<-\EOF
2328         branch.Z
2329         browser.Z
2330         EOF
2331 '
2332
2333 test_expect_success 'git config - variable name' '
2334         test_completion "git config log.d" <<-\EOF
2335         log.date Z
2336         log.decorate Z
2337         log.diffMerges Z
2338         EOF
2339 '
2340
2341 test_expect_success 'git config - value' '
2342         test_completion "git config color.pager " <<-\EOF
2343         false Z
2344         true Z
2345         EOF
2346 '
2347
2348 test_expect_success 'git -c - section' '
2349         test_completion "git -c br" <<-\EOF
2350         branch.Z
2351         browser.Z
2352         EOF
2353 '
2354
2355 test_expect_success 'git -c - variable name' '
2356         test_completion "git -c log.d" <<-\EOF
2357         log.date=Z
2358         log.decorate=Z
2359         log.diffMerges=Z
2360         EOF
2361 '
2362
2363 test_expect_success 'git -c - value' '
2364         test_completion "git -c color.pager=" <<-\EOF
2365         false Z
2366         true Z
2367         EOF
2368 '
2369
2370 test_expect_success 'git clone --config= - section' '
2371         test_completion "git clone --config=br" <<-\EOF
2372         branch.Z
2373         browser.Z
2374         EOF
2375 '
2376
2377 test_expect_success 'git clone --config= - variable name' '
2378         test_completion "git clone --config=log.d" <<-\EOF
2379         log.date=Z
2380         log.decorate=Z
2381         log.diffMerges=Z
2382         EOF
2383 '
2384
2385 test_expect_success 'git clone --config= - value' '
2386         test_completion "git clone --config=color.pager=" <<-\EOF
2387         false Z
2388         true Z
2389         EOF
2390 '
2391
2392 test_expect_success 'options with value' '
2393         test_completion "git merge -X diff-algorithm=" <<-\EOF
2394
2395         EOF
2396 '
2397
2398 test_expect_success 'sourcing the completion script clears cached commands' '
2399         __git_compute_all_commands &&
2400         verbose test -n "$__git_all_commands" &&
2401         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
2402         verbose test -z "$__git_all_commands"
2403 '
2404
2405 test_expect_success 'sourcing the completion script clears cached merge strategies' '
2406         __git_compute_merge_strategies &&
2407         verbose test -n "$__git_merge_strategies" &&
2408         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
2409         verbose test -z "$__git_merge_strategies"
2410 '
2411
2412 test_expect_success 'sourcing the completion script clears cached --options' '
2413         __gitcomp_builtin checkout &&
2414         verbose test -n "$__gitcomp_builtin_checkout" &&
2415         __gitcomp_builtin notes_edit &&
2416         verbose test -n "$__gitcomp_builtin_notes_edit" &&
2417         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
2418         verbose test -z "$__gitcomp_builtin_checkout" &&
2419         verbose test -z "$__gitcomp_builtin_notes_edit"
2420 '
2421
2422 test_expect_success '__git_complete' '
2423         unset -f __git_wrap__git_main &&
2424
2425         __git_complete foo __git_main &&
2426         __git_have_func __git_wrap__git_main &&
2427         unset -f __git_wrap__git_main &&
2428
2429         __git_complete gf _git_fetch &&
2430         __git_have_func __git_wrap_git_fetch &&
2431
2432         __git_complete foo git &&
2433         __git_have_func __git_wrap__git_main &&
2434         unset -f __git_wrap__git_main &&
2435
2436         __git_complete gd git_diff &&
2437         __git_have_func __git_wrap_git_diff &&
2438
2439         test_must_fail __git_complete ga missing
2440 '
2441
2442 test_done