Ways to Make Your Git Usage Enjoyable

by

As powerful and useful as Git is, it’s not all fun and games.  It can be down right intimidating and hard to use.

But with some customization on your part, and some changes to your team’s Git workflow, Git can become a far more tammer beast to conquer.

Configuring Git:  It Can Do That?!?!

When I’m helping out one of the other guys with a git problem, I always get a major sad because they don’t have git setup all nice and pretty like I do.  And what do I have?

  • Color output when I run git status
  • Aliases for the common commands:  status, checkout and checkin
  • Automatic white-space fixing

So here’s the setup I like which I put into my global Git config file (~/.gitconfig):

[user]
    name = Julio A. Mistral
    email = jmistral@grio.com

[color]
    diff = auto
    status = auto
    branch = auto
    interactive = auto
    ui = true
    pager = true

[color "status"]
    added = green
    changed = yellow
    untracked = red

[core]
    excludesfile = $HOME/.gitignore
    pager = less -FRSX
    whitespace = fix,-indent-with-non-tab,trailing-space,cr-at-eol

[alias]
    ci = commit
    co = checkout
    st = status
    lg = log --graph --pretty=format:'%C(yellow)%h%C(cyan)%d%Creset %s %C(white)- %an, %ar%Creset'
    dtc = difftool --cached

[difftool "Kaleidoscope"]
    cmd = ksdiff-wrapper git \"$LOCAL\" \"$REMOTE\"

[difftool]
    prompt = false


    tool = Kaleidoscope

And I add this little nugget to my ~/.bash_profile so that I can get Git autocomplete and a status on my prompt (current HEAD and whether my working branch is dirty):

# Set git autocompletion and PS1 integration
if [ -f /usr/local/git/contrib/completion/git-completion.bash ]; then
  . /usr/local/git/contrib/completion/git-completion.bash
fi

GIT_PS1_SHOWDIRTYSTATE=true
PS1='\[\033[32m\]\u:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '

Ridding Your Team of those Pesky Merge Bubbles

So you just finished a new feature, committed it, and are now ready to push it out of the nest and up to origin. But then you get this:

    To git@github.com:juliomistral/TestMainRepo.git
     ! [rejected]        master -> master (non-fast-forward)
    error: failed to push some refs to 'git@github.com:juliomistral/TestMainRepo.git'
    hint: Updates were rejected because the tip of your current branch is behind
    hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
    hint: before pushing again.
    hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Big sad.

So you then follow the instructions and you get this little gem:

    Merge branch 'master' of github.com:juliomistral/TestMainRepo
    
    # Please enter a commit message to explain why this merge is necessary,
    # especially if it merges an updated upstream into a topic branch.
    #
    # Lines starting with '#' will be ignored, and an empty message aborts
    # the commit.

Which results in this history:

    *   8f7e922 (HEAD, master) Merge branch 'master' of github.com:juliomistral/TestMainRepo - Julio A. Mistral, 4 seconds ago
    |\  
    | * 1dc0a3d (origin/master, origin/HEAD) Another commit that happened and was pushed up - Julio A. Mistral, 7 minutes ago
    * | 6bf4e46 New feature to be pushed up - Julio A. Mistral, 8 minutes ago
    |/  
    * 1413896 Test checkin on local branch tracking master - julio@yola.com, 1 year, 6 months ago
    * 710c1d3 Initial commit - julio@yola.com, 1 year, 6 months ago
 

Bigger sad (unless you like multi-color ASCII art, in which case go buck wild).

This is just useless: you commit a merge that has zero relevancy. There was no conflict to resolve and you weren’t even merging another branch into master. You just wanted to push your change up. Over time, and with commits coming in from a team of developers, this creates a difficult history to follow rife with useless “Merge this into that” commit messages

So this is what you do:

    # Preserve any local changes you have 
    # that will get blown away with next step
    git stash save
    
    # Reset to last commit before merge bubble commit
    git reset --hard HEAD~1
    
    # Pull with rebase
    git pull --rebase
    
    # Push your change up, guilt free
    git push origin HEAD

And now you have a clean, bubble free history

    * 8f34b08 (HEAD, origin/master, origin/HEAD, master) New feature to be pushed up - Julio A. Mistral, 10 minutes ago
    * 1dc0a3d Another commit that happened and was pushed up - Julio A. Mistral, 9 minutes ago
    * 1413896 Test checkin on local branch tracking master - julio@yola.com, 1 year, 6 months ago
    * 710c1d3 Initial commit - julio@yola.com, 1 year, 6 months ago

And these are just 2 of the things you can do to make Git easier to use. The great thing about Git is that it is very customizable and has a large, vibrant community improving it every day.

Here’s a list of some useful plugins/add-ons that you should take a look at and happy Git-ing!

Leave a Reply

Your email address will not be published. Required fields are marked