advice: keep config name in camelCase in advice_config[]
[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 these lists:
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_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files'
34 GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch'
35
36 . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
37
38 # We don't need this function to actually join words or do anything special.
39 # Also, it's cleaner to avoid touching bash's internal completion variables.
40 # So let's override it with a minimal version for testing purposes.
41 _get_comp_words_by_ref ()
42 {
43         while [ $# -gt 0 ]; do
44                 case "$1" in
45                 cur)
46                         cur=${_words[_cword]}
47                         ;;
48                 prev)
49                         prev=${_words[_cword-1]}
50                         ;;
51                 words)
52                         words=("${_words[@]}")
53                         ;;
54                 cword)
55                         cword=$_cword
56                         ;;
57                 esac
58                 shift
59         done
60 }
61
62 print_comp ()
63 {
64         local IFS=$'\n'
65         echo "${COMPREPLY[*]}" > out
66 }
67
68 run_completion ()
69 {
70         local -a COMPREPLY _words
71         local _cword
72         _words=( $1 )
73         test "${1: -1}" = ' ' && _words[${#_words[@]}+1]=''
74         (( _cword = ${#_words[@]} - 1 ))
75         __git_wrap__git_main && print_comp
76 }
77
78 # Test high-level completion
79 # Arguments are:
80 # 1: typed text so far (cur)
81 # 2: expected completion
82 test_completion ()
83 {
84         if test $# -gt 1
85         then
86                 printf '%s\n' "$2" >expected
87         else
88                 sed -e 's/Z$//' >expected
89         fi &&
90         run_completion "$1" &&
91         test_cmp expected out
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 test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
405         sed -e "s/Z$//g" >expected <<-EOF &&
406         with-trailing-space Z
407         without-trailing-spaceZ
408         --option Z
409         --option=Z
410         $invalid_variable_name Z
411         EOF
412         (
413                 cur=should_be_ignored &&
414                 __gitcomp_direct "$(cat expected)" &&
415                 print_comp
416         ) &&
417         test_cmp expected out
418 '
419
420 test_expect_success '__gitcomp - trailing space - options' '
421         test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message=
422                 --reset-author" <<-EOF
423         --reuse-message=Z
424         --reedit-message=Z
425         --reset-author Z
426         EOF
427 '
428
429 test_expect_success '__gitcomp - trailing space - config keys' '
430         test_gitcomp "br" "branch. branch.autosetupmerge
431                 branch.autosetuprebase browser." <<-\EOF
432         branch.Z
433         branch.autosetupmerge Z
434         branch.autosetuprebase Z
435         browser.Z
436         EOF
437 '
438
439 test_expect_success '__gitcomp - option parameter' '
440         test_gitcomp "--strategy=re" "octopus ours recursive resolve subtree" \
441                 "" "re" <<-\EOF
442         recursive Z
443         resolve Z
444         EOF
445 '
446
447 test_expect_success '__gitcomp - prefix' '
448         test_gitcomp "branch.me" "remote merge mergeoptions rebase" \
449                 "branch.maint." "me" <<-\EOF
450         branch.maint.merge Z
451         branch.maint.mergeoptions Z
452         EOF
453 '
454
455 test_expect_success '__gitcomp - suffix' '
456         test_gitcomp "branch.me" "master maint next pu" "branch." \
457                 "ma" "." <<-\EOF
458         branch.master.Z
459         branch.maint.Z
460         EOF
461 '
462
463 test_expect_success '__gitcomp - doesnt fail because of invalid variable name' '
464         __gitcomp "$invalid_variable_name"
465 '
466
467 read -r -d "" refs <<-\EOF
468 maint
469 master
470 next
471 pu
472 EOF
473
474 test_expect_success '__gitcomp_nl - trailing space' '
475         test_gitcomp_nl "m" "$refs" <<-EOF
476         maint Z
477         master Z
478         EOF
479 '
480
481 test_expect_success '__gitcomp_nl - prefix' '
482         test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF
483         --fixup=maint Z
484         --fixup=master Z
485         EOF
486 '
487
488 test_expect_success '__gitcomp_nl - suffix' '
489         test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF
490         branch.maint.Z
491         branch.master.Z
492         EOF
493 '
494
495 test_expect_success '__gitcomp_nl - no suffix' '
496         test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF
497         maintZ
498         masterZ
499         EOF
500 '
501
502 test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' '
503         __gitcomp_nl "$invalid_variable_name"
504 '
505
506 test_expect_success '__git_remotes - list remotes from $GIT_DIR/remotes and from config file' '
507         cat >expect <<-EOF &&
508         remote_from_file_1
509         remote_from_file_2
510         remote_in_config_1
511         remote_in_config_2
512         EOF
513         test_when_finished "rm -rf .git/remotes" &&
514         mkdir -p .git/remotes &&
515         >.git/remotes/remote_from_file_1 &&
516         >.git/remotes/remote_from_file_2 &&
517         test_when_finished "git remote remove remote_in_config_1" &&
518         git remote add remote_in_config_1 git://remote_1 &&
519         test_when_finished "git remote remove remote_in_config_2" &&
520         git remote add remote_in_config_2 git://remote_2 &&
521         (
522                 __git_remotes >actual
523         ) &&
524         test_cmp expect actual
525 '
526
527 test_expect_success '__git_is_configured_remote' '
528         test_when_finished "git remote remove remote_1" &&
529         git remote add remote_1 git://remote_1 &&
530         test_when_finished "git remote remove remote_2" &&
531         git remote add remote_2 git://remote_2 &&
532         (
533                 verbose __git_is_configured_remote remote_2 &&
534                 test_must_fail __git_is_configured_remote non-existent
535         )
536 '
537
538 test_expect_success 'setup for ref completion' '
539         git commit --allow-empty -m initial &&
540         git branch matching-branch &&
541         git tag matching-tag &&
542         (
543                 cd otherrepo &&
544                 git commit --allow-empty -m initial &&
545                 git branch -m master master-in-other &&
546                 git branch branch-in-other &&
547                 git tag tag-in-other
548         ) &&
549         git remote add other "$ROOT/otherrepo/.git" &&
550         git fetch --no-tags other &&
551         rm -f .git/FETCH_HEAD &&
552         git init thirdrepo
553 '
554
555 test_expect_success '__git_refs - simple' '
556         cat >expected <<-EOF &&
557         HEAD
558         master
559         matching-branch
560         other/branch-in-other
561         other/master-in-other
562         matching-tag
563         EOF
564         (
565                 cur= &&
566                 __git_refs >"$actual"
567         ) &&
568         test_cmp expected "$actual"
569 '
570
571 test_expect_success '__git_refs - full refs' '
572         cat >expected <<-EOF &&
573         refs/heads/master
574         refs/heads/matching-branch
575         refs/remotes/other/branch-in-other
576         refs/remotes/other/master-in-other
577         refs/tags/matching-tag
578         EOF
579         (
580                 cur=refs/heads/ &&
581                 __git_refs >"$actual"
582         ) &&
583         test_cmp expected "$actual"
584 '
585
586 test_expect_success '__git_refs - repo given on the command line' '
587         cat >expected <<-EOF &&
588         HEAD
589         branch-in-other
590         master-in-other
591         tag-in-other
592         EOF
593         (
594                 __git_dir="$ROOT/otherrepo/.git" &&
595                 cur= &&
596                 __git_refs >"$actual"
597         ) &&
598         test_cmp expected "$actual"
599 '
600
601 test_expect_success '__git_refs - remote on local file system' '
602         cat >expected <<-EOF &&
603         HEAD
604         branch-in-other
605         master-in-other
606         tag-in-other
607         EOF
608         (
609                 cur= &&
610                 __git_refs otherrepo >"$actual"
611         ) &&
612         test_cmp expected "$actual"
613 '
614
615 test_expect_success '__git_refs - remote on local file system - full refs' '
616         cat >expected <<-EOF &&
617         refs/heads/branch-in-other
618         refs/heads/master-in-other
619         refs/tags/tag-in-other
620         EOF
621         (
622                 cur=refs/ &&
623                 __git_refs otherrepo >"$actual"
624         ) &&
625         test_cmp expected "$actual"
626 '
627
628 test_expect_success '__git_refs - configured remote' '
629         cat >expected <<-EOF &&
630         HEAD
631         branch-in-other
632         master-in-other
633         EOF
634         (
635                 cur= &&
636                 __git_refs other >"$actual"
637         ) &&
638         test_cmp expected "$actual"
639 '
640
641 test_expect_success '__git_refs - configured remote - full refs' '
642         cat >expected <<-EOF &&
643         HEAD
644         refs/heads/branch-in-other
645         refs/heads/master-in-other
646         refs/tags/tag-in-other
647         EOF
648         (
649                 cur=refs/ &&
650                 __git_refs other >"$actual"
651         ) &&
652         test_cmp expected "$actual"
653 '
654
655 test_expect_success '__git_refs - configured remote - repo given on the command line' '
656         cat >expected <<-EOF &&
657         HEAD
658         branch-in-other
659         master-in-other
660         EOF
661         (
662                 cd thirdrepo &&
663                 __git_dir="$ROOT/.git" &&
664                 cur= &&
665                 __git_refs other >"$actual"
666         ) &&
667         test_cmp expected "$actual"
668 '
669
670 test_expect_success '__git_refs - configured remote - full refs - repo given on the command line' '
671         cat >expected <<-EOF &&
672         HEAD
673         refs/heads/branch-in-other
674         refs/heads/master-in-other
675         refs/tags/tag-in-other
676         EOF
677         (
678                 cd thirdrepo &&
679                 __git_dir="$ROOT/.git" &&
680                 cur=refs/ &&
681                 __git_refs other >"$actual"
682         ) &&
683         test_cmp expected "$actual"
684 '
685
686 test_expect_success '__git_refs - configured remote - remote name matches a directory' '
687         cat >expected <<-EOF &&
688         HEAD
689         branch-in-other
690         master-in-other
691         EOF
692         mkdir other &&
693         test_when_finished "rm -rf other" &&
694         (
695                 cur= &&
696                 __git_refs other >"$actual"
697         ) &&
698         test_cmp expected "$actual"
699 '
700
701 test_expect_success '__git_refs - URL remote' '
702         cat >expected <<-EOF &&
703         HEAD
704         branch-in-other
705         master-in-other
706         tag-in-other
707         EOF
708         (
709                 cur= &&
710                 __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
711         ) &&
712         test_cmp expected "$actual"
713 '
714
715 test_expect_success '__git_refs - URL remote - full refs' '
716         cat >expected <<-EOF &&
717         HEAD
718         refs/heads/branch-in-other
719         refs/heads/master-in-other
720         refs/tags/tag-in-other
721         EOF
722         (
723                 cur=refs/ &&
724                 __git_refs "file://$ROOT/otherrepo/.git" >"$actual"
725         ) &&
726         test_cmp expected "$actual"
727 '
728
729 test_expect_success '__git_refs - non-existing remote' '
730         (
731                 cur= &&
732                 __git_refs non-existing >"$actual"
733         ) &&
734         test_must_be_empty "$actual"
735 '
736
737 test_expect_success '__git_refs - non-existing remote - full refs' '
738         (
739                 cur=refs/ &&
740                 __git_refs non-existing >"$actual"
741         ) &&
742         test_must_be_empty "$actual"
743 '
744
745 test_expect_success '__git_refs - non-existing URL remote' '
746         (
747                 cur= &&
748                 __git_refs "file://$ROOT/non-existing" >"$actual"
749         ) &&
750         test_must_be_empty "$actual"
751 '
752
753 test_expect_success '__git_refs - non-existing URL remote - full refs' '
754         (
755                 cur=refs/ &&
756                 __git_refs "file://$ROOT/non-existing" >"$actual"
757         ) &&
758         test_must_be_empty "$actual"
759 '
760
761 test_expect_success '__git_refs - not in a git repository' '
762         (
763                 GIT_CEILING_DIRECTORIES="$ROOT" &&
764                 export GIT_CEILING_DIRECTORIES &&
765                 cd subdir &&
766                 cur= &&
767                 __git_refs >"$actual"
768         ) &&
769         test_must_be_empty "$actual"
770 '
771
772 test_expect_success '__git_refs - unique remote branches for git checkout DWIMery' '
773         cat >expected <<-EOF &&
774         HEAD
775         master
776         matching-branch
777         other/ambiguous
778         other/branch-in-other
779         other/master-in-other
780         remote/ambiguous
781         remote/branch-in-remote
782         matching-tag
783         branch-in-other
784         branch-in-remote
785         master-in-other
786         EOF
787         for remote_ref in refs/remotes/other/ambiguous \
788                 refs/remotes/remote/ambiguous \
789                 refs/remotes/remote/branch-in-remote
790         do
791                 git update-ref $remote_ref master &&
792                 test_when_finished "git update-ref -d $remote_ref"
793         done &&
794         (
795                 cur= &&
796                 __git_refs "" 1 >"$actual"
797         ) &&
798         test_cmp expected "$actual"
799 '
800
801 test_expect_success '__git_refs - after --opt=' '
802         cat >expected <<-EOF &&
803         HEAD
804         master
805         matching-branch
806         other/branch-in-other
807         other/master-in-other
808         matching-tag
809         EOF
810         (
811                 cur="--opt=" &&
812                 __git_refs "" "" "" "" >"$actual"
813         ) &&
814         test_cmp expected "$actual"
815 '
816
817 test_expect_success '__git_refs - after --opt= - full refs' '
818         cat >expected <<-EOF &&
819         refs/heads/master
820         refs/heads/matching-branch
821         refs/remotes/other/branch-in-other
822         refs/remotes/other/master-in-other
823         refs/tags/matching-tag
824         EOF
825         (
826                 cur="--opt=refs/" &&
827                 __git_refs "" "" "" refs/ >"$actual"
828         ) &&
829         test_cmp expected "$actual"
830 '
831
832 test_expect_success '__git refs - exluding refs' '
833         cat >expected <<-EOF &&
834         ^HEAD
835         ^master
836         ^matching-branch
837         ^other/branch-in-other
838         ^other/master-in-other
839         ^matching-tag
840         EOF
841         (
842                 cur=^ &&
843                 __git_refs >"$actual"
844         ) &&
845         test_cmp expected "$actual"
846 '
847
848 test_expect_success '__git refs - exluding full refs' '
849         cat >expected <<-EOF &&
850         ^refs/heads/master
851         ^refs/heads/matching-branch
852         ^refs/remotes/other/branch-in-other
853         ^refs/remotes/other/master-in-other
854         ^refs/tags/matching-tag
855         EOF
856         (
857                 cur=^refs/ &&
858                 __git_refs >"$actual"
859         ) &&
860         test_cmp expected "$actual"
861 '
862
863 test_expect_success 'setup for filtering matching refs' '
864         git branch matching/branch &&
865         git tag matching/tag &&
866         git -C otherrepo branch matching/branch-in-other &&
867         git fetch --no-tags other &&
868         rm -f .git/FETCH_HEAD
869 '
870
871 test_expect_success '__git_refs - dont filter refs unless told so' '
872         cat >expected <<-EOF &&
873         HEAD
874         master
875         matching-branch
876         matching/branch
877         other/branch-in-other
878         other/master-in-other
879         other/matching/branch-in-other
880         matching-tag
881         matching/tag
882         EOF
883         (
884                 cur=master &&
885                 __git_refs >"$actual"
886         ) &&
887         test_cmp expected "$actual"
888 '
889
890 test_expect_success '__git_refs - only matching refs' '
891         cat >expected <<-EOF &&
892         matching-branch
893         matching/branch
894         matching-tag
895         matching/tag
896         EOF
897         (
898                 cur=mat &&
899                 __git_refs "" "" "" "$cur" >"$actual"
900         ) &&
901         test_cmp expected "$actual"
902 '
903
904 test_expect_success '__git_refs - only matching refs - full refs' '
905         cat >expected <<-EOF &&
906         refs/heads/matching-branch
907         refs/heads/matching/branch
908         EOF
909         (
910                 cur=refs/heads/mat &&
911                 __git_refs "" "" "" "$cur" >"$actual"
912         ) &&
913         test_cmp expected "$actual"
914 '
915
916 test_expect_success '__git_refs - only matching refs - remote on local file system' '
917         cat >expected <<-EOF &&
918         master-in-other
919         matching/branch-in-other
920         EOF
921         (
922                 cur=ma &&
923                 __git_refs otherrepo "" "" "$cur" >"$actual"
924         ) &&
925         test_cmp expected "$actual"
926 '
927
928 test_expect_success '__git_refs - only matching refs - configured remote' '
929         cat >expected <<-EOF &&
930         master-in-other
931         matching/branch-in-other
932         EOF
933         (
934                 cur=ma &&
935                 __git_refs other "" "" "$cur" >"$actual"
936         ) &&
937         test_cmp expected "$actual"
938 '
939
940 test_expect_success '__git_refs - only matching refs - remote - full refs' '
941         cat >expected <<-EOF &&
942         refs/heads/master-in-other
943         refs/heads/matching/branch-in-other
944         EOF
945         (
946                 cur=refs/heads/ma &&
947                 __git_refs other "" "" "$cur" >"$actual"
948         ) &&
949         test_cmp expected "$actual"
950 '
951
952 test_expect_success '__git_refs - only matching refs - checkout DWIMery' '
953         cat >expected <<-EOF &&
954         matching-branch
955         matching/branch
956         matching-tag
957         matching/tag
958         matching/branch-in-other
959         EOF
960         for remote_ref in refs/remotes/other/ambiguous \
961                 refs/remotes/remote/ambiguous \
962                 refs/remotes/remote/branch-in-remote
963         do
964                 git update-ref $remote_ref master &&
965                 test_when_finished "git update-ref -d $remote_ref"
966         done &&
967         (
968                 cur=mat &&
969                 __git_refs "" 1 "" "$cur" >"$actual"
970         ) &&
971         test_cmp expected "$actual"
972 '
973
974 test_expect_success 'teardown after filtering matching refs' '
975         git branch -d matching/branch &&
976         git tag -d matching/tag &&
977         git update-ref -d refs/remotes/other/matching/branch-in-other &&
978         git -C otherrepo branch -D matching/branch-in-other
979 '
980
981 test_expect_success '__git_refs - for-each-ref format specifiers in prefix' '
982         cat >expected <<-EOF &&
983         evil-%%-%42-%(refname)..master
984         EOF
985         (
986                 cur="evil-%%-%42-%(refname)..mas" &&
987                 __git_refs "" "" "evil-%%-%42-%(refname).." mas >"$actual"
988         ) &&
989         test_cmp expected "$actual"
990 '
991
992 test_expect_success '__git_complete_refs - simple' '
993         sed -e "s/Z$//" >expected <<-EOF &&
994         HEAD Z
995         master Z
996         matching-branch Z
997         other/branch-in-other Z
998         other/master-in-other Z
999         matching-tag Z
1000         EOF
1001         (
1002                 cur= &&
1003                 __git_complete_refs &&
1004                 print_comp
1005         ) &&
1006         test_cmp expected out
1007 '
1008
1009 test_expect_success '__git_complete_refs - matching' '
1010         sed -e "s/Z$//" >expected <<-EOF &&
1011         matching-branch Z
1012         matching-tag Z
1013         EOF
1014         (
1015                 cur=mat &&
1016                 __git_complete_refs &&
1017                 print_comp
1018         ) &&
1019         test_cmp expected out
1020 '
1021
1022 test_expect_success '__git_complete_refs - remote' '
1023         sed -e "s/Z$//" >expected <<-EOF &&
1024         HEAD Z
1025         branch-in-other Z
1026         master-in-other Z
1027         EOF
1028         (
1029                 cur=
1030                 __git_complete_refs --remote=other &&
1031                 print_comp
1032         ) &&
1033         test_cmp expected out
1034 '
1035
1036 test_expect_success '__git_complete_refs - track' '
1037         sed -e "s/Z$//" >expected <<-EOF &&
1038         HEAD Z
1039         master Z
1040         matching-branch Z
1041         other/branch-in-other Z
1042         other/master-in-other Z
1043         matching-tag Z
1044         branch-in-other Z
1045         master-in-other Z
1046         EOF
1047         (
1048                 cur=
1049                 __git_complete_refs --track &&
1050                 print_comp
1051         ) &&
1052         test_cmp expected out
1053 '
1054
1055 test_expect_success '__git_complete_refs - current word' '
1056         sed -e "s/Z$//" >expected <<-EOF &&
1057         matching-branch Z
1058         matching-tag Z
1059         EOF
1060         (
1061                 cur="--option=mat" &&
1062                 __git_complete_refs --cur="${cur#*=}" &&
1063                 print_comp
1064         ) &&
1065         test_cmp expected out
1066 '
1067
1068 test_expect_success '__git_complete_refs - prefix' '
1069         sed -e "s/Z$//" >expected <<-EOF &&
1070         v1.0..matching-branch Z
1071         v1.0..matching-tag Z
1072         EOF
1073         (
1074                 cur=v1.0..mat &&
1075                 __git_complete_refs --pfx=v1.0.. --cur=mat &&
1076                 print_comp
1077         ) &&
1078         test_cmp expected out
1079 '
1080
1081 test_expect_success '__git_complete_refs - suffix' '
1082         cat >expected <<-EOF &&
1083         HEAD.
1084         master.
1085         matching-branch.
1086         other/branch-in-other.
1087         other/master-in-other.
1088         matching-tag.
1089         EOF
1090         (
1091                 cur= &&
1092                 __git_complete_refs --sfx=. &&
1093                 print_comp
1094         ) &&
1095         test_cmp expected out
1096 '
1097
1098 test_expect_success '__git_complete_fetch_refspecs - simple' '
1099         sed -e "s/Z$//" >expected <<-EOF &&
1100         HEAD:HEAD Z
1101         branch-in-other:branch-in-other Z
1102         master-in-other:master-in-other Z
1103         EOF
1104         (
1105                 cur= &&
1106                 __git_complete_fetch_refspecs other &&
1107                 print_comp
1108         ) &&
1109         test_cmp expected out
1110 '
1111
1112 test_expect_success '__git_complete_fetch_refspecs - matching' '
1113         sed -e "s/Z$//" >expected <<-EOF &&
1114         branch-in-other:branch-in-other Z
1115         EOF
1116         (
1117                 cur=br &&
1118                 __git_complete_fetch_refspecs other "" br &&
1119                 print_comp
1120         ) &&
1121         test_cmp expected out
1122 '
1123
1124 test_expect_success '__git_complete_fetch_refspecs - prefix' '
1125         sed -e "s/Z$//" >expected <<-EOF &&
1126         +HEAD:HEAD Z
1127         +branch-in-other:branch-in-other Z
1128         +master-in-other:master-in-other Z
1129         EOF
1130         (
1131                 cur="+" &&
1132                 __git_complete_fetch_refspecs other "+" ""  &&
1133                 print_comp
1134         ) &&
1135         test_cmp expected out
1136 '
1137
1138 test_expect_success '__git_complete_fetch_refspecs - fully qualified' '
1139         sed -e "s/Z$//" >expected <<-EOF &&
1140         refs/heads/branch-in-other:refs/heads/branch-in-other Z
1141         refs/heads/master-in-other:refs/heads/master-in-other Z
1142         refs/tags/tag-in-other:refs/tags/tag-in-other Z
1143         EOF
1144         (
1145                 cur=refs/ &&
1146                 __git_complete_fetch_refspecs other "" refs/ &&
1147                 print_comp
1148         ) &&
1149         test_cmp expected out
1150 '
1151
1152 test_expect_success '__git_complete_fetch_refspecs - fully qualified & prefix' '
1153         sed -e "s/Z$//" >expected <<-EOF &&
1154         +refs/heads/branch-in-other:refs/heads/branch-in-other Z
1155         +refs/heads/master-in-other:refs/heads/master-in-other Z
1156         +refs/tags/tag-in-other:refs/tags/tag-in-other Z
1157         EOF
1158         (
1159                 cur=+refs/ &&
1160                 __git_complete_fetch_refspecs other + refs/ &&
1161                 print_comp
1162         ) &&
1163         test_cmp expected out
1164 '
1165
1166 test_expect_success 'teardown after ref completion' '
1167         git branch -d matching-branch &&
1168         git tag -d matching-tag &&
1169         git remote remove other
1170 '
1171
1172 test_expect_success '__git_get_config_variables' '
1173         cat >expect <<-EOF &&
1174         name-1
1175         name-2
1176         EOF
1177         test_config interesting.name-1 good &&
1178         test_config interesting.name-2 good &&
1179         test_config subsection.interesting.name-3 bad &&
1180         __git_get_config_variables interesting >actual &&
1181         test_cmp expect actual
1182 '
1183
1184 test_expect_success '__git_pretty_aliases' '
1185         cat >expect <<-EOF &&
1186         author
1187         hash
1188         EOF
1189         test_config pretty.author "%an %ae" &&
1190         test_config pretty.hash %H &&
1191         __git_pretty_aliases >actual &&
1192         test_cmp expect actual
1193 '
1194
1195 test_expect_success 'basic' '
1196         run_completion "git " &&
1197         # built-in
1198         grep -q "^add \$" out &&
1199         # script
1200         grep -q "^filter-branch \$" out &&
1201         # plumbing
1202         ! grep -q "^ls-files \$" out &&
1203
1204         run_completion "git f" &&
1205         ! grep -q -v "^f" out
1206 '
1207
1208 test_expect_success 'double dash "git" itself' '
1209         test_completion "git --" <<-\EOF
1210         --paginate Z
1211         --no-pager Z
1212         --git-dir=
1213         --bare Z
1214         --version Z
1215         --exec-path Z
1216         --exec-path=
1217         --html-path Z
1218         --man-path Z
1219         --info-path Z
1220         --work-tree=
1221         --namespace=
1222         --no-replace-objects Z
1223         --help Z
1224         EOF
1225 '
1226
1227 test_expect_success 'double dash "git checkout"' '
1228         test_completion "git checkout --" <<-\EOF
1229         --quiet Z
1230         --detach Z
1231         --track Z
1232         --orphan=Z
1233         --ours Z
1234         --theirs Z
1235         --merge Z
1236         --conflict=Z
1237         --patch Z
1238         --ignore-skip-worktree-bits Z
1239         --ignore-other-worktrees Z
1240         --recurse-submodules Z
1241         --progress Z
1242         --no-track Z
1243         --no-recurse-submodules Z
1244         EOF
1245 '
1246
1247 test_expect_success 'general options' '
1248         test_completion "git --ver" "--version " &&
1249         test_completion "git --hel" "--help " &&
1250         test_completion "git --exe" <<-\EOF &&
1251         --exec-path Z
1252         --exec-path=
1253         EOF
1254         test_completion "git --htm" "--html-path " &&
1255         test_completion "git --pag" "--paginate " &&
1256         test_completion "git --no-p" "--no-pager " &&
1257         test_completion "git --git" "--git-dir=" &&
1258         test_completion "git --wor" "--work-tree=" &&
1259         test_completion "git --nam" "--namespace=" &&
1260         test_completion "git --bar" "--bare " &&
1261         test_completion "git --inf" "--info-path " &&
1262         test_completion "git --no-r" "--no-replace-objects "
1263 '
1264
1265 test_expect_success 'general options plus command' '
1266         test_completion "git --version check" "checkout " &&
1267         test_completion "git --paginate check" "checkout " &&
1268         test_completion "git --git-dir=foo check" "checkout " &&
1269         test_completion "git --bare check" "checkout " &&
1270         test_completion "git --exec-path=foo check" "checkout " &&
1271         test_completion "git --html-path check" "checkout " &&
1272         test_completion "git --no-pager check" "checkout " &&
1273         test_completion "git --work-tree=foo check" "checkout " &&
1274         test_completion "git --namespace=foo check" "checkout " &&
1275         test_completion "git --paginate check" "checkout " &&
1276         test_completion "git --info-path check" "checkout " &&
1277         test_completion "git --no-replace-objects check" "checkout " &&
1278         test_completion "git --git-dir some/path check" "checkout " &&
1279         test_completion "git -c conf.var=value check" "checkout " &&
1280         test_completion "git -C some/path check" "checkout " &&
1281         test_completion "git --work-tree some/path check" "checkout " &&
1282         test_completion "git --namespace name/space check" "checkout "
1283 '
1284
1285 test_expect_success 'git --help completion' '
1286         test_completion "git --help ad" "add " &&
1287         test_completion "git --help core" "core-tutorial "
1288 '
1289
1290 test_expect_success 'setup for integration tests' '
1291         echo content >file1 &&
1292         echo more >file2 &&
1293         git add file1 file2 &&
1294         git commit -m one &&
1295         git branch mybranch &&
1296         git tag mytag
1297 '
1298
1299 test_expect_success 'checkout completes ref names' '
1300         test_completion "git checkout m" <<-\EOF
1301         master Z
1302         mybranch Z
1303         mytag Z
1304         EOF
1305 '
1306
1307 test_expect_success 'git -C <path> checkout uses the right repo' '
1308         test_completion "git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b" <<-\EOF
1309         branch-in-other Z
1310         EOF
1311 '
1312
1313 test_expect_success 'show completes all refs' '
1314         test_completion "git show m" <<-\EOF
1315         master Z
1316         mybranch Z
1317         mytag Z
1318         EOF
1319 '
1320
1321 test_expect_success '<ref>: completes paths' '
1322         test_completion "git show mytag:f" <<-\EOF
1323         file1 Z
1324         file2 Z
1325         EOF
1326 '
1327
1328 test_expect_success 'complete tree filename with spaces' '
1329         echo content >"name with spaces" &&
1330         git add "name with spaces" &&
1331         git commit -m spaces &&
1332         test_completion "git show HEAD:nam" <<-\EOF
1333         name with spaces Z
1334         EOF
1335 '
1336
1337 test_expect_success 'complete tree filename with metacharacters' '
1338         echo content >"name with \${meta}" &&
1339         git add "name with \${meta}" &&
1340         git commit -m meta &&
1341         test_completion "git show HEAD:nam" <<-\EOF
1342         name with ${meta} Z
1343         name with spaces Z
1344         EOF
1345 '
1346
1347 test_expect_success 'send-email' '
1348         test_completion "git send-email --cov" "--cover-letter " &&
1349         test_completion "git send-email ma" "master "
1350 '
1351
1352 test_expect_success 'complete files' '
1353         git init tmp && cd tmp &&
1354         test_when_finished "cd .. && rm -rf tmp" &&
1355
1356         echo "expected" > .gitignore &&
1357         echo "out" >> .gitignore &&
1358
1359         git add .gitignore &&
1360         test_completion "git commit " ".gitignore" &&
1361
1362         git commit -m ignore &&
1363
1364         touch new &&
1365         test_completion "git add " "new" &&
1366
1367         git add new &&
1368         git commit -a -m new &&
1369         test_completion "git add " "" &&
1370
1371         git mv new modified &&
1372         echo modify > modified &&
1373         test_completion "git add " "modified" &&
1374
1375         touch untracked &&
1376
1377         : TODO .gitignore should not be here &&
1378         test_completion "git rm " <<-\EOF &&
1379         .gitignore
1380         modified
1381         EOF
1382
1383         test_completion "git clean " "untracked" &&
1384
1385         : TODO .gitignore should not be here &&
1386         test_completion "git mv " <<-\EOF &&
1387         .gitignore
1388         modified
1389         EOF
1390
1391         mkdir dir &&
1392         touch dir/file-in-dir &&
1393         git add dir/file-in-dir &&
1394         git commit -m dir &&
1395
1396         mkdir untracked-dir &&
1397
1398         : TODO .gitignore should not be here &&
1399         test_completion "git mv modified " <<-\EOF &&
1400         .gitignore
1401         dir
1402         modified
1403         untracked
1404         untracked-dir
1405         EOF
1406
1407         test_completion "git commit " "modified" &&
1408
1409         : TODO .gitignore should not be here &&
1410         test_completion "git ls-files " <<-\EOF &&
1411         .gitignore
1412         dir
1413         modified
1414         EOF
1415
1416         touch momified &&
1417         test_completion "git add mom" "momified"
1418 '
1419
1420 test_expect_success "completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'" '
1421         test_config alias.co "!sh -c '"'"'git checkout ...'"'"'" &&
1422         test_completion "git co m" <<-\EOF
1423         master Z
1424         mybranch Z
1425         mytag Z
1426         EOF
1427 '
1428
1429 test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '
1430         test_config alias.co "!f () { VAR=val git checkout ... ; } f" &&
1431         test_completion "git co m" <<-\EOF
1432         master Z
1433         mybranch Z
1434         mytag Z
1435         EOF
1436 '
1437
1438 test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '
1439         test_config alias.co "!f() { : git checkout ; if ... } f" &&
1440         test_completion "git co m" <<-\EOF
1441         master Z
1442         mybranch Z
1443         mytag Z
1444         EOF
1445 '
1446
1447 test_expect_success 'completion without explicit _git_xxx function' '
1448         test_completion "git version --" <<-\EOF
1449         --build-options Z
1450         EOF
1451 '
1452
1453 test_expect_failure 'complete with tilde expansion' '
1454         git init tmp && cd tmp &&
1455         test_when_finished "cd .. && rm -rf tmp" &&
1456
1457         touch ~/tmp/file &&
1458
1459         test_completion "git add ~/tmp/" "~/tmp/file"
1460 '
1461
1462 test_expect_success 'setup other remote for remote reference completion' '
1463         git remote add other otherrepo &&
1464         git fetch other
1465 '
1466
1467 for flag in -d --delete
1468 do
1469         test_expect_success "__git_complete_remote_or_refspec - push $flag other" '
1470                 sed -e "s/Z$//" >expected <<-EOF &&
1471                 master-in-other Z
1472                 EOF
1473                 (
1474                         words=(git push '$flag' other ma) &&
1475                         cword=${#words[@]} cur=${words[cword-1]} &&
1476                         __git_complete_remote_or_refspec &&
1477                         print_comp
1478                 ) &&
1479                 test_cmp expected out
1480         '
1481
1482         test_expect_failure "__git_complete_remote_or_refspec - push other $flag" '
1483                 sed -e "s/Z$//" >expected <<-EOF &&
1484                 master-in-other Z
1485                 EOF
1486                 (
1487                         words=(git push other '$flag' ma) &&
1488                         cword=${#words[@]} cur=${words[cword-1]} &&
1489                         __git_complete_remote_or_refspec &&
1490                         print_comp
1491                 ) &&
1492                 test_cmp expected out
1493         '
1494 done
1495
1496 test_expect_success 'sourcing the completion script clears cached commands' '
1497         __git_compute_all_commands &&
1498         verbose test -n "$__git_all_commands" &&
1499         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1500         verbose test -z "$__git_all_commands"
1501 '
1502
1503 test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
1504         __git_compute_merge_strategies &&
1505         verbose test -n "$__git_merge_strategies" &&
1506         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1507         verbose test -z "$__git_merge_strategies"
1508 '
1509
1510 test_expect_success 'sourcing the completion script clears cached --options' '
1511         __gitcomp_builtin checkout &&
1512         verbose test -n "$__gitcomp_builtin_checkout" &&
1513         __gitcomp_builtin notes_edit &&
1514         verbose test -n "$__gitcomp_builtin_notes_edit" &&
1515         . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
1516         verbose test -z "$__gitcomp_builtin_checkout" &&
1517         verbose test -z "$__gitcomp_builtin_notes_edit"
1518 '
1519
1520 test_done