My Favourite Git Tips

Here are a few of my favourite git tips I’ve lovingly collected into my .gitconfig that have saved me lots of time.

Save future time!

Deletes old branches you’ve already merged

git branch --merged upstream/master | grep -v master | xargs git branch -d

What this does is:

  • finds all branches that have been merged to upstream/master
  • greps master (so you don’t delete master!)
  • deletes all those branches (a soft delete — if you want to overwrite you’d have to use git branch -D)

This command deletes all old branches that you’ve merged into master.

For example, when I was working on Piecemeal, I had a list of branches like this:

feat/all-dishes-markup 
feat/all-dishes-socket-api
bugfix/duplicate-websocket-bug-all-dishes
doc/all-dishes-docco
feat/gruntfile-build
refactor/css-migration

Many of them were eventually merged into master after my PRs were looked at. However, I had an ugly list of branches to see whenever I did git branch -v, many of which were outdated. This command cut the list down immediately.

It’s lovely when you can do git branch and see only the relevant branches!

Viewing changed lines before staging and committing

This is also another favourite of mine — whenever you run git diff you can see the changed lines side by side. After I picked this up and added it to iTerm, I blazed through reviewing my commits like never before!

You have to first install git icdiff, and once that’s done, run:

git icdiff

Now you can see side by side the changes — before & after, with deleted lines in red and added ones in green:

Git diff, nicely visualized side by side.

Another one that people seem to like is:

git diff --color-words

Where the changes are inline (as opposed to different lines) and in colour. However, I’m not a huge fan of it — YMMV.

Git diff but in one line.

You can play around with the colours easily if you’re using iTerm — after going through many existing themes I was happiest to customize mine.

Visualize a pretty history

git log returns such an ugly and unfriendly output that this was the first command I changed in my .gitconfig when I first started learning Git. After experimenting, this is what I have settled on:

git log --pretty=format:'%h %Cgreen %ar %Creset | %s%C(yellow)%d %Cblue[%an]' --graph --date=short

Which basically means

  • %h: abbreviated commit hash
  • %Cgreen %ar: Author date, relative, in green
  • %Creset: reset colour back to default
  • %s: Subject, or commit message
  • %C(yellow)%d: Ref name in yellow
  • %Cblue[%an]: Author’s name in blue and square brackets
  • — graph: Text-based graphical rep of commit history (as you can see, “Merge pull request #…” connects different branches)

Sometimes I also include — max-count=9 when I want to only see the latest 9 commits.

You get something like this:

git log prettified!

Pretty and easy to visualize!

Cherry picking

This is great for situations where you commit changes to the wrong branch. You can invoke git checkout branch-name] (or cut a new branch) to navigate back to the right branch, and copy the commit(s) over, using git cherry-pick. You can find the hashes (shortened ones are fine) using the git log trick I showed above :)

Then, return to the branch with the commits wrongly applied, and use git log to find the latest commit before you applied the mistaken commit. Invoke git reset — hard [latest-correct-commit-hash].

Stashing

If you don’t know git stash, you’re in for a real, real treat. It’s great when you want to travel around different branches but you don’t want to make a commit to your working tree just yet. Another situation where it comes in handy is when you’ve made unstaged changes to a different branch, and want to move those changes to the correct branch.

If the branch you want to move the unstaged changes to doesn’t exist, you can simply do

git checkout -b [branch-name]

and your changes will automatically be moved to this branch.

However, if you have a specific branch you want to move to, simply

git stash

and your unstaged changes will be saved to a ‘stash’ within Git. Make your changes (i.e., git checkout [branch-name]) and then

git stash apply // OR
git stash pop

and your changes will be moved! The only difference between the two is that pop will well, pop your stashed changes off the stack, whereas for apply, you can do them again and again.

Squashing

Have a million little commits that you want to squash into one? You can do git rebase -i HEAD^[number of commits to look back], such as git rebase -i HEAD^6 to look at the past 6 commits made.

From there, vim or a text editor of your choice will pop up, and give you the choice to squash certain commits.

My git aliases

It’s actually kind of crazy how much time I’ve saved over a year by making a git alias as git pom rather than git push origin master. Here are some of my git aliases to you!

Protip: You can also type alt + ‘.’ to repeat your last command. I use it constantly so that I don’t have to type a long filepath every time.

Really simple ones

co = checkout 
br = branch
pom = push origin master
pum = pull upstream master
st = status
di = icdiff
dc = diff --cached
dicolor = diff --color-words

Staging, committing, rebasing.

I like to remember things as ‘uncommitting’ or ‘unstaging’ rather than trying to remember them all. This can be helpful:

rsb = rebase --autostash 
unstage = reset
uncommit = reset --soft HEAD^
redev = pull --rebase upstream dev
remas = pull --rebase upstream master
devmerge = reset --hard upstream/dev
opull = git fetch --all && git reset --hard origin/dev
deploy = push heroku master

And here are more iTerm/shell specific things I like:

Show which branch you’re on

Show which branch you’re on.

I stuck to iTerm rather than switching to zsh, but wanted to have the capability to see which branch I was on. Cue Git Aware Prompt — now it shows every time I fire up my iTerm.

Git branch autocompletion

Autocompletes local/remote branch names, local/remote tag names, file names, git subcommands, and tree paths! Get it here.


Hope that was helpful! I’m always on the lookout for more and will add when I find them!


Originally published at codepen.io.