{"action":"created","issue":{"url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/3725","labels_url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/3725/labels{/name}","comments_url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/3725/comments","events_url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/3725/events","html_url":"https://github.com/robbyrussell/oh-my-zsh/pull/3725","id":64646779,"number":3725,"title":"Timebox `git status` checks inside prompt_info","user":{"login":"apjanke","id":2618447,"avatar_url":"https://avatars.githubusercontent.com/u/2618447?v=3","gravatar_id":"","url":"https://api.github.com/users/apjanke","html_url":"https://github.com/apjanke","followers_url":"https://api.github.com/users/apjanke/followers","following_url":"https://api.github.com/users/apjanke/following{/other_user}","gists_url":"https://api.github.com/users/apjanke/gists{/gist_id}","starred_url":"https://api.github.com/users/apjanke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apjanke/subscriptions","organizations_url":"https://api.github.com/users/apjanke/orgs","repos_url":"https://api.github.com/users/apjanke/repos","events_url":"https://api.github.com/users/apjanke/events{/privacy}","received_events_url":"https://api.github.com/users/apjanke/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":8,"created_at":"2015-03-26T22:23:27Z","updated_at":"2015-04-23T03:59:20Z","closed_at":"2015-03-26T23:14:19Z","pull_request":{"url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/pulls/3725","html_url":"https://github.com/robbyrussell/oh-my-zsh/pull/3725","diff_url":"https://github.com/robbyrussell/oh-my-zsh/pull/3725.diff","patch_url":"https://github.com/robbyrussell/oh-my-zsh/pull/3725.patch"},"body":"UPDATE: Can't use this because it'll break any use of `coproc` by the user. Nevermind.\r\n\r\n###   Summary\r\n\r\nThis adds a user-configurable timeout to the `git status` call done inside `git_prompt_info()` so the prompt doesn't hang when you are in a slow-to-check repo, such as a very large repo or one accessed over a network file system.\r\n\r\nFixes #3009.\r\nFixes #3706.\r\nFixes #3723.\r\nMaybe #3351.\r\nFixes #1160.\r\nMaybe #38.\r\n\r\nWhen it times out, it'll include an explicit \"?\" indicator in the prompt to show that it doesn't know what the repo's status is, instead of spuriously reporting either clean or dirty.\r\n\r\nGives \"robbyrussell\" theme support for the timed-out status check, with a \"?\" indicator.\r\n\r\nThe current way to deal with slow repos is to set `git config --add oh-my-zsh.hide-status 1` to turn off status display. This has a couple drawbacks:\r\n\r\n* It requires you to identify and manually configure each slow repo.\r\n* It affects all views of configured repos, regardless of how they're accessed. Some repos may only be slow when they're accessed via a remote filesystem, so you'd still want to see their status when viewed on a fast local filesystem.\r\n* It is indistinguishable from a clean repo in the prompt's output, so you have to remember that it's been set for that repo.\r\n\r\n### Implementation\r\n\r\nUses zsh's `coproc` and `read -p -t` to put a timeout on the `git status` call inside `git_prompt_info()`.\r\n\r\nIntroduces new theme configuration variables:\r\n* `$ZSH_THEME_GIT_PROMPT_TIMEDOUT` - how the timeout appears in the theme's prompt\r\n* `$ZSH_THEME_SCM_CHECK_TIMEOUT` - how long the timeout is\r\n\r\nI chose the generic \"SCM\" instead of \"GIT\" in `$ZSH_THEME_SCM_CHECK_TIMEOUT` so the same control could be reused for `hg` and other source control systems if they want to implement timeboxing, too.\r\n\r\n###  Effects\r\n\r\nWhen you're in a slow git repo using a theme that includes git prompt info, it'll give up and show a \"?\" or other theme-defined status indicator instead of a clean/dirty indicator. Fast repos (where `git status` is <1 second, by default) work just as they did before.\r\n\r\nIf you really want it to grind out a status for every prompt, you can just set the $ZSH_THEME_SCM_CHECK_TIMEOUT to a very large number in your `~/.zshrc`.\r\n\r\nHere's an example of what it looks like in the `robbyrussell` theme. When in a repo over a slow network connection (under `/Volumes/janke`), it times out and shows a \"?\". In a fast local repo (under `~`), it shows the normal clean/dirty indicator.\r\n\r\n![git timeboxing in robbyrussell theme](https://cloud.githubusercontent.com/assets/2618447/6858325/fa69c61e-d3e3-11e4-9819-fe5de9a8c91a.png)\r\n\r\n###   Future enhancements\r\n\r\nIf this works out, it could be improved further by having `git.zsh` track which repos have been slow in this session, and skip future `git status` checks for them for the rest of the session, so the prompt would be instantaneous, instead of eating the 1-second timeout each time it's presented.\r\n"},"comment":{"url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/comments/95420559","html_url":"https://github.com/robbyrussell/oh-my-zsh/pull/3725#issuecomment-95420559","issue_url":"https://api.github.com/repos/robbyrussell/oh-my-zsh/issues/3725","id":95420559,"user":{"login":"apjanke","id":2618447,"avatar_url":"https://avatars.githubusercontent.com/u/2618447?v=3","gravatar_id":"","url":"https://api.github.com/users/apjanke","html_url":"https://github.com/apjanke","followers_url":"https://api.github.com/users/apjanke/followers","following_url":"https://api.github.com/users/apjanke/following{/other_user}","gists_url":"https://api.github.com/users/apjanke/gists{/gist_id}","starred_url":"https://api.github.com/users/apjanke/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apjanke/subscriptions","organizations_url":"https://api.github.com/users/apjanke/orgs","repos_url":"https://api.github.com/users/apjanke/repos","events_url":"https://api.github.com/users/apjanke/events{/privacy}","received_events_url":"https://api.github.com/users/apjanke/received_events","type":"User","site_admin":false},"created_at":"2015-04-23T03:59:20Z","updated_at":"2015-04-23T03:59:20Z","body":"Thanks Marc.\r\n\r\nYep: I see the same behavior on my Debian box. I guess TMPDIR and TEMP aren't as universal as I thought.\r\n\r\nI incorporated your patch in to my branch (along with a paranoid check to see if `/tmp` actually exists). Looks like it's working for me; I'll run it as well for a while.\r\n\r\n(There's another change on the branch that speeds up the parsing for the full `git_prompt_status()`, but most themes do not use that one.)\r\n\r\nThis logic is starting to feel a little long. Maybe it would be better to use `mktemp` or one of the related temp file commands. I don't know how universal *those* are either; I'll look in to them. I was also hoping to implement this without having to issue many commands or create many files, since it does get called on every prompt. (Especially for Cygwin users, where command execution overhead is higher.) (That's why I'm using a FIFO: it should require just a directory entry, and no data actually going to disk.) I suppose that in most cases this would all happen inside disk cache since the files are very short-lived. But I don't want to assume too much about people's systems.\r\n\r\nOpen to suggestions on what the Right Way to pick temp files is here, especially if it would generalize to other other temp file uses in OMZ.\r\n\r\nIf you're benchmarking, note that this change isn't intended to speed up the normal `git_prompt_dirty()` case where `git status` completes and you get the clean/dirty info for your prompt. It just avoids you getting a hung or unusably slow shell in the case where you're in a slow repo. So the worst case should be 1 second now; and ordinary cases should be unchanged. Just watch out for if it accidentally made things slower.\r\n"}}