bash-git-prompt icon indicating copy to clipboard operation
bash-git-prompt copied to clipboard

it takes too long to cd into large repositories

Open yilkalargaw opened this issue 6 years ago • 13 comments

when changing a directory to a large repository like servo and linux kernel it takes too long to list the directory.

yilkalargaw avatar Oct 15 '17 08:10 yilkalargaw

I think it's too slow in general. Even in a small repo it's taking around 10 seconds. I'm using it in cygwin on Windows 7 if that makes any difference.

whittedb avatar Oct 17 '17 19:10 whittedb

I have two repos, each of which around 5000 files (excluding ignored). Switching takes less than 1 second

ghost avatar Oct 17 '17 19:10 ghost

I made some tests, i have some slow prompt too when i work with repo in my linux home on a NFS share. i clone the repo locally and no problem even on a rather big repo (4500 objects / 400 commit in master / only master branch).

No test on Windows with a babun, because i already have oh-my-zsh then don't use bash-git-prompt. (the same repo with this config guive near no lag but i don't have all the status icons it seems)

dcpc007 avatar Oct 18 '17 07:10 dcpc007

performance on Windows seems generally a problem. I have the same problems in Windows with the Powershell-Prompts (posh-git)

magicmonty avatar Oct 22 '17 13:10 magicmonty

Seems perfectly fine for me with windows 10 (64-bit) and cygwin(32-bit). Subsecond response on everything.

 $ git --version
git version 2.12.3

jimmywan avatar Oct 24 '17 16:10 jimmywan

My understanding of that bash-git-prompt is doing is: everytime your prompt has to be displayed, it runs /usr/lib/bash-git-prompt/gitstatus.sh (or wherever it's at in on your system.)

gitstatus.sh runs git status once and parses its output.

If it's being slow in a directory, IMO, that's because git status is slow, not because bash-git-prompt is slow. See how long your prompt takes to run, and see if that's the same time it takes git status to run.

If your repo has large submodules, you can change gitstatus.sh line 18 from:

gitstatus=$( LC_ALL=C git status --untracked-files=${__GIT_PROMPT_SHOW_UNTRACKED_FILES:-all} --porcelain --branch )

to

gitstatus=$( LC_ALL=C git status --ignore-submodules --untracked-files=${__GIT_PROMPT_SHOW_UNTRACKED_FILES:-all} --porcelain --branch )

This will run faster, but your prompt will no longer show you any changes to your submodules. Perhaps you're OK with that, and can remember that whenever you make a change in your submodules. Manually running git (i.e. git status) will still know the changes, even though your prompt won't.

jamespharvey20 avatar Oct 25 '17 01:10 jamespharvey20

P.S. Running git_prompt_toggle will toggle between the original prompt and the one that bash-git-prompt defines.

If you're in the linux kernel repo, there's just no way continuously running git status isn't going to be slow.

jamespharvey20 avatar Oct 25 '17 01:10 jamespharvey20

With git-prompt disabled I get sub-second responses, both just hitting enter and executing git status. With git-prompt enabled, the responses jump to the 5-6 second range. After running git_prompt_toggle, responses are around 2-3 seconds.

Could it make a difference if my repo is living on a ramdisk? You would think that would be faster. My remotes are also local and being hosted via gitblit hosted on Tomcat 8. Although, if that were an issue, then you would think that executing git status without git-prompt enabled would be slow too.

whittedb avatar Oct 27 '17 16:10 whittedb

Hi, I just added a new option GIT_PROMPT_IGNORE_SUBMODULES which can be set to 1 to ignore submodules. This value can also be set in .bash-git-rc to disable this behavior in individual repositories

magicmonty avatar Dec 18 '17 21:12 magicmonty

My problem was that this line

git_status_fields=($("$__GIT_STATUS_CMD" 2>/dev/null))

Invokes this

gitstatus=$( LC_ALL=C git status ${_ignore_submodules} --untracked-files=${__GIT_PROMPT_SHOW_UNTRACKED_FILES:-all} --porcelain --branch )

Which in my case was 50,597 files. This took a few seconds each time I got a new prompt.

Took me a few hours to figure out I needed to add this to my .bash_profile.

export GIT_PROMPT_SHOW_UNTRACKED_FILES=0

I would recommend defaulting to that option just like git-prompt.sh does.

ubershmekel avatar Aug 15 '18 05:08 ubershmekel

I have a repo with 53K files including some binaries. It takes over a minute to refresh the prompt. Git tells me 38s is just for untracked files. I tried

export GIT_PROMPT_SHOW_UNTRACKED_FILES=0

But then I lose my git prompt altogether. Looks like it has been updated to

 export GIT_PROMPT_SHOW_UNTRACKED_FILES=no

And I add

export GIT_PROMPT_SHOW_CHANGED_FILES_COUNT=0

I also tried every other env that seemed like it would reduce prompt refresh but nothing else did anything. I have no submodules. Best case reduced refresh from over a minute to about 18s but that is still too much. Is there a theme that would simply keep the branch name without any of the other git queries? This would be sufficient for this particular repo. I don't want to hack the scripts as I don't want to change the behavior for any other reop. Unfortunately I am stuck with git 1.8.3.

BTW, git status -uno returns in just a few seconds.

fastzombies avatar Mar 14 '19 18:03 fastzombies

If you need to use the old gitstatus_pre-1.7.10.sh then I don't think it has support for GIT_PROMPT_SHOW_UNTRACKED_FILES unfortunately.

It calculates (quite inefficiently) untracked files every time. If you are using the old status script you could patch it like so and see if that makes it faster (or just hard code the num_untracked value to 0.

@fastzombies

diff --git a/gitstatus_pre-1.7.10.sh b/gitstatus_pre-1.7.10.sh
index 7ae7238..633d130 100755
--- a/gitstatus_pre-1.7.10.sh
+++ b/gitstatus_pre-1.7.10.sh
@@ -50,7 +50,11 @@ staged_files=$( git diff --staged --name-status )
 num_changed=$(( $( all_lines "${gitstatus}" ) - $( count_lines "${gitstatus}" U ) ))
 num_conflicts=$( count_lines "${staged_files}" U )
 num_staged=$(( $( all_lines "${staged_files}" ) - num_conflicts ))
-num_untracked=$( git ls-files --others --exclude-standard $(git rev-parse --show-cdup) | wc -l )
+if [[ "$__GIT_PROMPT_SHOW_UNTRACKED_FILES" != "no" ]]; then
+  num_untracked=$( git ls-files --others --exclude-standard $(git rev-parse --show-cdup) | wc -l )
+else
+  num_untracked=0
+fi
 
 num_stashed=0
 if [[ "${__GIT_PROMPT_IGNORE_STASH}" != "1" ]]; then

ogr3 avatar Mar 14 '19 19:03 ogr3

https://github.com/magicmonty/bash-git-prompt/pull/491 is merged now. @yilkalargaw Could you confirm that this solves your issue?

guenhter avatar Oct 10 '22 07:10 guenhter