Reputation: 13477
Recently I found the command
git ls-files
and I find it very useful (see the it with -h
option). Why doesn't it appear if i type git
and then press Tab
?
I mean - where is the list of "other" commands of git
?
Upvotes: 13
Views: 1614
Reputation: 1325155
With Git 2.18 (Q2 2018), the command line completion (in contrib/
) learned to complete pathnames for various commands better.
And that includes git ls-files
!
See commit 7d31407, commit 8b4c2e0 (18 May 2018), and commit 7b00342, commit 193757f, commit c1bc0a0, commit 9703797, commit 105c0ef, commit a364e98, commit f12785a, commit 3dfe23b, commit 6bf0ced, commit 722e31c, commit 5bb534a (16 Apr 2018) by SZEDER Gábor (szeder
).
(Merged by Junio C Hamano -- gitster
-- in commit 4ce7218, 30 May 2018)
completion: improve handling quoted paths in '
git ls-files
's outputIf any pathname contains backslash, double quote, tab, newline, or any control characters, '
git ls-files
' and 'git diff-index
' will enclose that pathname in double quotes and escape those special characters using C-style one-character escape sequences or\nnn
octal values.This prevents those files from being listed during git-aware path completion, because due to the quoting they will never match the current word to be completed.
That leads to various speed improvements:
completion: remove repeated
dirnames
with 'awk
' during path completionDuring git-aware path completion, after all the trailing path components have been removed from the output of 'git ls-files' and 'git diff-index', each directory name is repeated as many times as the number of listed paths it contains.
This can be a lot of repetitions, especially when invoking path completion close to the root of a big worktree.Listing all tracked files (12) and directories (23) at the top of the worktree in linux.git (over 62k files), i.e. what's doing all the hard work behind 'git ls-files ':
Before this patch, best of five, using GNU awk on Linux:
real 0m0.069s user 0m0.089s sys 0m0.026s
After:
real 0m0.052s user 0m0.072s sys 0m0.014s Difference: -24.6%
completion: let '
ls-files
' and 'diff-index
' filter matching pathsDuring git-aware path completion, e.g. '
git rm dir/fil<TAB>
', both 'git ls-files
' and 'git diff-index
' list all paths in the given 'dir/
' matching certain criteria (cached, modified, untracked, etc.) appropriate for the given git command, even paths whose names don't begin with 'fil'.
This comes with a considerable performance penalty when the directory in question contains a lot of paths, but the current word can be uniquely completed or when only a handful of those paths match the current word.Reduce the number of iterations in this codepath from the number of paths to the number of matching paths by specifying an appropriate globbing pattern to '
git ls-files
' and 'git diff-index
' to list only paths that match the current word to be completed.This speeds up path completion considerably when there are a lot of non-matching paths to be filtered out.
Uniquely completing a tracked filename at the top of the worktree in linux.git (over 62k files), i.e. what's doing all the hard work behind 'git ls-files Mak' to complete 'Makefile':Before this patch, best of five, on Linux:
$ time cur=Mak __git_complete_index_file real 0m2.159s user 0m1.299s sys 0m1.089s
After:
real 0m0.033s user 0m0.023s sys 0m0.015s Difference: -98.5% Speedup: 65.4x
completion: fill
COMPREPLY
directly when completing pathsThis speeds up path completion when there are a lot of paths matching the current word to be completed.
In a pathological repository with 100k files in a single directory, listing all those files:Before this patch, best of five, using GNU awk on Linux:
$ time cur=dir/ __git_complete_index_file real 0m0.983s user 0m1.004s sys 0m0.033s
After:
real 0m0.313s user 0m0.341s sys 0m0.029s Difference: -68.2% Speedup: 3.1x
Upvotes: 0
Reputation: 14621
Look at your ~/.git-completion.sh
and the __git_list_porcelain_commands()
function. The commands that git supports but won't tab-complete are listed there. Most of these commands are so-called "plumbing" commands, including ls-files
. You can easily make them tab-completed by commenting the respective line. Like this:
#ls-files) : plumbing;;
#ls-remote) : plumbing;;
#ls-tree) : plumbing;;
Upvotes: 6
Reputation: 25606
In a default install, Tab completion only lists names of commands as they appear in /bin
, /usr/bin
, etc. There is no file /usr/bin/git ls-files
.
ls-files
is a sub command that you will have to teach your shell about. Assuming you are using bash, you can run help complete
to see what commands you can put in your .bashrc
.
If your distribution supplies the bash-completion package, you can install it to save a lot of time:
apt-get install bash-completion # on Debian/Ubuntu/etc.
yum install bash-completion # on Fedora/Red Hat/etc.
But as manojlds points out, this won't work for the less commonly used git commands such as ls-files
because bash-completion hides those from you. You would have to edit /etc/bash_completion.d/git
to change that.
Upvotes: -2
Reputation: 301177
git ls-files
is a plumbing command and many of these commands are "hidden" and rightfully so. Over time, many have been added to the bash completion, but many are still "hidden"
Upvotes: 4