Customize Git Bash Shell to Make it Yours

· 10 mins

If you are a web developer but work mainly on Windows environments like me, you may have known about Git Bash. It's based on MinGW64 (Minimalist GNU for Windows x64). It serves well for its purpose but sometimes it's kind of boring. Due to the need to maintain backward compatibility, newer features of Bash are rarely enabled by default. WSL is a good replacement but it needs configurations on the system level. Not very handy if you work in a limited access system. So back to Git Bash, no worries, we can tweak it a little bit to enhance the experience. In this tutorial, I will assume that you installed Git for Windows and (optionally) Windows Terminal.

Customize startup files

Bash uses a few startup files to configure the shell environment for users. It will source files like ~/.bash_profile, ~/.bash_login, and ~/.profile in the order given. The first readable file that exists is sourced.

Bash profiles

Create ~/.bash_profile file. The .bash_profile contains commands for setting the shell's environment variables. Since the shell is interactive, the ~/.bashrc file is not sourced. Copy the following content to the file:

# Source the ~/.bashrc file if it exists
if [ -f ~/.bashrc ]
then
. ~/.bashrc
fi

Bash shell script

Create ~/.bashrc file. The .bashrc file contains commands that are specific to the Bash shell. It is the best place for aliases and bash-related functions. Copy the following content to the file:

# Git aliases
alias gs='git status -sb'
alias gcc='git checkout'
alias gcm='git checkout master'
alias gaa='git add --all'
alias gc='git commit -m $2'
alias push='git push'
alias gpo='git push origin'
alias pull='git pull'
alias clone='git clone'
alias stash='git stash'
alias pop='git stash pop'
alias ga='git add'
alias gb='git branch'
alias gl="git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
alias gm='git merge'

# Bash aliases
alias .='cd .'
alias ..='cd ..'
alias ...='cd ../../'
alias ....='cd ../../../'
alias .....='cd ../../../../'
alias bashclear='echo "" > ~/.bash_history'
alias cls='clear'
alias ls='ls -F --color=auto --show-control-chars'
alias ll='ls -l'
alias ll.='ls -la'
alias lls='ls -la --sort=size'
alias llt='ls -la --sort=time'
alias rm='rm -iv'
alias work='cd /c/repos'

# Bash shell settings
# Typing a directory name just by itself will automatically change into that directory.
shopt -s autocd

# Automatically fix directory name typos when changing directory.
shopt -s cdspell

# Automatically expand directory globs and fix directory name typos whilst completing.
# Note, this works in conjuction with the cdspell option listed above.
shopt -s direxpand dirspell

# Enable the ** globstar recursive pattern in file and directory expansions.
# For example, ls **/*.txt will list all text files in the current directory hierarchy.
shopt -s globstar

# Ignore lines which begin with a <space> and match previous entries.
  # Erase duplicate entries in history file.
  HISTCONTROL=ignoreboth:erasedups

# Ignore saving short- and other listed commands to the history file.
HISTIGNORE=?:??:history

# The maximum number of lines in the history file.
HISTFILESIZE=99999

# The number of entries to save in the history file.
HISTSIZE=99999

# Set Bash to save each command to history, right after it has been executed.
PROMPT_COMMAND='history -a'

# Save multi-line commands in one history entry.
shopt -s cmdhist

# Append commands to the history file, instead of overwriting it.
# History substitution are not immediately passed to the shell parser.
shopt -s histappend histverify

Git Bash prompt

The Git Bash prompt is set by a shell script called git-prompt.sh and can be found in the c/Program\ Files/Git/etc/profile.d directory. Notice that in lines 8-10, a custom ~/.config/git/git-prompt.sh file will be sourced, if it exists. This is our chance to override the default settings.

# lines omitted
if test -f ~/.config/git/git-prompt.sh
then
. ~/.config/git/git-prompt.sh
else
# lines omitted
fi
# lines omitted

So let's create ~/.config/git/git-prompt.sh file. The git-prompt.sh file contains commands for setting the title of the Git Bash terminal and the Bash prompt string. This is where you decide how your prompt will look like. Here is an example setting:

