Install and Setup Cygwin

I recently started a new job for part-time work while in school. As with any new tech job, I went through the process of customizing my Windows box with all the settings, configurations and programs I like. As part of this process I setup Cygwin.

If you aren’t familiar with Cygwin as a Windows user, I hope you will be some day. Cygwin is basically a command line interface (CLI) and set of tools that emulates a Linux environment on Windows. I prefer Cygwin over the basic CLI that comes with Windows because I can use the programs familiar to *Nix users in addition to the autocomplete functionality with Git. I can customize my shell and thank goodness for that! It definitely makes me more efficient and feel more at home. If you’re still using the command prompt for Windows, it’s time to branch out and try something new. It’s valuable to understand how to navigate and script in the Windows CLI, but it’s also worth looking into Cygwin.

As I was going through the process I took note of all the details for future reference. Here’s a list of the packages I suggest you include in your installation of Cygwin:

  • openssh
  • git
  • vim
  • curl
  • bash completion
  • xinit & X-start-menu-icons (if you plan on using gitk)

Cygwin will tell you to install their various dependencies. Just do what it says :).

Here’s what my .bash_profile looks like. It’s a little bit different from the .profile on my Mac:

##################
### MY ALIASES ###
##################

# git command autocompletion script
source ~/bin/git-completion.bash

# navigate to C:\
alias cdc='cd /cygdrive/c'

# navigate to C:\Source\Certus
alias certus='cd /cygdrive/c/Source/Certus'

# git commamands simplified
alias gst='git status'
alias gco='git checkout'
alias gci='git commit'
alias grb='git rebase'
alias gbr='git branch'
alias gpl='git pull'
alias gpu='git push'
alias gad='git add -A'
alias gmt='git mergetool'
alias bdf='git diff'
alias glg='git log --date-order --all --graph --format="%C(green)%h%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'
alias glg2='git log --date-order --all --graph --name-status --format="%C(green)%H%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'

# ls alias for color-mode
alias ls='ls -lha --color=always'

# up 'n' folders
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias .....='cd ../../../..'

# processes
#alias ps='ps -ax'

# refresh shell
alias reload='source ~/.bash_profile'

###############################
### ENVIRONMENTAL VARIABLES ###
###############################

# Update PATH with private bin
export PATH="${HOME}/bin:${PATH}"

# Show clean/dirty state for Git in prompt
export GIT_PS1_SHOWDIRTYSTATE=1

# Change prompt
PS1_OLD=${PS1}
export PS1='\[\033[1;34m\]\!\[\033[0m\] \[\033[1;35m\]\u\[\033[0m\]:\[\033[1;35m\]\W\[\033[0m\] \[\033[1;92m\]$(__git_ps1 "(%s)")\[\033[0m\]$ '

# Display variable for gitk
export DISPLAY=:0.0

#################
### PROCESSES ###
#################

# Run XWin Server
startxwin >/dev/null 2>&1 &

As an aside, while I was using Git I realized there was no color for my git status (aka gstat) commands, so I turned on the color: git config --global color.ui true. For a list of other useful configurations to explore, checkout Customizing Git.

I also installed the Perforce’s P4Merge visual merge tool for resolving conflicts when using Git. You can read about how to set that up with Git from the same link above.

Show Current Git Branch in Bash Prompt

Current Git Branch In Bash Prompt

If you’ve added autocomplete functionality for Git using the git-completion.bash script, then you’re in for a treat. You can use a function of the script to show the current Git branch in your Bash prompt. All you have to do is a little snippet to your $PS1 environment variable like so:

PS1='\! \u:\W$(__git_ps1 "(%s)")\$ '

With color, mine looks like this:

export PS1='\[\033[1;34m\]\!\[\033[0m\] \[\033[1;35m\]\u\[\033[0m\]:\[\033[1;35m\]\W\[\033[0m\] \[\033[1;92m\]$(__git_ps1 "(%s)")\[\033[0m\]\$ '

To test the functionality, navigate to a git repository in your shell. Wahla! Magic.

**UPDATE: 2013-01-25**

Dirty/Clean Status in Prompt

If you want to see the dirty/clean status of your current branch in the command prompt next to the branch name, simply add this line to your bash_profile/bashrc if you’re already using __git_ps1:

