Skip to content

Instantly share code, notes, and snippets.

@goldie-lin
Last active September 29, 2022 00:39
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save goldie-lin/c71aa2881826d32c40731c3e1cfcf491 to your computer and use it in GitHub Desktop.
git-prompt.sh re-implemented with gawk, and required git version >= 2.11.0
#!/usr/bin/env bash
git rev-parse 2>/dev/null && \
( [[ "$(git rev-parse --is-bare-repository)" == true ]] && (echo '&' ; echo "# branch.head $(git rev-parse --abbrev-ref HEAD)") || \
[[ "$(git rev-parse --is-inside-git-dir)" == true ]] && echo '@' || \
(git rev-parse --verify -q refs/stash >/dev/null && echo '$' ; git status --porcelain=v2 -b --ignored) \
) | gawk '
/^&$/ { bare++; next; }
/^@$/ { insidegit++; next; }
/^\$$/ { stashed++; next; }
/^# branch\.head / { head = $0; sub(/# branch\.head /, "", head); next; }
/^# branch\.ab / { match($0, /^# branch\.ab \+([0-9]+) -([0-9]+)$/, ab); ahead = ab[1]; behind = ab[2]; next; }
/^! / { ignored++; next; }
/^\? / { untracked++; next; }
/^[12] U. / { conflicts++; next; }
/^[12] .U / { conflicts++; next; }
/^[12] DD / { conflicts++; next; }
/^[12] AA / { conflicts++; next; }
/^[12] .M / { changed++; }
/^[12] .D / { changed++; }
/^[12] [^.]. / { staged++; }
END {
printf(" (");
if (bare != 0) {
printf("\033[1;32m%s\033[0m:\033[0;32m%s\033[0m", "BARE", head);
} else if (insidegit != 0) {
printf("\033[1;32m%s\033[0m", "GIT_DIR");
} else {
printf("\033[0;32m%s\033[0m", head);
if (stashed + ignored + untracked + conflicts + changed + staged != 0) {
printf(" ");
if (stashed ) printf("\033[1;34m$\033[0m" );
if (staged ) printf("\033[0;32m+%d\033[0m", staged );
if (changed ) printf("\033[0;31m*%d\033[0m", changed );
if (untracked) printf("\033[0;35m%%%d\033[0m", untracked);
if (ignored ) printf("\033[1;30mi%d\033[0m", ignored );
if (conflicts) printf("\033[1;41;30m!%d\033[0m", conflicts);
}
if (behind + ahead != 0) {
if (behind ) printf("\033[1;40;31m↓%d\033[0m", behind );
if (ahead ) printf("\033[1;40;36m↑%d\033[0m", ahead );
} else {
printf("\033[0m=");
}
}
printf("\033[0m)");
}'
# vim: set ft=awk:
@goldie-lin
Copy link
Author

goldie-lin commented Jan 1, 2017

It's based on josuahdemangeon's git-prompt posted on Reddit, and try to add features and tweak styles/colors to overtake the official git-prompt.sh, and make slight improvement (reduce the number of the git command calls) by using new Porcelain Format Version 2 of "git status" command introduced from Git v2.11.0.

Copy link

ghost commented Jan 1, 2017

Thank you for improving this script!

I saw you were using a shebang to bash, but you can make it compatible with any shell with very few changes https://gist.github.com/josuah/2fe1e6f145b59d4d1155dc2ab84d1cf8/revisions

Also, it seems to work with any awk, even busybox's awk, so you may not require gawk.
I tried to make light changes keeping the same coding style and indentation.

Finally, I'm using the next keyword rather than a m = 0 and m = 1 && ....

Pull some changes if you want, do not if you don't, feel free.

@goldie-lin
Copy link
Author

Thank you @josuah for your improvement, I had merged some parts of your contributions back.
I'm really glad you like it and contribute my changes back to your version.

But, now, I will stick with bash and gawk, the reason I had commented in your gist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment