mirror of
https://github.com/git/git.git
synced 2026-08-09 09:34:14 +00:00
completion: complete tracked paths for 'git diff'
When completing arguments for 'git diff', _git_diff() delegates to __git_complete_revlist_file(), which only completes revision references. This is good [*], as mixing both revisions and paths in a single list for the user to pick from is simply too confusing. If no reference matches, or if '--' is given, however, _git_diff() leaves COMPREPLY empty. Bash then falls back to default filename completion in $PWD. This fails when 'git -C <path>' is used because $PWD is not the target repository. Update _git_diff() to use __git_complete_index_file() when '--' is present, or when revision reference completion yields no matching candidates, so that tracked paths are offered as candidates. This changes behavior even in the case where '-C <there>' is not used. The new behavior omits untracked paths from suggestions when no revs match the prefix but matching tracked paths exist, which is more useful in the context of 'git diff'. When run outside the working tree of a repository, or when nothing matches from revisions or tracked paths, Bash still falls back to default filename completion in $PWD, so such a use case would be just like completing paths for any 'diff' command, rather than for 'git diff'. [Footnote] * In https://lore.kernel.org/git/al%2Fw2qgBfhe9qMg6@szeder.dev/ SZEDER made the same argument for "git send-email 0<TAB>". Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
@@ -1981,6 +1981,10 @@ _git_diff ()
|
||||
esac
|
||||
__git_complete_revlist_file
|
||||
fi
|
||||
|
||||
if [ ${#COMPREPLY[@]} -eq 0 ]; then
|
||||
__git_complete_index_file
|
||||
fi
|
||||
}
|
||||
|
||||
__git_mergetools_common="diffuse diffmerge ecmerge emerge kdiff3 meld opendiff
|
||||
|
||||
@@ -2712,6 +2712,45 @@ test_expect_success 'git -C <path> checkout uses the right repo' '
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'git diff completes tracked paths when no refs match' '
|
||||
# file1 and file2 are tracked but file3 is not
|
||||
test_completion "git diff f" <<-\EOF
|
||||
file1
|
||||
file2
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'git diff -- completes tracked paths' '
|
||||
# file1 and file2 are tracked but file3 is not
|
||||
test_completion "git diff -- f" <<-\EOF
|
||||
file1
|
||||
file2
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'git -C <path> diff completes tracked paths in specified repo' '
|
||||
test_when_finished "rm -rf repo-for-diff" &&
|
||||
git init repo-for-diff &&
|
||||
echo content >repo-for-diff/otherfile &&
|
||||
git -C repo-for-diff add otherfile &&
|
||||
echo untracked >repo-for-diff/oops &&
|
||||
git -C repo-for-diff commit -m otherfile &&
|
||||
test_completion "git -C repo-for-diff diff o" <<-\EOF
|
||||
otherfile
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'git -C <path> diff -- completes pathspecs in specified repo' '
|
||||
test_when_finished "rm -rf repo-for-diff" &&
|
||||
git init repo-for-diff &&
|
||||
echo content >repo-for-diff/otherfile &&
|
||||
git -C repo-for-diff add otherfile &&
|
||||
git -C repo-for-diff commit -m otherfile &&
|
||||
test_completion "git -C repo-for-diff diff -- o" <<-\EOF
|
||||
otherfile
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'show completes all refs' '
|
||||
test_completion "git show m" <<-\EOF
|
||||
main Z
|
||||
|
||||
Reference in New Issue
Block a user