export GIT_PS1_SHOWDIRTYSTATE=1

Explanation from git-completion.bash:

# In addition, if you set GIT_PS1_SHOWDIRTYSTATE to a nonempty
# value, unstaged (*) and staged (+) changes will be shown next
# to the branch name. You can configure this per-repository
# with the bash.showDirtyState variable, which defaults to true
# once GIT_PS1_SHOWDIRTYSTATE is enabled.

Troubleshooting __git_ps1 Error

If you’re getting an error like -bash: __git_ps1: command not found in the command prompt and your branch name isn’t showing up in the command prompt, try sourcing the git-completion.bash that comes with your Git install (assuming you have installed Git via Homebrew, which I’d recommend for Mac users.) The code would look like something like this:

# git command autocompletion script
source /usr/share/git-core/git-completion.bash

Leverage Git Config & Autocomplete Git Commands

Git Logo

I’ve already discussed customizing your shell and command prompt. To me, it is equally important to leverage Git configuration and autocomplete Git commands. You should also check out how to show the current Git branch in your Bash prompt.

Git Config

There are a lot of cool things you can do to customize Git just the way you like it. Most of these ideas are personalized versions of the git config customizations found at the Git website.

To create succinct, efficient commands in Git, create aliases for both the shell and for Git. Add the following code snippet to your .profile or .bash_profile:

alias gst='git status'
alias gco='git checkout'
alias gci='git commit'
alias grb='git rebase'
alias gbr='git branch'
alias gpl='git pull'
alias gpu='git push'
alias gad='git add -A'
alias gmt='git mergetool'
alias bdf='git diff'
alias glg='git log --date-order --all --graph --format="%C(green)%h%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'
alias glg2='git log --date-order --all --graph --name-status --format="%C(green)%h%Creset %C(yellow)%an%Creset %C(blue bold)%ar%Creset %C(red bold)%d%Creset%s"'

Next add the following code to your ~/.gitconfig file:

[alias]
st = status
co = checkout
ci = commit
rb = rebase
br = branch
pl = pull
pu = push
ad = add
mt = mergetool
df = diff
lg = log --graph --name-status --oneline

Now reload your shell and you’re good to go. I’d also recommend you configure the following settings:

  • Color UI. Adds color to commands like git status so you can read the output more easily. It’s as simple as git config --global color.ui true.
  • Code Editor. I like to use vim, but Sublime would be a great alternative. git config --global core.editor vim.
  • Diff & Merge Tool. I downloaded the DiffMerge app for my MacBook Pro and the P4Merge for my Windows box. These tools allow me to compare code or resolve code conflicts when I run into them. This is worth the time it takes to set up before hand. Read how at Customizing Git – Git Configuration: External Merge and Diff Tools.

Below is what my .gitconfig file looks like now (Updated 2012-09-28):

[user]
        name = John Doe
        email = johndoe@doe.com
[alias]
        st = status
        co = checkout
        ci = commit
        rb = rebase
        br = branch
        pl = pull
        pu = push
        ad = add
        mt = mergetool
        lg = log --graph --name-status --oneline
[core]
        editor = vim
        #autocrlf = true
[color]
        ui = true
[merge]
        tool = kdiff3
        ff = true
[mergetool "kdiff3"]
        path = /usr/local/bin/kdiff3
        #path = C:/Program Files (x86)/KDiff3/kdiff3.exe

        guitool = kdiff3
[difftool]
        path = /usr/local/bin/kdiff3
        #path = C:/Program Files (x86)/KDiff3/kdiff3.exe

Autocomplete Git Commands

To add autocomplete for your Git commands, download the git-completion.bash file. The easiest way I know to do it is by using the following curl command in the shell:

curl https://github.com/git/git/raw/master/contrib/completion/git-completion.bash -OL

The -O options tells curl to output a local file with the same name as the remote file. Thus, the name of the file is extracted from the given URL.

The -L option allows curl to redirect if the appropriate location is indicated with a Location: header and a 3XX response code. curl will redo the request using the new location.

Once you get the the git-completion.bash file, find a place to store it permanently. I put mine with the rest of my shell scripts in ~/bin. Then add the following code snippet to your .profile or .bash_profile file:

source ~/git-completion.bash