Ways to Make Your Git Usage Enjoyable
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):
[code language=”bash”]
[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
[diff][/diff]
tool = Kaleidoscope
[/code]
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):
[code language=”bash”]
# 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\]\$ ‘
[/code]
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:
[code language=”text”]
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.
[/code]
Big sad.
So you then follow the instructions and you get this little gem:
[code language=”text”]
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.
[/code]
Which results in this history:
[code language=”text”]
* 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
[/code]
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:
[code language=”text”]
# 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
[/code]
And now you have a clean, bubble free history
[code language=”text”]
* 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
[/code]
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!