completion: improve sparse-checkout cone mode directory completion
Use new __gitcomp_directories method to complete directory names in cone mode sparse-checkouts. This method addresses the caveat of poor performance in monorepos from the previous commit (by completing only one level of directories). The unusual character caveat from the previous commit will be fixed by the final commit in this series. Co-authored-by: Elijah Newren <newren@gmail.com> Co-authored-by: Lessley Dennington <lessleydennington@gmail.com> Signed-off-by: Lessley Dennington <lessleydennington@gmail.com> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Lessley Dennington committed
Feb 7, 2022 at 17:31 UTC
c5f5c5082f813a875c213445135a24c2507021dd
2 files changed
+53
-17
contrib/completion/git-completion.bash
+31
-1
@@ -2986,6 +2986,36 @@ _git_show_branch ()
2986
__git_complete_revlist
2987
}
2988
2989
+__gitcomp_directories ()
2990
+{
2991
+ local _tmp_dir _tmp_completions
2992
+
2993
+ # Get the directory of the current token; this differs from dirname
2994
+ # in that it keeps up to the final trailing slash. If no slash found
2995
+ # that's fine too.
2996
+ [[ "$cur" =~ .*/ ]]
2997
+ _tmp_dir=$BASH_REMATCH
2998
+
2999
+ # Find possible directory completions, adding trailing '/' characters
3000
+ _tmp_completions="$(git ls-tree -d --name-only HEAD $_tmp_dir |
3001
+ sed -e s%$%/%)"
3002
+
3003
+ if [[ -n "$_tmp_completions" ]]; then
3004
+ # There were some directory completions, so find ones that
3005
+ # start with "$cur", the current token, and put those in COMPREPLY
3006
+ local i=0 c IFS=$' \t\n'
3007
+ for c in $_tmp_completions; do
3008
+ if [[ $c == "$cur"* ]]; then
3009
+ COMPREPLY+=("$c")
3010
+ fi
3011
+ done
3012
+ elif [[ "$cur" =~ /$ ]]; then
3013
+ # No possible further completions any deeper, so assume we're at
3014
+ # a leaf directory and just consider it complete
3015
+ __gitcomp_direct_append "$cur "
3016
+ fi
3017
+}
3018
+
3019
_git_sparse_checkout ()
3020
{
3021
local subcommands="list init set disable add reapply"
@@ -3002,7 +3032,7 @@ _git_sparse_checkout ()
3032
set,*|add,*)
3033
if [ "$(__git config core.sparseCheckoutCone)" == "true" ] ||
3034
[ -n "$(__git_find_on_cmdline --cone)" ]; then
3005
- __gitcomp "$(git ls-tree -d -r HEAD --name-only)"
3035
+ __gitcomp_directories
3036
fi
3037
esac
3038
}
t/t9902-completion.sh
+22
-16
@@ -1477,21 +1477,30 @@ test_expect_success 'cone mode sparse-checkout completes directory names' '
1477
(
1478
cd sparse-checkout &&
1479
test_completion "git sparse-checkout set f" <<-\EOF
1480
- folder1 Z
1481
- folder1/0 Z
1482
- folder1/0/1 Z
1483
- folder2 Z
1484
- folder2/0 Z
1485
- folder3 Z
1480
+ folder1/
1481
+ folder2/
1482
+ folder3/
1483
+ EOF
1484
+ ) &&
1485
+
1486
+ (
1487
+ cd sparse-checkout &&
1488
+ test_completion "git sparse-checkout set folder1/" <<-\EOF
1489
+ folder1/0/
1490
+ EOF
1491
+ ) &&
1492
+
1493
+ (
1494
+ cd sparse-checkout &&
1495
+ test_completion "git sparse-checkout set folder1/0/" <<-\EOF
1496
+ folder1/0/1/
1497
EOF
1498
) &&
1499
1500
(
1501
cd sparse-checkout/folder1 &&
1491
- test_completion "git sparse-checkout add " <<-\EOF
1492
- ./ Z
1493
- 0 Z
1494
- 0/1 Z
1502
+ test_completion "git sparse-checkout add 0" <<-\EOF
1503
+ 0/
1504
EOF
1505
)
1506
'
@@ -1517,12 +1526,9 @@ test_expect_success 'git sparse-checkout set --cone completes directory names' '
1526
(
1527
cd sparse-checkout &&
1528
test_completion "git sparse-checkout set --cone f" <<-\EOF
1520
- folder1 Z
1521
- folder1/0 Z
1522
- folder1/0/1 Z
1523
- folder2 Z
1524
- folder2/0 Z
1525
- folder3 Z
1529
+ folder1/
1530
+ folder2/
1531
+ folder3/
1532
EOF
1533
)
1534
'