Skip to content

Commit 9d2f9a6

Browse files
committed
Merge branch 'ld/sparse-index-bash-completion'
The command line completion (in contrib/) learns to complete arguments to give to "git sparse-checkout" command. * ld/sparse-index-bash-completion: completion: handle unusual characters for sparse-checkout completion: improve sparse-checkout cone mode directory completion completion: address sparse-checkout issues
2 parents b801210 + 4880382 commit 9d2f9a6

File tree

2 files changed

+174
-8
lines changed

2 files changed

+174
-8
lines changed

contrib/completion/git-completion.bash

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,24 +2986,52 @@ _git_show_branch ()
29862986
__git_complete_revlist
29872987
}
29882988

2989+
__gitcomp_directories ()
2990+
{
2991+
local _tmp_dir _tmp_completions _found=0
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+
# de-quoting, and handling unusual characters.
3001+
while IFS= read -r -d $'\0' c ; do
3002+
# If there are directory completions, find ones that start
3003+
# with "$cur", the current token, and put those in COMPREPLY
3004+
if [[ $c == "$cur"* ]]; then
3005+
COMPREPLY+=("$c/")
3006+
_found=1
3007+
fi
3008+
done < <(git ls-tree -z -d --name-only HEAD $_tmp_dir)
3009+
3010+
if [[ $_found == 0 ]] && [[ "$cur" =~ /$ ]]; then
3011+
# No possible further completions any deeper, so assume we're at
3012+
# a leaf directory and just consider it complete
3013+
__gitcomp_direct_append "$cur "
3014+
fi
3015+
}
3016+
29893017
_git_sparse_checkout ()
29903018
{
2991-
local subcommands="list init set disable"
3019+
local subcommands="list init set disable add reapply"
29923020
local subcommand="$(__git_find_on_cmdline "$subcommands")"
29933021
if [ -z "$subcommand" ]; then
29943022
__gitcomp "$subcommands"
29953023
return
29963024
fi
29973025

29983026
case "$subcommand,$cur" in
2999-
init,--*)
3000-
__gitcomp "--cone"
3001-
;;
3002-
set,--*)
3003-
__gitcomp "--stdin"
3004-
;;
3005-
*)
3027+
*,--*)
3028+
__gitcomp_builtin sparse-checkout_$subcommand "" "--"
30063029
;;
3030+
set,*|add,*)
3031+
if [ "$(__git config core.sparseCheckoutCone)" == "true" ] ||
3032+
[ -n "$(__git_find_on_cmdline --cone)" ]; then
3033+
__gitcomp_directories
3034+
fi
30073035
esac
30083036
}
30093037

t/t9902-completion.sh

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,144 @@ test_expect_success 'git checkout - with --detach, complete only references' '
14441444
EOF
14451445
'
14461446

