git prompt: faster count of untracked files #3294

Closed
wants to merge 3 commits into
from

Projects

None yet

4 participants

@nomaed
Contributor
nomaed commented Aug 9, 2016

In a repository with 18k untracked files (by accident, node_modules not in .gitignore), counting them using count (git ls-files) was causing a considerable lag with prompt generation.

After changing it to git ls-files | wc -l, the count process is at least twice as fast. Not ideal, but it avoids caching the entire git ls-files result as a string to count the number of lines by piping the result through wc -l directly.

@nomaed
Contributor
nomaed commented Aug 9, 2016

Test/demo:

$ cat count-fish
#!/usr/bin/env fish
count (git ls-files --others)

$ cat count-wc 
#!/usr/bin/env fish
git ls-files --others | wc -l

$ time -p ./count-fish
20930
real 0.18
user 0.15
sys 0.02

$ time -p ./count-fish
20930
real 0.17
user 0.14
sys 0.02

$ time -p ./count-fish
20930
real 0.19
user 0.15
sys 0.02

$ time -p ./count-wc
20930
real 0.09
user 0.04
sys 0.03

$ time -p ./count-wc
20930
real 0.06
user 0.03
sys 0.02

$ time -p ./count-wc
20930
real 0.09
user 0.04
sys 0.02
@faho
Member
faho commented Aug 9, 2016

Minor nit: You can pipe to string trim as well (wc -l | string trim) instead of nesting command substitutions.

@faho faho added the enhancement label Aug 9, 2016
@faho faho added this to the next-2.x milestone Aug 9, 2016
@nomaed
Contributor
nomaed commented Aug 9, 2016

@faho Good point, done.

@krader1961 krader1961 commented on the diff Aug 10, 2016
share/functions/__fish_git_prompt.fish
@@ -478,7 +478,7 @@ function __fish_git_prompt_informative_status
set -l dirtystate (math (count $changedFiles) - (count (echo $changedFiles | grep "U")))
set -l invalidstate (count (echo $stagedFiles | grep "U"))
set -l stagedstate (math (count $stagedFiles) - $invalidstate)
- set -l untrackedfiles (count (command git ls-files --others --exclude-standard))
+ set -l untrackedfiles (command git ls-files --others --exclude-standard | wc -l | string trim)
@krader1961
krader1961 Aug 10, 2016 Member

Why is | string trim required? The wc -l portion of that command will return a single line that the fish sub-command will turn into a single value since it strips (i.e., ignores) a trailing newline.

@nomaed
nomaed Aug 10, 2016 edited Contributor

@faho commented about it, so I made the change
#3294 (comment)

Edit: I thought at first that you were talking about why piping instead of using a string trim with a sub-command. As @floam wrote, the reason is exactly that there are leading spaces that are saved and the string needs to be trimmed.

@krader1961
krader1961 Aug 10, 2016 Member

Right. I forgot that there are brain-dead wc implementations (e.g., the BSD one) that left-pad the value with spaces.

@floam
Member
floam commented Aug 10, 2016 edited

@krader1961 The spaces will not be ignored:

> set -l foo (command git ls-files --others --exclude-standard | wc -l)
> echo $foo
     102
@krader1961
Member

Thanks. Merged as dc02587.

@krader1961 krader1961 closed this Aug 10, 2016
@krader1961 krader1961 modified the milestone: fish 2.4.0, next-2.x Sep 3, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment