Be Present Now

durdn is here talking about tech stuff. or so he says.

Must Have Git Aliases: Advanced Examples

Over the course of a few years I piled up a long list of git aliases. This post will assume you know what aliases are and you have defined a few for yourself.

I rely on many of them dozens of times a day. And maybe some have slipped your radar. Maybe you've never thought you could do some of these useful things with an alias. Let me show you some of the cool things you can do.

You can add all the examples below to the [alias] section of your .gitconfig.

To acquire the full list of my aliases you can check out my .gitconfig on Github.

Explore your history, the commits and the code

Shorten and beautify your log command because you will use it a lot. I have a ton of list(ls) and inspection commands that I use constantly. I recommend you experiment with the examples below and come up with your own variation. I type git ls and git ll several dozens of times a day.

List commits in short form, with colors and branch/tag annotations. My bread and butter log command is invoked with git ls and looks like this:

git ls

And you can have it by adding this to your aliases section:

ls = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate

List commits showing changed files is invoked with git ll and looks like this:

git ll

And you can have it with this:

ll = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --numstat

List with no colors if you need to chain the out put with Unix pipes:

lnc = log --pretty=format:"%h\\ %s\\ [%cn]"

List oneline commits showing dates:

git lds

With the line:

lds = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=short

List oneline commits showing relative dates:

git ld

With the line:

ld = log --pretty=format:"%C(yellow)%h\\ %ad%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --date=relative

And closing the listing aliases, here is the default look for short git log:

le = log --oneline --decorate

Show the history of a file, with diffs

You can see all the commits related to a file, with the diff of the changes with git log -u which i shortened to fl for filelog:

filelog = log -u
fl = log -u

Log commands to inspect (recent) history

I constantly check what was in the last commit and so I used to type git log --numstat -1 a lot. But now it's only dl and dlc.

Show modified files in last commit:

dl = "!git ll -1"

Show a diff last commit:

dlc = diff --cached HEAD^

And if the commit you want to inspect is not the last one the typical git command becomes even longer. For this you definitely need a shortcut. Example usage:

git dr

Show content (full diff) of a commit given a revision:

dr  = "!f() { git diff "$1"^.."$1"; }; f"
lc  = "!f() { git ll "$1"^.."$1"; }; f"
diffr  = "!f() { git diff "$1"^.."$1"; }; f"

Finding files and content inside files (grep)

Find a file path in codebase:

f = "!git ls-files | grep -i"

Example usage:

[nick][u12:~/dev/projects/durdn-com]
$ git f trenches
source/drafts/2012-11-12-more-curated-git-tips-from-the-trenches.html.md

Search/grep your entire codebase for a string:

grep = grep -Ii
gr = grep -Ii

Example usage:

[nick][u12:~/dev/projects/durdn-com]
$ git gr trenches
source/drafts/2012-11-12-more-curated-git-tips-from-the-trenches.html.md:title: "More Curated Git Tips From The Trench
source/drafts/2012-11-12-more-curated-git-tips-from-the-trenches.html.md:## More Curated Git Tips From The Trenches
source/drafts/2012-11-17-must-have-git-aliases-advanced-examples.html.md:    $ git f trenches
source/drafts/2012-11-17-must-have-git-aliases-advanced-examples.html.md:    source/drafts/2012-11-12-more-curated-git

Grep from root folder:

gra = "!f() { A=$(pwd) && TOPLEVEL=$(git rev-parse --show-toplevel) && cd $TOPLEVEL && git grep --full-name -In $1 | xargs -I{} echo $TOPLEVEL/{} && cd $A; }; f"

Going meta: List all your Aliases (la)

Sometimes you forget all your aliases and don't want to open .gitconfig just to check. This simple alias git la will output all your aliases:

la = "!git config -l | grep alias | cut -c 7-"

Rename [branch] to done-[branch]

In some of my workflows I wanted to quickly rename branches prepending done- to their names. Here is the alias that came out of that workflow:

done = "!f() { git branch | grep "$1" | cut -c 3- | grep -v done | xargs -I{} git branch -m {} done-{}; }; f"

Assume aliases

If you interact with big corporate projects - like Java projects under Subversion - you might run into the need to ignore certain files which are under subversion control but you need to modify them but not commit. The assume-unchanged flag comes to the rescue.

Assume a file as unchanged:

assume = update-index --assume-unchanged

Unassume a file:

unassume = update-index --no-assume-unchanged

Show assumed files:

assumed = "!git ls-files -v | grep ^h | cut -c 3-"

Unassume all the assumed files:

unassumeall = "!git assumed | xargs git update-index --no-assume-unchanged"

Assume all:

assumeall = "!git st -s | awk {'print $2'} | xargs git assume"

Tag aliases

Show the last tag:

lasttag = describe --tags --abbrev=0
lt = describe --tags --abbrev=0

Merge aliases

Being the Branch/Integration manager at my current client, I use these constantly to merge stuff:

ours = "!f() { git co --ours $@ && git add $@; }; f"
theirs = "!f() { git co --theirs $@ && git add $@; }; f"

Bonus: Basic Shortcuts

Of course I use a ton of basic shortcuts, here's a few ingrained in my fingertips:

cp = cherry-pick
st = status -s
cl = clone
ci = commit
co = checkout
br = branch 
diff = diff --word-diff
dc = diff --cached

Reset Commands

r = reset
r1 = reset HEAD^
r2 = reset HEAD^^
rh = reset --hard
rh1 = reset HEAD^ --hard
rh2 = reset HEAD^^ --hard

Git-svn shortcuts

svnr = svn rebase
svnd = svn dcommit
svnl = svn log --oneline --show-commit

Stash operations

sl = stash list
sa = stash apply
ss = stash save

For the full list of my aliases you can check out my gitconfig on Github. And I know you'll ask so here is pre-emptively the answer: the colorscheme for my shells and editors is Solarized at the moment.

comments powered by Disqus