1447+
test_expect_success 'setup sparse-checkout tests' '
1448+
# set up sparse-checkout repo
1449+
git init sparse-checkout &&
1450+
(
1451+
cd sparse-checkout &&
1452+
mkdir -p folder1/0/1 folder2/0 folder3 &&
1453+
touch folder1/0/1/t.txt &&
1454+
touch folder2/0/t.txt &&
1455+
touch folder3/t.txt &&
1456+
git add . &&
1457+
git commit -am "Initial commit"
1458+
)
1459+
'
1460+
1461+
test_expect_success 'sparse-checkout completes subcommands' '
1462+
test_completion "git sparse-checkout " <<-\EOF
1463+
list Z
1464+
init Z
1465+
set Z
1466+
add Z
1467+
reapply Z
1468+
disable Z
1469+
EOF
1470+
'
1471+
1472+
test_expect_success 'cone mode sparse-checkout completes directory names' '
1473+
# initialize sparse-checkout definitions
1474+
git -C sparse-checkout sparse-checkout set --cone folder1/0 folder3 &&
1475+
1476+
# test tab completion
1477+
(
1478+
cd sparse-checkout &&
1479+
test_completion "git sparse-checkout set f" <<-\EOF
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 &&
1502+
test_completion "git sparse-checkout add 0" <<-\EOF
1503+
0/
1504+
EOF
1505+
)
1506+
'
1507+
1508+
test_expect_success 'cone mode sparse-checkout completes directory names with spaces and accents' '
1509+
# reset sparse-checkout
1510+
git -C sparse-checkout sparse-checkout disable &&
1511+
(
1512+
cd sparse-checkout &&
1513+
mkdir "directory with spaces" &&
1514+
mkdir "directory-with-áccent" &&
1515+
>"directory with spaces/randomfile" &&
1516+
>"directory-with-áccent/randomfile" &&
1517+
git add . &&
1518+
git commit -m "Add directory with spaces and directory with accent" &&
1519+
git sparse-checkout set --cone "directory with spaces" \
1520+
"directory-with-áccent" &&
1521+
test_completion "git sparse-checkout add dir" <<-\EOF &&
1522+
directory with spaces/
1523+
directory-with-áccent/
1524+
EOF
1525+
rm -rf "directory with spaces" &&
1526+
rm -rf "directory-with-áccent" &&
1527+
git add . &&
1528+
git commit -m "Remove directory with spaces and directory with accent"
1529+
)
1530+
'
1531+
1532+
# use FUNNYNAMES to avoid running on Windows, which doesn't permit backslashes or tabs in paths
1533+
test_expect_success FUNNYNAMES 'cone mode sparse-checkout completes directory names with backslashes and tabs' '
1534+
# reset sparse-checkout
1535+
git -C sparse-checkout sparse-checkout disable &&
1536+
(
1537+
cd sparse-checkout &&
1538+
mkdir "directory\with\backslashes" &&
1539+
mkdir "$(printf "directory\twith\ttabs")" &&
1540+
>"directory\with\backslashes/randomfile" &&
1541+
>"$(printf "directory\twith\ttabs")/randomfile" &&
1542+
git add . &&
1543+
git commit -m "Add directory with backslashes and directory with tabs" &&
1544+
git sparse-checkout set --cone "directory\with\backslashes" \
1545+
"$(printf "directory\twith\ttabs")" &&
1546+
test_completion "git sparse-checkout add dir" <<-\EOF &&
1547+
directory\with\backslashes/
1548+
directory with tabs/
1549+
EOF
1550+
rm -rf "directory\with\backslashes" &&
1551+
rm -rf "$(printf "directory\twith\ttabs")" &&
1552+
git add . &&
1553+
git commit -m "Remove directory with backslashes and directory with tabs"
1554+
)
1555+
'
1556+
1557+
test_expect_success 'non-cone mode sparse-checkout uses bash completion' '
1558+
# reset sparse-checkout repo to non-cone mode
1559+
git -C sparse-checkout sparse-checkout disable &&
1560+
git -C sparse-checkout sparse-checkout set --no-cone &&
1561+
1562+
(
1563+
cd sparse-checkout &&
1564+
# expected to be empty since we have not configured
1565+
# custom completion for non-cone mode
1566+
test_completion "git sparse-checkout set f" <<-\EOF
1567+
1568+
EOF
1569+
)
1570+
'
1571+
1572+
test_expect_success 'git sparse-checkout set --cone completes directory names' '
1573+
git -C sparse-checkout sparse-checkout disable &&
1574+
1575+
(
1576+
cd sparse-checkout &&
1577+
test_completion "git sparse-checkout set --cone f" <<-\EOF
1578+
folder1/
1579+
folder2/
1580+
folder3/
1581+
EOF
1582+
)
1583+
'
1584+
14471585
test_expect_success 'git switch - with -d, complete all references' '
14481586
test_completion "git switch -d " <<-\EOF
14491587
HEAD Z

0 commit comments

Comments
 (0)