Git – Bash Command-line Aliases

Just as at many other companies, at Monetate we use Github as our source control system. Recently I decided to dedicate some time to create some helpful aliases to save some time. Assuming that you create new branches all based off of your “master” branch these aliases may be helpful for you as well:

	# Show a log of all commits with any pertinent files listed below each
	# commit.
	lo = "log --name-only --color --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

	# Creates a new branch and checks it out.
	b-co = checkout -b

	# Remove the specified local branch.
	b-rm = branch --delete

	# Remove the specified remote branch.
	rb-rm = push --delete origin

	# A diff showing what has been added or taken away in this branch in
	# comparison to what is in master.
	b-diff = "! git diff 'HEAD~'$(git log HEAD ^master --oneline | wc -l | tr -d ' ') --color"

	# Show a log of all commits found in this branch but not in master.
	b-log = log master..HEAD --color --name-only

	# Rebase this branch, allowing for all commits added in this branch to be
	# modified.
	b-rebase = "! git rebase -i 'HEAD~'$(git log HEAD ^master --oneline | wc -l | tr -d ' ')"

	# Opens a new window in Sublime Text 2 with all the files that have been
	# modified in this branch.
	b-subl = "! cd $(git rev-parse --show-toplevel) && /Applications/Sublime\ Text\ --new-window $(git b-diff --name-status | awk '/^[^D][ \t]+(.+)/ {print $2}')"

All of the above aliases can be added to your .gitconfig file which is probably located at “~/.gitconfig“. The following explains what adding each of the above aliases actually does:

Command Description
git lo Similar to a git log but instead of printing each commit in its own block, each commit only shows on one line: efce549 - Name of the Commit (28 hours ago) <John Doe>
git b-co <new_branch_name> Creates the branch specified and then checks it out.
git b-rm <branch_name> Removes the specified local branch. In order to force the removal of the branch you can use git b-rm -f <branch_name>.
git rb-rm <remote_branch_name> Removes the specified remote branch. In order to force the removal of the remote branch you can use git rb-rm -f <branch_name>.
git b-diff Does a git diff HEAD~# where # is the number of commits found in this branch which are not found in your local master.
git b-log Shows the logs for all of the commits found in this branch which aren’t in the master branch.
git b-rebase Does a git rebase -i HEAD~# where # is the number of commits found in this branch which are not found in your local master. Especially useful for squashing all of your commits into one.
git b-subl Opens all of the files which have been updated in this branch in Sublime Text 2 (in comparison with what is in your local master). NOTE: This may need to be modified if Sublime Text 2 is not located at /Applications/Sublime\ Text\

It is important to note that you can change the “Sublime Text 2” shortcut to the editor of your choice. I just put that there to show you how to get all files that were updated in this branch to open. Have fun, and let us know if you have any modifications or additional aliases! 8)

Bash – Git PS1 Branch Based Coloring

A few coworkers have asked me why I didn’t have Git setup on my Mac so that when I am in a repository it will show which branch. I finally set that up and did a little extra inside of my ~/.bash_profile. The following lines were added to get everything working:

# has the definition of __git_ps1 and the other auto-completion stuff
. ~/git-completion.bash

# sets up the bash prompt so that when I am in a branch, it will indicate which branch
function set_bash_prompt {
    # Colors found at
    local branch=$(__git_ps1 "%s");
    if [[ "$branch" == "master" ]] 
    elif [[ "$branch" != "" ]]
    PS1='\n\[\e[4;30m\]local(\!)\[\e[0m\]:\W '$PS1'\$ '

# Tell bash to execute this function just before displaying its prompt.

After sourcing my ~/.bash_profile file, now whenever I am in the master branch, the word “master” appears underlined in red at the end of the prompt. If I am not in the master branch but am in a directory in the repository, the name of the branch will appear underlined in blue. In all other cases, the prompt will appear normal. The following are screenshots showing what I am talking about:

Informative Command Prompt with Git
Informative Command Prompt with Git

Final Notes

  1. One of the cool things I learned while setting this pu was the fact that you could assign a function to PROMPT_COMMAND to make that function run before the command prompt returns control to the user.
  2. Another cool thing that I kind of re-learned was about coloring portions of the command prompt.
  3. Go here if you are looking for a good reference for formatting your Bash command prompt the way that you want.

Bash Script – Manually Synchronize Date/Time

Although I am not a system administrator, I do have to make sure that the date/time on many different servers is correct. For some reason, the time on these servers keeps getting off by between 15 and 30 minutes. I use to simply write the sudo date -s command to reset the date but I eventually got tired of doing that. Now I use the following bash script:

# If this script wasn't run as SUDO, do it.
if [ "$(id -u)" != "0" ]; then
  MY_PATH="$( cd "$( dirname "$0" )" && pwd )/$(basename $0)"    # Path to this script.
  sudo $MY_PATH;
  echo "+------------------------------+";
  echo "+------------------------------+";
  read -p "IP Address:  " IP;
  read -p "Username:  " USERNAME;
  ssh $USERNAME@$IP "echo \\\"\`date\`\\\"" | xargs date -s;

For all of you real systems administrators, I am sure there are many better solutions as to how to synchronize the dates on servers, but our system administrator is too busy to get the solution working right now. This simple bash script does the following:

  1. Forces the script to run under SUDO privileges.
  2. Prompts the user for the remote IP address.  I always use my Mac as the remote machine.
  3. Prompts the user for the remote username.
  4. Prompts the user for the remote password.
  5. Sets the date using the date of the remote machine.

The script can be run in either of the following ways (assuming that you are in the directory with the file, the file is named, and the permissions are setup correctly [chmod 777]):

  • ./
  • sudo ./
Running this script is like doing the following (while making sure that the date is pulled from the remote machine):
sudo date -s "08/07/2012 14:30:00"