[PATCH v3 2/2] completion: treat results of git ls-tree as file paths
- From
Chayoung You <yousbe@gmail.com>
- Date
- Jan 1, 2019, 14:05 UTC
- Message-ID
- <20190101140509.1857-3-yousbe@gmail.com>
- In-Reply-To
- <20190101140509.1857-1-yousbe@gmail.com>
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 f12785a3, 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 Zwhere 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 <yousbe@gmail.com> --- contrib/completion/git-completion.bash | 31 ++++++++++---------------- t/t9902-completion.sh | 10 ++++----- 2 files changed, 17 insertions(+), 24 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 816ee3280..26ea310fd 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -855,7 +855,7 @@ __git_compute_merge_strategies () __git_complete_revlist_file () { - local pfx ls ref cur_="$cur" + local dequoted_word pfx ls ref cur_="$cur" case "$cur_" in *..?*:*) return @@ -863,14 +863,18 @@ __git_complete_revlist_file () ?*:*) ref="${cur_%%:*}" cur_="${cur_#*:}" - case "$cur_" in + + __git_dequote "$cur_" + + case "$dequoted_word" in ?*/*) - pfx="${cur_%/*}" - cur_="${cur_##*/}" + pfx="${dequoted_word%/*}" + cur_="${dequoted_word##*/}" ls="$ref:$pfx" pfx="$pfx/" ;; *) + cur_="$dequoted_word" ls="$ref" ;; esac @@ -880,21 +884,10 @@ __git_complete_revlist_file () *) pfx="$ref:$pfx" ;; esac - __gitcomp_nl "$(__git ls-tree "$ls" \ - | sed '/^100... blob /{ - s,^.* ,, - s,$, , - } - /^120000 blob /{ - s,^.* ,, - s,$, , - } - /^040000 tree /{ - s,^.* ,, - s,$,/, - } - s/^.* //')" \ - "$pfx" "$cur_" "" + __gitcomp_file "$(__git ls-tree "$ls" \ + | sed 's/^.* // + s/$//')" \ + "$pfx" "$cur_" ;; *...*) pfx="${cur_%...*}..." diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 137fdc9bd..94157e587 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1515,8 +1515,8 @@ test_expect_success 'show completes all refs' ' test_expect_success '<ref>: completes paths' ' test_completion "git show mytag:f" <<-\EOF - file1 Z - file2 Z + file1Z + file2Z EOF ' @@ -1525,7 +1525,7 @@ test_expect_success 'complete tree filename with spaces' ' git add "name with spaces" && git commit -m spaces && test_completion "git show HEAD:nam" <<-\EOF - name with spaces Z + name with spacesZ EOF ' @@ -1534,8 +1534,8 @@ test_expect_success 'complete tree filename with metacharacters' ' git add "name with \${meta}" && git commit -m meta && test_completion "git show HEAD:nam" <<-\EOF - name with ${meta} Z - name with spaces Z + name with ${meta}Z + name with spacesZ EOF '
-- 2.17.1