DEV Community

Cover image for Customize Git Bash shell
Blikoor
Blikoor

Posted on • Edited on

Customize Git Bash shell

Due to the need to maintain backward compatibility, newer features of Bash are rarely enabled by default. MinGW64 (Minimalist GNU for Windows x64) has to be configured to take full advantage of these features. Improve your productivity with several simple tweaks that can enhance Bash out-of-the-box without using external stuff. I will assume that Git for Windows and optionally also Windows Terminal are already installed.

Customize Startup Files

The Git bash shell is invoked as an interactive login shell for Git-only authentication access. 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 Profile

1. Create a ~/.bash_profile file. The .bash_profile contains commands for setting the shell's environment variables. A ~/.bash_profile can be used instead of ~/.profile but is read by Bash only. Since the shell is interactive, the ~/.bashrc file is not sourced. Refer to the Bash Manual for more information. Copy everything below into your own file.



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


Enter fullscreen mode Exit fullscreen mode

Bash shell Script

2. Create a ~/.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 everything below into your own 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


Enter fullscreen mode Exit fullscreen mode

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. I believe that this is the recommended method 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


Enter fullscreen mode Exit fullscreen mode

3. Create a ~/.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. Copy everything below into your own file.



# 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"


Enter fullscreen mode Exit fullscreen mode

User Configuration

4. Create a ~/.inputrc file. This file contains commands to configure command history, directory display, and keyboard bindings using the built-in GNU Readline library. Refer to the Bash Manual, and Readline Documentation for more information.



# 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


Enter fullscreen mode Exit fullscreen mode

The Readline library also provides several useful shortcuts.

Keyboard shortcut Description
Control-A Go to beginning of line.
Control-E Go to the end of the line.
Alt-B Go back one word.
Alt-F Go forward on word.
Alt-Backspace Delete backward one word.
Alt-D Delete forward one word.
Control-R Search back through history.
Control-R Cycle backward through history.
Control-Shift-R Cycle forward through history.
Alt-. Append an argument of the previous command.

Finished Result

5. After the customization is done, restart the terminal or open a new Git Bash tab in Windows Terminal. Your Git Bash should look similar to the result below.
Image description

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. Refer to 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


Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
lauro235 profile image
Lauro

Hi Blikoor,

Really loved the article! I wanted to get your thoughts. I'm experiencing a slight problem with the setup as you've implemented above. When I tab folder names without including cd it seems to look through all files in my pc. Lot's of files that aren't in the current directory are displayed. Would you be able to give me some pointers in how to correct this?

One other bit of minor feedback. Beginners might not know what the tilde ~ sign is. I think it's important to be a bit more explicit here.

It's a really great article overall though. Thank you so much!

Collapse
 
tmomoh profile image
T-Momoh

Hi Bilkoor, I ran the following lines:

lines omitted

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

and got the response:
bash: syntax error near unexpected token `fi'

Can you help with this please?