Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Slowness issue with git completion

On Tue, 26 Apr 2011, Felipe Contreras wrote:

On Tue, Apr 26, 2011 at 11:34 PM, Mikael Magnusson wrote:
On 26 April 2011 22:23, Felipe Contreras wrote:
On Tue, Apr 26, 2011 at 9:43 PM, Frank Terbeck wrote:
Felipe Contreras wrote:
It's very easy to reproduce:
% git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
% cd linux
% git log v<tab>

It will take a looong time to figure out anything, specially if not cached. I think I recall investigating the issue and finding that it's looking for *all* the files in the git repo.

Well yes. This is a known issue.

I'm fairly sure that this is due to _multi_parts, which probably doesn't scale for jobs like that.  I once gave rewriting all that a shot and ended up with a number of helpers for each "type" of file etc. (like modified or ignored files).  While they were significantly quicker than the current code, they were probably still full of bugs and shortcomings. Also, I would have had to rewrite *large* parts of the rest of the completion, which would have been a *major* undertaking.

In short: It's a known issue and it's very hard to fix (if only because it is a *lot* of work).

Here's a quick solution: don't try to list files. If I want to list files, I would use '-- '. And in fact, that's exactly what the bash completion does.

git accepts files with or without a --


So if git accepts filenames with or without the '--', Zsh's completion should list filenames with or without the '--'.

Moreover, why do you want to be smarter than git? There are ways to ask git precisely what we want: list the contents of certain tree-ish on-demand. And in fact, that's exactly what the bash completion does:

time git ls-tree HEAD -- (0m0.005s)
time git ls-tree HEAD -- drivers/ (0m0.007s)

git ls-tree doesn't allow you to filter the output files by 'changed', 'new', 'unknown' etc etc.


So 'ls-tree' doesn't list context-appropriate completions, which is what Zsh is providing. So, 'ls-tree' can't provide the list of files Zsh needs.

The point is that the way bash does it ignores the context cues that Zsh (very-)inefficiently exploits.

If you don't care about the correctness, just modify __git_files to only complete anything if it's already seen '--'.

Or, far more simply, just disable __git_files entirely. I have <Alt>+<,> bound to file completion partly so I can complete filenames even in places where it doesn't make sense -- or more often: where Zsh doesn't think it makes sense -- but partly for this workaround in particular.

In ~/.zshrc or wherever:

" map alt-, to complete files
zle -C complete-files complete-word _generic
zstyle ':completion:complete-files:*' completer _files
bindkey '^[,' complete-files

" disable git file completion because it's so slow

It's a workaround. At some point, someone (probably someone participating in this thread) will figure out a proper solution. But until that happens the workaround is better than breaking the context sensitivity of git completion just to make it as fast as bash.


Messages sorted by: Reverse Date, Date, Thread, Author