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 = firstname.lastname@example.org [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 email@example.com:juliomistral/TestMainRepo.git ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'firstname.lastname@example.org: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.
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 - email@example.com, 1 year, 6 months ago * 710c1d3 Initial commit - firstname.lastname@example.org, 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 - email@example.com, 1 year, 6 months ago * 710c1d3 Initial commit - firstname.lastname@example.org, 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!