Skip to content

Commit 6d54f52

Browse files
yousgitster
authored andcommitted
completion: treat results of git ls-tree as file paths
Let's say there are files named 'foo bar.txt', and 'abc def/test.txt' in repository. When following commands trigger a completion: git show HEAD:fo<Tab> git show HEAD:ab<Tab> The completion results in bash/zsh: git show HEAD:foo bar.txt git show HEAD:abc def/ Where the both of them have an unescaped space in paths, so they'll be misread by git. All entries of git ls-tree either a filename or a directory, so __gitcomp_file() is proper rather than __gitcomp_nl(). Note the commit f12785a, which handles quoted paths properly. Like this case, we should dequote $cur_ for ?*:* case. For example, let's say there is untracked directory 'abc deg', then trigger a completion: git show HEAD:abc\ de<Tab> git show HEAD:'abc de<Tab> git show HEAD:"abc de<Tab> should uniquely complete 'abc def', but bash completes 'abc def' and 'abc deg' instead. In zsh, triggering a completion: git show HEAD:abc\ def/<Tab> should complete 'test.txt', but nothing comes. The both problems will be resolved by dequoting paths. __git_complete_revlist_file() passes arguments to __gitcomp_nl() where the first one is a list something like: abc def/Z foo bar.txt Z where Z is the mark of the EOL. - The trailing space of blob in __git ls-tree | sed. It makes the completion results become: git show HEAD:foo\ bar.txt\ <CURSOR> So git will try to find a file named 'foo bar.txt ' instead. - The trailing slash of tree in __git ls-tree | sed. It makes the completion results on zsh become: git show HEAD:abc\ def/ <CURSOR> So that the last space on command like should be removed on zsh to complete filenames under 'abc def/'. Signed-off-by: Chayoung You <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 7a478b3 commit 6d54f52

File tree

2 files changed

+17
-24
lines changed

2 files changed

+17
-24
lines changed

contrib/completion/git-completion.bash

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -855,22 +855,26 @@ __git_compute_merge_strategies ()
855855

856856
__git_complete_revlist_file ()
857857
{
858-
local pfx ls ref cur_="$cur"
858+
local dequoted_word pfx ls ref cur_="$cur"
859859
case "$cur_" in
860860
*..?*:*)
861861
return
862862
;;
863863
?*:*)
864864
ref="${cur_%%:*}"
865865
cur_="${cur_#*:}"
866-
case "$cur_" in
866+
867+
__git_dequote "$cur_"
868+
869+
case "$dequoted_word" in
867870
?*/*)
868-
pfx="${cur_%/*}"
869-
cur_="${cur_##*/}"
871+
pfx="${dequoted_word%/*}"
872+
cur_="${dequoted_word##*/}"
870873
ls="$ref:$pfx"
871874
pfx="$pfx/"
872875
;;
873876
*)
877+
cur_="$dequoted_word"
874878
ls="$ref"
875879
;;
876880
esac
@@ -880,21 +884,10 @@ __git_complete_revlist_file ()
880884
*) pfx="$ref:$pfx" ;;
881885
esac
882886

883-
__gitcomp_nl "$(__git ls-tree "$ls" \
884-
| sed '/^100... blob /{
885-
s,^.* ,,
886-
s,$, ,
887-
}
888-
/^120000 blob /{
889-
s,^.* ,,
890-
s,$, ,
891-
}
892-
/^040000 tree /{
893-
s,^.* ,,
894-
s,$,/,
895-
}
896-
s/^.* //')" \
897-
"$pfx" "$cur_" ""
887+
__gitcomp_file "$(__git ls-tree "$ls" \
888+
| sed 's/^.* //
889+
s/$//')" \
890+
"$pfx" "$cur_"
898891
;;
899892
*...*)
900893
pfx="${cur_%...*}..."

t/t9902-completion.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,8 +1515,8 @@ test_expect_success 'show completes all refs' '
15151515

15161516
test_expect_success '<ref>: completes paths' '
15171517
test_completion "git show mytag:f" <<-\EOF
1518-
file1 Z
1519-
file2 Z
1518+
file1Z
1519+
file2Z
15201520
EOF
15211521
'
15221522

@@ -1525,7 +1525,7 @@ test_expect_success 'complete tree filename with spaces' '
15251525
git add "name with spaces" &&
15261526
git commit -m spaces &&
15271527
test_completion "git show HEAD:nam" <<-\EOF
1528-
name with spaces Z
1528+
name with spacesZ
15291529
EOF
15301530
'
15311531

@@ -1534,8 +1534,8 @@ test_expect_success 'complete tree filename with metacharacters' '
15341534
git add "name with \${meta}" &&
15351535
git commit -m meta &&
15361536
test_completion "git show HEAD:nam" <<-\EOF
1537-
name with ${meta} Z
1538-
name with spaces Z
1537+
name with ${meta}Z
1538+
name with spacesZ
15391539
EOF
15401540
'
15411541

0 commit comments

Comments
 (0)