From: Matthew Hughes <matthewhughes934@gmail.com>
To: git@vger.kernel.org
Subject: Bash completion very slow in large repo
Date: Fri, 14 Aug 2026 19:55:36 +0100 [thread overview]
Message-ID: <an9iXOqOOvFfyN4A@desktop> (raw)
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
reply other threads:[~2026-08-14 18:55 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=an9iXOqOOvFfyN4A@desktop \
--to=matthewhughes934@gmail.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox