Powerlevel9k: Question mark doesn't go away in git repository

Created on 20 Jul 2015  Â·  22Comments  Â·  Source: Powerlevel9k/powerlevel9k

Just updated to the latest version (c853be57e7efa79f9818394e3aec7900a6a35516) from a fairly old one, and now I can't seem to get rid of the question mark in the git vcs segment.

Here's a screenshot:
screen shot 2015-07-19 at 4 06 03 pm

Most helpful comment

Woops, I just completely overlook the fact that the .DS_Store file was untracked. Adding a .gitignore solved the problem. Sorry!

All 22 comments

The line that causes the problem is at https://github.com/bhilburn/powerlevel9k/blob/10c5b28859d372f480c1352d4b7a74672e77b430/powerlevel9k.zsh-theme#L183

A proposed fix is in PR #61

The problem is that wc -l returns a string with whitespace characters in it:

 '       0'

This string is then compared to the number 0 using [[ $string != 0 ]].
That comparison will always return true unless the whitespace is stripped out somehow. In this case , by using tr -d ' '.

On a related note: What's with the pipe to sed q ? What does that do?

Fixed in commit 7f83bac947893175ef937e26f1a3bc8a389d1718 by reverting to using tr -d ' '

@natemccurdy - Thank you so much for reporting this, finding the root cause, and submitting a pull request for it. This was the first time (that I'm aware of) that we broke master, which is a big deal, and so I super appreciate your time tracking this down and documenting your findings.

Strangely, the problem didn't exist for me - I tested it out before merging #57, and I imagine @dritter did, as well. I wonder if there is a difference in how wc behaves on different systems regarding whitespace in the output.

Regarding your question around the purpose of sed -q, after looking at it... I honestly don't know. I adapted the git hooks originally from @tupton, and didn't modify that. Looking through the docs, honestly, I can't figure out the reasoning for it. I might play with removing it and see what happens.

@bhilburn Happy to help! This is, by far, my favorite zsh prompt.

Strange that it worked for you. In a ZSH session, what does true | wc -l return for you?
Here's my output:
screen shot 2015-07-19 at 6 28 26 pm

Uh. Didn't see that coming.. :(

true | wc -l return 0 for me (on Mac OSX).. Even the GNU-variant of wc return 0 (true | gwc -l)..

I'll rework that later on..

sed q just returns as soon as there's a match. In this case it means that it returns as soon as there's any output at all instead of printing all of the git output.

There's probably a more efficient way to do that – I'm not completely sure why head -1 doesn't do the same thing, or if cutting off the output to just the first line even does anything in terms of speed or efficiency – but it works and is fast enough for me.

@natemccurdy @dritter - Yeah, it returns a raw 0 character for me, using wc (GNU coreutils) 8.21 on Fedora 20.

@tupton - Thanks for weighing in! You still have a credit at the top of the theme, btw ;)

Interesting... so sed q effectively stops parsing and returns as soon as it sees something. That's pretty useful, honestly. I'm not sure how head handles streams - as you hypothesized, it may be slower in terms of just taking the first line and returning. Thanks!

I'm on OSX 10.10.4, and I imagine this "bug" will only affect OSX users.

When I use the built in wc, the problem appears. But when I use gwc from brew install coreutils, there's no issue:
screen shot 2015-07-20 at 2 04 38 pm

I am on OSX 10.9.4, and I found wc on my machine is linked to gwc from coreutils. This is the reason, why I didn't see it!
With /usr/bin/wc I can reproduce this error. Perfect! Now I can work on a solution.

Interesting... so sed q effectively stops parsing and returns as soon as it sees something. That's pretty useful, honestly. I'm not sure how head handles streams - as you hypothesized, it may be slower in terms of just taking the first line and returning.

http://stackoverflow.com/questions/15632691/fastest-way-to-print-a-single-line-in-a-file

@tupton - Awesome reference. Thanks!

Interesting that the author for the accepted answer recommends sed, even though head -1 is actually faster.

When the difference is 1µs, I start to think it might not matter or that you might need to sample a huge number of runs to really see the difference and determine if it's meaningful.

I think the main point is that it's constant (and fast!) regardless of the size of the file.

Of course, @dritter has a point and we might not even need head or sed.

@tupton You are right! Benchmarking first is the way to go.

Here is my benchmark: I have a file with 2,095,680 Lines of Text (7.3GB).

Testscript with test -n

time ./testscript.sh
DID NOT FINISH!

I cancelled this one after about 10 minutes..

Testscript with sed q | wc -l

time ./testscript.sh
match!
./testscript.sh  0,01s user 0,01s system 100% cpu 0,017 total

Testscript with sed q | test -n

time ./testscript.sh
match!
./testscript.sh  0,01s user 0,01s system 86% cpu 0,017 total

So the use of sed q makes sense. Interestingly test -n seems to read the whole string, instead of returning true after the first character..

@bhilburn I prefer the last variant. At least we avoid the use of wc and stripping its output. I'll update my PR.

Here is my testscript.sh:
#!/bin/sh

if [[ -n $(cat test.txt) ]]; then
    echo "match!"
fi

#if [[ $(cat test.txt | sed q | wc -l) != 0 ]]; then
#       echo "match!"
#fi

#if [[ -n $(cat test.txt | sed q) ]]; then
#       echo "match!"
#fi

After sleeping a night over this, it is now clear to me, why test -n fails... If we do $(cat test.txt) the whole file gets loaded into the memory. The other solutions just pipe it to sed q..
_facepalm_ for overseeing this..

Was this ever fixed? I'm getting a question mark here as well (all latest, fonts are correct as far as I can tell)

Same here, getting a question mark. Is there any fix?

Whoa, weird. Yes, this was fixed a long time ago. What do you see when you do git status?

https://github.com/bhilburn/powerlevel9k/commit/56bc1b3f47e4dbe72ef13a3227dd90682c6dbea8#diff-790a1b679113b7ea09863d24414b58ba

The changes discussed here were modified as of that commit. Not saying that commit broke this fix, but the regression probably happened after that, if there is one. I think the change there could be changed to … | sed q if git status --porcelain is what you want to stick with.

FYI, for always listing untracked files even in subdirectories, you could temporarily change directories with something like pushd $(git rev-parse --show-toplevel) 2>&1 >/dev/null && git ls-files --others --exclude-standard | sed q && popd 2>&1 >/dev/null. git ls-files is just so much better than git status | grep for this type of check. This doesn't get around the fact that ls-files doesn't deal with submodules very well, but perhaps that could be optional for anyone who _really_ needs submodule untracked file status.

Woops, I just completely overlook the fact that the .DS_Store file was untracked. Adding a .gitignore solved the problem. Sorry!

@louiswolfers so it forces you to add .gitignore and even .vscode/ on git.
anyway to leave those things and still get rid of this question mark?

@aaveidt Well you could use a global .gitignore file, where you add all the stuff to be ignored over all projects. It should work to create a .gitignore file in your Home Directory and add .vscode there..

Was this page helpful?
0 / 5 - 0 ratings

Related issues

agungsetiawan picture agungsetiawan  Â·  6Comments

hackerwin7 picture hackerwin7  Â·  4Comments

yoyoys picture yoyoys  Â·  3Comments

jpdoria picture jpdoria  Â·  5Comments

xufab picture xufab  Â·  4Comments