Simple and fast prompt for bash which can show git repo status
- It prints a useful prompt, for easy plugging into PS1.
- It can tell if you’re standing in a git repo or if you’re outside of one. Depending on the situation, it will use one of the two main prompt types.
- I’m a bash user, and
- bash functions to update the prompt when standing in a git repo is just too slow
Source the contents of profile
into your bash shell. There’s a lot
of stuff in there, mostly commented, but the core of it is:
prompt_cmd() {
PS1="$(/path/to/generate-prompt)"
}
PROMPT_COMMAND=prompt_cmd
Generate-prompt was designed to be configured. The defaults should work well enough, but if you want to modify the look of the prompt, read on.
export GP_GIT_PROMPT="[\pR][\pL][\pC]\n$ "
The strings in the example above which begin with \p
are
three-character Instructions which generate-prompt looks for. These,
if found, are replaced with other content.
For example, \pC
is replaced with the name of the current working
directory you’re standing in.
Currently supported Instructions:
\pR
replaced with the git repo name*\pL
replaced with the local branch name*\pC
replaced with the current working directory(cwd)*\pa
replaced with number of commits local is ahead of upstream\pb
replaced with number of commits local is behind of upstream\pd
replaced with combination of\pa
and\pb
. ”(a:-b)
”\pK
replaced with warning about conflicts in git repo, if there are any*\pi
replaced with “(interactive rebase)” if in that state.\pP
replaced with prompt symbol # or $ depending on user*
\* \pr
, \pl
, \pc
, \pk
, \pp
for uncoloured versions of the above
Note that upper-case Instructions are decorated with Pre- and postfix patterns (see below)
Instructions can be further configured using Styles.
The part of the prompt which shows the current working directory, is
governed by the \pC
Instruction. To change its style, you
can set the environment variable GP_WD_STYLE
to one of styles
below.
- If unset or set to
basename
,\pC
will output the basename of CWD. - If set to
cwd
, output the full path from the user’s$HOME
. - If set to
gitrelpath_inclusive
, output the full path from git-root, including the project name - If set to
gitrelpath_exclusive
, output the full path from git-root, excluding the project name. This is nice in that it doesn’t repeat the name of the project when standing at the root of the repo, but then there is no text to colour when the repo is not in up-to-date state. To address this, there’s an environment variable you can use to set what is written at the root of the repo:GP_WD_STYLE_GITRELPATH_EXCLUSIVE
.For example:
export GP_WD_STYLE=gitrelpath_exclusive export GP_WD_STYLE_GITRELPATH_EXCLUSIVE='☃️'
This would make
\pC
expand to the complete path from the root of the git repo to the directory you’re standing in, and replace the name of the repo with ☃️.
You can override the default string used to indicate an ongoing
interactive rebase by setting the GP_REBASE_STYLE
environment
variable.
For example:
export GP_REBASE_STYLE="(interactive rebase)"
This would make the prompt show the string “(interactive rebase)” when the repo you’re standing in is in the interactive rebase state.
Generate-prompt can tell when the local repo has diverged from the
upstream ref. What is shown in the prompt in these situations is
governed by the three Instructions \pa
(ahead), \pb
(behind), and
\pd
(both ahead and behind of upstream ref). To change what these
look like, set one or all of the following environment variables:
GP_A_DIVERGENCE_STYLE
GP_B_DIVERGENCE_STYLE
GP_AB_DIVERGENCE_STYLE
These are used directly as printf formats, so you’ll need to set %d
in them to specify where the diffs should be displayed.
For example, if we’re behind by 1 and ahead by 2, and you set these like so:
export GP_A_DIVERGENCE_STYLE="(%d)"
export GP_B_DIVERGENCE_STYLE="(-%d)"
export GP_AB_DIVERGENCE_STYLE="(%d,-%d)"
Then \pa
will expand to “(1)”, \pb
will expand to “(-2)”, and
\pd
will expand to “(1,-2)”.
These are environment variables which override some particular part of the default look of generate-prompt.
Generate-prompt will look for Instructions (see above) inside of these patterns, and replace them with specific strings which depend on the current context.
GP_DEFAULT_PROMPT
is a pattern which overrides the hard-coded prompt
you see when not in a git repo. It is passed as-is to stdout, so your
normal PS1 prompt can be set here.
Example:
export GP_DEFAULT_PROMPT="\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[01;34m\]\W\[\033[00m\] $ "
GP_GIT_PROMPT
pattern overrides the hard-coded git prompt you see
when in a git repo. After some string replacements are done, it is
passed to stdout like it does with the default prompt.
Example:
export GP_GIT_PROMPT="[\pR][\pL][\pC]\n$ "
You may have noticed that there are three peculiar substrings in the
example above, which start with a \p
, followed by a character. These
are the Instructions mentioned above.
Some Instructions will decorate the output with colours, depending on context.
For example, if you are standing in a git repo and change a tracked
file, then the current working directory Instruction (\pC
) will
change the colour of its output to indicate a status change. Once the
change is staged, it will once again revert to its original colour.
Prefix patterns:
export GP_UP_TO_DATE="\033[0;32m"
export GP_MODIFIED="\033[0;33m"
export GP_CONFLICT="\033[0;31m"
export GP_NO_DATA="\033[0;37m"
Postfix patterns:
export GP_RESET="\033[0m"
Though these are all currently used for colours, one can use these for arbitrary text.
GP_WD_STYLE_GITRELPATH_EXCLUSIVE
(sic)
- Install dependencies:
- With homebrew:
brew install libgit2 bats-core
- With apt:
sudo apt install libgit2-dev bats
- With homebrew:
- Run
make
to build generate-prompt. (tested on mac and ubuntu) make local-install
installs at ~/binsudo make install
installs at /usr/local/binmake clean
cleans things up.