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