* Bash completion very slow in large repo
@ 2026-08-14 18:55 Matthew Hughes
2026-08-15 14:17 ` D. Ben Knoble
0 siblings, 1 reply; 3+ messages in thread
From: Matthew Hughes @ 2026-08-14 18:55 UTC (permalink / raw)
To: git
Hi,
While working in a repo with _a lot_ of directories I've noticed a painful
slowdown in some of the bash completion for git. Specifically, for any
completion that calls `git ls-files` and needs to iterate through the
file-system (and not just check the index), e.g. `git add`. Has anyone run into
this? Are there existing solutions or workarounds?
I first ran into it when running something like
$ git add ./<tab> # hangs for a good second or two
For reference the number of files/directories in the actual repo I work with:
# this many files
$ git ls-files | wc --lines
367628
# this many directories
$ git ls-files -z | xargs -0 dirname | sort --unique | wc --lines
58404
See below for a reproduction and my logic, but I conclude this is because e.g.
in the case of `git add` (with no other args) git will need to look through
every directory in the repo to discover if there any untracked files at any
level.
I'm not sure about potential fixes. Hacking around on it the best I could come
up with was a workaround: add an env var to skip index completion during bash
completion, so the completion falls back to the default Bash file completion
(i.e. complete any time), here that is (just for demonstration):
diff --git i/contrib/completion/git-completion.bash w/contrib/completion/git-completion.bash
index e875787710..7b412e5b74 100644
--- i/contrib/completion/git-completion.bash
+++ w/contrib/completion/git-completion.bash
@@ -727,6 +727,10 @@ __git_index_files ()
# The exception is --committable, which finds the files appropriate commit.
__git_complete_index_file ()
{
+ if test -n "${GIT_COMPLETION_NO_COMPLETE_INDEX-}"
+ then
+ return
+ fi
local dequoted_word pfx="" cur_
__git_dequote "$cur"
For reproduction: here's a roughly similar setup of a repo, with many
directories at the root:
$ git init .
$ for i in {1..25000}; do echo dir_$i/sub_dir/; done | xargs mkdir -p
$ for i in {1..25000}; do for j in {1..12}; do echo dir_$i/sub_dir/file_$j.txt; done; done | xargs touch
$ git add .
With that setup I see slow completion e.g. on `git add ./di<TAB>`. Debugging
the completion script I see it hangs for a while on:
git -C ./ -c core.quotePath=false ls-files --exclude-standard --others --modified --directory --no-empty-directory -- 'di*'
(via `_git_add->__git_complete_index_file->__git_index_files`)
And running that through `strace` (on my Linux/AMD64 machine) tells me for each
directory there is (among other syscalls):
* ~100_000 calls to `getdents64`
* ~75_000 calls to `openat`
* ~50_000 calls to `fstat`
So that explains the slowdown.
Thanks,
Matt
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: Bash completion very slow in large repo
2026-08-14 18:55 Bash completion very slow in large repo Matthew Hughes
@ 2026-08-15 14:17 ` D. Ben Knoble
2026-08-15 19:52 ` Matthew Hughes
0 siblings, 1 reply; 3+ messages in thread
From: D. Ben Knoble @ 2026-08-15 14:17 UTC (permalink / raw)
To: Matthew Hughes; +Cc: git
On Fri, Aug 14, 2026 at 2:55 PM Matthew Hughes
<matthewhughes934@gmail.com> wrote:
>
> Hi,
>
> While working in a repo with _a lot_ of directories I've noticed a painful
> slowdown in some of the bash completion for git. Specifically, for any
> completion that calls `git ls-files` and needs to iterate through the
> file-system (and not just check the index), e.g. `git add`. Has anyone run into
> this? Are there existing solutions or workarounds?
Hi Matt, have you tried turning on "feature.manyFiles"? That enables a
few things (like the fsmonitor) that might help in large repositories.
[snip]
Best,
Ben
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Bash completion very slow in large repo
2026-08-15 14:17 ` D. Ben Knoble
@ 2026-08-15 19:52 ` Matthew Hughes
0 siblings, 0 replies; 3+ messages in thread
From: Matthew Hughes @ 2026-08-15 19:52 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git
On Sat, Aug 15, 2026 at 10:17:19AM -0400, D. Ben Knoble wrote:
> Hi Matt, have you tried turning on "feature.manyFiles"? That enables a
> few things (like the fsmonitor) that might help in large repositories.
Ah, thanks for calling that out: I should've mentioned this is in a repo that's
already configured via `git-scalar(1)`, so it sets that specific option off,
but justifies:
> feature.manyFiles=false
> This disables the "many files" optimizations grouped under this feature config.
> The expectation is that all valuable optimizations are also set explicitly by
> Scalar config, and any differences are intentional.
Though also testing in a fresh repo with no scalar but that option on I didn't
see any significant performance change.
I'm also not sure e.g. `git ls-files --exclude-standard --others --directory`
knows about things like `fsmonitor`/the untracked cache, like e.g. `git status`
does (disclaimer: I'm not at all familiar enough with the code to justify that
claim, it's based purely on my qualitative experience, I'm also not sure if it
_could_ benefit from such things)
Cheers,
Matt
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-15 19:52 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 18:55 Bash completion very slow in large repo Matthew Hughes
2026-08-15 14:17 ` D. Ben Knoble
2026-08-15 19:52 ` Matthew Hughes
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.