JanDeDobbeleer / oh-my-posh

The most customisable and low-latency cross platform/shell prompt renderer
https://ohmyposh.dev
MIT License
17.37k stars 2.39k forks source link

Enabling "fetch_status" really slow in case of big git repos #1647

Closed zbouslikhin closed 2 years ago

zbouslikhin commented 2 years ago

Code of Conduct

What happened?

Hello,

As the project (therefore repo) that I'm working on is getting bigger and bigger, I have noticed lately that each time a command is run, it takes 2-10s to run it.

After investigating I came to the conclusion that the problem is because of enabling "fetch_status". As soon as I disable it, everything runs smoothly.

Theme

Unicorn, but happens in all themes if fetch_status is enable

What OS are you seeing the problem on?

Windows, Linux

Which shell are you using?

No response

Log output

Version: 6.41.0

Segments:

ConsoleTitle(true)   -   0 ms - zaidb@DESKTOP in /mnt/c/Users/name
os(true)             -   0 ms -  WSL - 
path(true)           -   0 ms -   /mnt/c/Users/name 
git(false)           -   2 ms -
time(true)           -   0 ms -   12:34:34 
executiontime(true)  -   0 ms -  ﮫ 0ms⠀
root(false)          -   0 ms -
text(true)           -   0 ms - 🦄

Run duration: 3.3605ms

Logs:

2022/01/25 12:34:34 debug: getenv

2022/01/25 12:34:34 getenv duration: 230.5µs, args: XDG_CACHE_HOME
2022/01/25 12:34:34 getCachePath duration: 277.2µs, args:
2022/01/25 12:34:34 getArgs duration: 300ns, args:
2022/01/25 12:34:34 getArgs duration: 300ns, args:
2022/01/25 12:34:34 getShellName duration: 500ns, args:
2022/01/25 12:34:34 debug: getenv

2022/01/25 12:34:34 getenv duration: 2.1µs, args: OMP_CACHE_DISABLED
2022/01/25 12:34:34 isRunningAsRoot duration: 1.7µs, args:
2022/01/25 12:34:34 getcwd duration: 38µs, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 200ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 200ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getShellName duration: 300ns, args:
2022/01/25 12:34:34 getCurrentUser duration: 400ns, args:
2022/01/25 12:34:34 getHostName duration: 1.5µs, args:
2022/01/25 12:34:34 getcwd duration: 400ns, args:
2022/01/25 12:34:34 getRuntimeGOOS duration: 300ns, args:
2022/01/25 12:34:34 debug: getenv
Ubuntu-20.04
2022/01/25 12:34:34 getenv duration: 1.8µs, args: WSL_DISTRO_NAME
2022/01/25 12:34:34 getcwd duration: 400ns, args:
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 getArgs duration: 300ns, args:
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 getRuntimeGOOS duration: 200ns, args:
2022/01/25 12:34:34 getRuntimeGOOS duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getRuntimeGOOS duration: 300ns, args:
2022/01/25 12:34:34 stackCount duration: 300ns, args:
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 debug: getenv
Ubuntu-20.04
2022/01/25 12:34:34 getenv duration: 1.8µs, args: WSL_DISTRO_NAME
2022/01/25 12:34:34 isWsl duration: 4.7µs, args:
2022/01/25 12:34:34 getcwd duration: 200ns, args:
2022/01/25 12:34:34 getRuntimeGOOS duration: 300ns, args:
2022/01/25 12:34:34 hasCommand duration: 1.8993ms, args: git.exe
2022/01/25 12:34:34 getcwd duration: 400ns, args:
2022/01/25 12:34:34 error: hasParentFilePath
stat /.git: no such file or directory
2022/01/25 12:34:34 hasParentFilePath duration: 128.2µs, args: .git
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 getcwd duration: 400ns, args:
2022/01/25 12:34:34 executionTime duration: 400ns, args:
2022/01/25 12:34:34 getcwd duration: 400ns, args:
2022/01/25 12:34:34 isRunningAsRoot duration: 600ns, args:
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 isRunningAsRoot duration: 700ns, args:
2022/01/25 12:34:34 getcwd duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 200ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 200ns, args:
2022/01/25 12:34:34 getPathSeperator duration: 300ns, args:
2022/01/25 12:34:34 getShellName duration: 400ns, args:
2022/01/25 12:34:34 getCurrentUser duration: 400ns, args:
2022/01/25 12:34:34 getHostName duration: 1.7µs, args:
JanDeDobbeleer commented 2 years ago

@zbouslikhin this can't be resolved by oh-my-posh but is something the repo needs to address. You can try the following to make the repo more performant:

haizaar commented 1 year ago

Is there a way to disable fetch_status conditionally based on the current directory? (Using .envrc or something like that)

JanDeDobbeleer commented 1 year ago

@haizaar sure, you can use the ignore_status property to exclude fetching status in certain repositories. See here.

haizaar commented 1 year ago

Thank you for the quick response! Can I set this conditionally based on an environment variable? I'd rather keep the knowledge of a git directory being too big inside the directory itself and signal OMP about it using a env var with the help of direnv

JanDeDobbeleer commented 1 year ago

@haizaar no, we don't really have that functionality. It's config based today.

haizaar commented 1 year ago

Got'ya. Eventually I've created two copies of my theme - one with fetch_status: false. On large repos I use direnv's .envrc to export POSH_THEME to point to the no-status one. A bit hacky but works fine.

Have you considered fetching git status as a background async process? - powerlevel10k does it this way and it works great, i.e. prompt appears immediately with the git status being populated (a bit) later.

JanDeDobbeleer commented 1 year ago

@haizaar I did consider that, but that would require a completely separate service. I studied powerlevel10k's implementation but it's not worth my while as it's definitely not a simple background service. I'd argue git needs to become more efficient. Although recent improvements to fsmonitor do improve things out of the box when enabled.

haizaar commented 1 year ago

Goty'a. I hope fsmonitor lands on Linux one day.

JanDeDobbeleer commented 1 year ago

@haizaar wasn't it built-in as of late?

haizaar commented 1 year ago
❯ git fsmonitor--daemon
fatal: fsmonitor--daemon not supported on this platform

I can't find any reference for it working on linux :(

JanDeDobbeleer commented 1 year ago

@haizaar are you using NixOS?

haizaar commented 1 year ago

Yes, I am indeed - 23.05. Someone else reported similar issue.

github-actions[bot] commented 10 months ago

This issue has been automatically locked since there has not been any recent activity (i.e. last half year) after it was closed. It helps our maintainers focus on the active issues. If you have found a problem that seems similar, please open a discussion first, complete the body with all the details necessary to reproduce, and mention this issue as reference.