loading...
Cover image for Work faster with Git aliases

Work faster with Git aliases

peterj profile image Peter Jausovec ・4 min read

Back when I started with programming, there was no Git yet.
I tried using Visual Sourcesafe a couple of times for some pet projects and the only thing I do remember about Visual Sourcesafe is that the database would become corrupted quite often.

Visual Sourcesafe user interface

If you're interested in some history about VSS and its issues, check out this article or this one here.

When I started my first job, the team I worked in was using a company-internal source code control system (I tried remembering the name of it, but I can't - I'll update the post as soon as I remember the name. UPDATE: Source Depot was the name). Shortly after that, we moved the source code over to the TFS (Team Foundation Server) that was using Team Foundation Version Control.

Team Foundation Server user interface

Later, we would eventually move to Git. At the beginning of my career, I was using Visual Studio heavily, and all source code control commands were available from the user interface (they were also available from the console, but most of the work got done in the user interface).

One feature I liked about TFS was the ability to create shelvesets that could get easily shared with others. The equivalent of this in Git today is probably creating a branch and pushing it. For a little while, after I've started using Git, I'd still miss shelvesets, but once I got used to the way Git does things with branches the need for shelvesets went away.

Git Aliases

Ok, enough of history, let's talk about Git aliases. I have a bunch of them in my .gitconfig file, but I don't use all of them too often. I still like to use the GUI (I am using Sourcetree, which is free for both Windows and Mac), especially for merges.

Here's the link to my full .gitconfig file - note that most of these probably came from the repos I based my dotfiles on ( https://github.com/jfrazelle/mac-dev-setup and https://github.com/mathiasbynens/dotfiles).

In addition to the aliases, I also have an alias set for the Git binary, so I don't have to type all three letters, and I can only type g (huge time/type savings, I know :)).

I've grouped the aliases below - note that there are way more aliases in my config file (related to finding stuff, diffing, merging, etc.), however, I probably never used them, and that's why I haven't mentioned them. I do most of the searching and merging in the GUI.

Basic aliases

These are mostly shortcuts, rather than more complicated commands.

# View the current working tree status using the short format
s = status -s

# Clone a repository including all submodules
c = clone --recursive

# List all tags
tags = tag -l

# Lists all remote and local branches
branches = branch -a

# List remotes with URLs
remotes = remote -v

Command below shows how you can clone a repo:

g c [repo]

Working with forks

This is something you need to do quite often. I have two different aliases to do this - one merges the upstream master into local (origin) fork (fu) and the second one makes the fork even with the upstream master, discarding all local changes (fuf).

# Merges upstream master into local (origin) fork
fu = !"git fetch upstream; git checkout master; git merge upstream/master"

# Makes the fork even with the upstream master, discarding all local changes
fuf = !"git fetch upstream; git checkout master; git reset --hard upstream/master; git push origin master --force"

Branches

I use an alias called go to either switch to an existing branch, or create a new one if it doesn't exist. This is one of those commands I use fairly often:

# Switch to a branch, creating it if necessary
go = "!f() { git checkout -b \"$1\" 2> /dev/null || git checkout \"$1\"; }; f"

# Remove branches that have already been merged with master a.k.a. ‘delete merged’
dm = "!git branch --merged | grep -v '\\*' | xargs -n 1 git branch -d"

Commits

Amend alias is the one I use if I want to add current changes to the latest commit (instead of creating a new commit):

# Amend the currently staged files to the latest commit
amend = commit --amend --reuse-message=HEAD

Do you have any favorite Git aliases that you're frequently using?

UPDATE: The internal source code control we used was called Source Depot (found an article about it here)

Posted on Mar 22 '19 by:

peterj profile

Peter Jausovec

@peterj

Software engineer, author and international speaker. https://learncloudnative.com

Discussion

markdown guide
 

Aliases are great - they can really save a lot of time, but I always caution people from using them too much. If you ever end up in a spot where you don't have any of your aliases, you'll be struggling to remember the original command.

 

This is a good point. You can commit your aliases to a Github gist, or other online source control, just in case.

 

Good point. I usually have all my settings in a Github repo where I can pull it down if needed.

 

Nice article! I use git aliases heavily -- I personally use the zsh shell with oh-my-zsh, which comes with a huge list of git aliases in the form of a plugin (github.com/robbyrussell/oh-my-zsh/...)

It's great!

 

s = stash
st = status
cp = cherry-pick
co = checkout

I use Android Studio (Intellij-based) to checkout remote branches via GUI or the co alias to create a local branch with "git co -b ". s and st come into play in many pull-requests because I can make test modifications and revert back to where I was. Lastly, cp is useful because "cherry-pick" is very annoying to type out correctly.

 

I love aliases so much, I have A TON, but the most useful are these:

rv = !git stash && git stash drop

pr = remote update --prune

rmb = !sh -c 'git push origin :refs/heads/$1 && git branch -D $1' -
rmt = !sh -c 'git push origin :refs/tags/$1 && git tag -d $1' -

This next list is all of the log aliases that I have...and I'd be lost without them:

l   = log --abbrev-commit --first-parent --pretty=format:'%C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'
ll  = log --abbrev-commit --graph --pretty=format:'%C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'

ld  = log --abbrev-commit --first-parent --pretty=format:'%C(bold blue)%ai%C(reset) - %C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'
lda = log --abbrev-commit --graph --pretty=format:'%C(bold blue)%ai%C(reset) - %C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'

la  = log --abbrev-commit --name-status --first-parent --pretty=format:'%C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'
lla = log --abbrev-commit --name-status --pretty=format:'%C(dim white)%h%C(reset)%C(bold green)%d%C(reset) %s %C(yellow)<%an>%C(reset)'

lg  = !git lg1
lg1 = !git lg1-specific --all
lg2 = !git lg2-specific --all
lg3 = !git lg3-specific --all

lg1-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(bold yellow)%d%C(reset)'
lg2-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
lg3-specific = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset) %C(bold cyan)(committed: %cD)%C(reset) %C(bold yellow)%d%C(reset)%n''          %C(white)%s%C(reset)%n''          %C(dim white)- %an <%ae> %C(reset) %C(dim white)(committer: %cn <%ce>)%C(reset)'
 

Nice point. I have all my settings in a Github repo. it works very great.
Dubai’s leading multi-brand Sharp TV Repair Dubai. Get the best price on tv repairing,
Effective and at the nominal prices. Get your tv repaired by our expert technicians.

 
 

Thanks for the article, but (yes, the infamous but) maybe you would consider adding a short paragraph early on explaining what a git alias is? I didn't know about them before and even though I found it obvious upon reading your article it would be nice to get an explanation early on.
/a git novice