# Custom prompt settings
PROMPT_DIRTRIM=4                         # Shorten deep paths in the prompt
PS1='\[\033]0;Git | Bash v\v | \W\007\]' # set window title
PS1="$PS1"'\n'                           # new line
PS1="$PS1"'\[\033[30;45m\] [\A] '        # black text, magenta, 24h time
PS1="$PS1"'\[\033[30;42m\] \u '          # black text, green, user
#PS1="$PS1"'\[\033[30;42m\]@\h '          # black text, green, @host
PS1="$PS1"'\[\033[30;43m\] \w '          # black text, yellow, working director
if test -z "$WINELOADERNOEXEC"
then
GIT_EXEC_PATH="$(git --exec-path 2>/dev/null)"
COMPLETION_PATH="${GIT_EXEC_PATH%/libexec/git-core}"
COMPLETION_PATH="${COMPLETION_PATH%/lib/git-core}"
COMPLETION_PATH="$COMPLETION_PATH/share/git/completion"
if test -f "$COMPLETION_PATH/git-prompt.sh"
then
. "$COMPLETION_PATH/git-completion.bash"
. "$COMPLETION_PATH/git-prompt.sh"
PS1="$PS1"'\[\033[97;46m\]'  # white text, cyan
PS1="$PS1"'`__git_ps1`'      # bash function
fi
fi
PS1="$PS1"'\[\033[0m\]'        # change color
PS1="$PS1"'\n'                 # new line
PS1="$PS1"'$ '                 # prompt: always $

# Git status options
# Shows * or + for unstaged and staged changes, respectively.
export GIT_PS1_SHOWSTASHSTATE=true

# shows $ if there are any stashes.
export GIT_PS1_SHOWDIRTYSTATE=true

# Shows % if there are any untracked files.
export GIT_PS1_SHOWUNTRACKEDFILES=true

# shows <, >, <>, or = when your branch is behind, ahead, diverged from,
# or in sync with the upstream branch, respectively.
export GIT_PS1_SHOWUPSTREAM="auto"

User configuration

Create ~/.inputrc file, where you will able to configure command history, directory display, and keyboard bindings using the built-in GNU Readline library.

# Disable beeps & bells, and do not display control characters.
set bell-style none
set echo-control-characters off

# The TAB key cycles forward through the completion choices.
# Press an arrow key, such as right-arrow, to choose a selection.
TAB: menu-complete

# The Shift-TAB key cycles backward through the completion choices.
# Like TAB, press an arrow key, such as right-arrow, to choose a selection.
"\e[Z": menu-complete-backward

# The first TAB key press will display a list that match the given prefix.
# The next TAB key press will start cycling through the available choices.
set menu-complete-display-prefix on

# Display completion matches upon the first press of the TAB key.
#set show-all-if-ambiguous on

#Enable colors when completing filenames and directories.
set colored-stats on

# Completion matches of multiple items highlight the matching prefix in color.
set colored-completion-prefix on

# Ignore case when completing.
set completion-ignore-case on

# Treat hypens and underscores as equivalent when completing.
set completion-map-case on

# Append the / character to the end of symlinked directories when completing.
set mark-symlinked-directories on

# Enable incremental history navigation with the UP and DOWN arrow keys.
# This will use the already typed text as a required prefix.
"\e[A": history-search-backward
"\e[B": history-search-forward

Here are some shortcuts provided by the Readline library:

Keyboard shortcutDescription
Control-AGo to beginning of line.
Control-EGo to the end of the line.
Alt-BGo back one word.
Alt-FGo forward on word.
Alt-BackspaceDelete backward one word.
Alt-DDelete forward one word.
Control-RSearch back through history.
Control-RCycle backward through history.
Control-Shift-RCycle forward through history.
Alt-.Append an argument of the previous command.

Bash utilities

Some Bash utilities are also included with Git for Windows and may be used to enhance your Git experience if the default behavior is not desired. These utilities will need to be configured in each independent development environment. Check out the Pro Git Book for more information.

The git-completion and git-prompt scripts can be found in the following directory: /c/Program\ Files/Git/mingw64/share/git/completion/. Copy the git-completion.bash and git-prompt.sh to your home directory.

To use the scripts append the following lines to the ~/.bashrc file.

# Enable tab completion for Git commands
source ~/.git-completion.bash
# Change bash prompt to display current Git branch and status
source ~/.git-prompt.sh

Thanks to @Blikoor.

> comment on threads / twitter
> cd ..