The Flexibility of Git Bash for Windows


This is an exploration into the world of command-line git. If you are new to git or new to the command-line I would recommend taking a look through the Pro Git book if you want to learn more. From this point on I am going to assume you use, or at least are familiar with, git bash as pictured below.

Git Bash

Here she is in all her glory

Any code blocks beginning with ‘$’ represent a command to be entered into this git bash command-line interface.

Allow me to explain how easy it is to shape this environment to maximize productivity. One concept that is ingrained into my mind as a developer, is to abhor redundancy and inefficiency. As much as I have always loved git, I was initially frustrated with having to type the same verbose commands tens to hundreds of times every day. After learning my most common commands and a little research, I was able to come up with some aliases to reduce the numbers of characters for these tasks.

Simple Aliases

You can see a number of aliases here:

  • git status -> gs
  • git add -A -> gaa
  • git commit -> gc

This was done by adding lines in a configuration file to define these aliases. Git bash runs on top of the bash shell, which reads configuration from a .bashrc file located in your home directory (typically C:\Users\<UserName> and referred to as ~/ within bash).

If the file doesn’t already exist, you must create it yourself. You can either Right-Click in Windows Explorer and create a New Text File naming it ‘.bashrc..’ (Windows needs those two trailing dots to allow you to save the file) or within the bash shell run the following command:

$ touch ~/.bashrc

Either way you should now have the required file. Then with the editor of your choice simply add whatever aliases you wish to have into that file in this format (any line starting with ‘#’ is a comment and is ignored).

# Aliases
alias gs="git status"
alias ga="git add"
alias gaa="git add -A"
alias gd="git diff"
alias gc="git commit"

Git Aliases

Git also has its own system for aliases.

I use these primarily for commands where I want git tab-completion (you can see I get a list of branches for ‘git co’ in the image above)

  • git branch -> git br
  • git checkout -> git co

These aliases can be added from the bash shell with one-line commands.

$ git config --global checkout
$ git config --global branch

This will add these aliases into your ~/.gitconfig file in the same directory as the .bashrc mentioned early. Feel free to take a look at everything in that file. More information on ‘git config’ can be found online.

This is only the beginning. You can do some pretty impressive things by building on this idea.

Advanced Aliases

I find it useful to view a graphical history of a repository. Some GUI tools for Windows such as SourceTree allow you to do this, but this power is also accessible in the command-line with the “git log — graph” command. I like mine with many bells and whistles. Check the documentation for what these modifiers all do.

  • gl -> git log — graph — full-history — all — color — decorate=short

This is added with one line in my ~/.bashrc file

alias gl="git log --graph --full-history --all --color --decorate=short"

I found myself frequently switching back and forth between bash and Windows Explorer to open up Solution Files (*.sln) in Visual Studio. Thinking there must be a better way, I came up with this script in my ~/.bashrc file.

# opens first .sln file in current directory in Visual Studio
function vs { /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0/Common7/IDE/devenv `ls *.sln | sort -n | head -1` & disown; }

This lets me quickly get to Visual Studio when needed. A short command “vs” will grab the first *.sln file in my current directory and spawn a new instance of Visual Studio to load it up.

How does this work?

  • I create a function named ‘vs’ which is invoked like any other command in bash
  • This function runs Visual Studio located on my hard drive at “C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe” which is run through bash with the command “/c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0/Common7/IDE/devenv”
  • I want to pass to Visual Studio the first solution file in the directory and I do that with another bash command “ls”
  • “ls *.sln” lists all solution files in the current directory”
  • ls *.sln | sort -n” lists those files sorted by name, one line at a time”
  • ls *.sln | sort -n | head -1" shows just the first line from that output
  • `ls *.sln | sort -n | head -1` (backticks, not quotes) takes that result and enables me to use it in my function
  • “& disown” on the end causes this process to spawn in the background, and not tied to the bash shell

More about bash scripting can be found throughout the Internet.

One More Thing

Occasionally, I’ve found myself faced with the task of having to manually copy over every changed file to the production system. With a little bit of convincing, git can give me a list of added/modified files between branches.

But what if I have a hundred of these files? I’m not going to find each file and copy it over manually. So I came up with this script in my ~/.bashrc file:

# Generate production deployment patch folder e.g.: git-live-patch ~/live-patch-2015-04-01
function git-live-patch { cp --parents `git diff-tree -r --name-only --diff-filter=ACMRT "$1"` "$2"; }

I can then safely copy over this folder and overwrite the old files without worry.

What Now?

Take git bash and make it your own. Spend some time to make aliases and make your life easier. Soon you won’t know how you ever lived without them.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.