Maciej Radzikowski
Posted on September 17, 2020
This post was originally published at https://betterdev.blog/handy-git-aliases/ - check it out for more related content.
Git allows us to define aliases, which are basically our own commands we can use. They may be just a calls for other commands with parameters, or even shell scripts. Possibilities are unlimited.
Do you ever google for this Git command you forgot every time? Often execute several commands one by one, every time in the same combination for a final effect? Or saw a really nice Git command on the internet, but with way too more flags to use it in a real-life? Git aliases are the solution.
Here I will show Git aliases that I use in everyday work. With explanation.
Defining first Git alias
Aliases are part of the Git configuration that is saved to the ~/.gitconfig
file. They can be added or modified directly by editing this file, or by executing a command that will do this for us.
Let’s create an alias to the git status
command that will be just a git s
command – simple abbreviation.
git config --global alias.s status
Alternatively, we can open the ~/.gitconfig
file (creating it if it does not already exist) and add this config lines by hand:
[alias]
s = status
In both cases, we add new alias named s
for status
command. Since then those two calls are equal.
git status
git s
In ~/.gitconfig
file more aliases may be added to the [alias]
block, we don’t need to repeat it. We just add next lines under it.
Useful Git aliases for everybody
Handy shortcuts for Git commands
[alias]
s = status
c = commit
go = checkout
gob = checkout -b
d = diff
dc = diff --cached
It may look silly at first. Oh, we can save 5 letters calling git status
.
But when you start to use those short command versions, you will find it frustrating to go back. Those versions are two times shorter (including git
command call at the beginning) than normal ones. It means you execute them two times faster. And for a git status
and git commit
commands, that we usually execute multiple times a day, it’s a significant change. You stop spending time typing commands, but rather analyzing the results instead. It’s also one second of distraction from work less.
Alias I use to move between the branches, git go
, has a new alternative available from Git 2.23. It’s git switch
, which is dedicated to changing branches. But still, I prefer my shorter version.
Beautiful and meaningful Git history log
[pretty]
better-oneline = "format:%C(auto)%h%d %s %Cblue[%cn]"
[alias]
tree = log --pretty=better-oneline --all --graph
ls = log --pretty=better-oneline
ll = log --pretty=better-oneline --numstat
details = "!f() { git ll "$1"^.."$1"; }; f"
For those we need to declare a new git log
format first, so we can use it in all three aliases.
The first 3 aliases (lines #5-7) are used to show Git history in a nicer form. git tree
is my favorite one and most used, as it shows a branching graph similar to the one shown on GitHub or GitLab. Irreplaceable in a branch-based workflow.
You can think about git ls
and git ll
as an equivalent of shell ls
command for files listing. The first version will show commits history in a nice, one-line-per-commit format. The second one will additionally show modified files with a number of added and removed lines in each of them.
The custom format we define makes the output of all 3 commands nice and significant. We get short commit hash, message, author, and branch name pointing on that commit, if any.
Last one, git details
(line #9), is used to show the same statistics as git ll
, but for a single commit. We use it providing commit reference as an argument, for example, git details HEAD
to show modified files in the last commit.
This last alias has a different syntax than all previous. It starts with an exclamation mark (!
), which makes Git execute it as a shell command rather than git
command. The commands will be always executed in a root repository directory. Additionally, we need to wrap it in a function to be safe using positional arguments – see explanation here.
Plurals for listing all elements
[alias]
branches = branch -a
tags = tag
Those two aliases are very helpful, especially for beginners. They make listing all branches and tags easy with just a plural form of the word. Additionally, it fixes inconsistency in commands, as we see that in a normal form showing all branches and all tags is done in a different way.
Fast files adding and committing
[alias]
a = !cd ${GIT_PREFIX:-.} && git add . && git s
aa = !git add -A && git s
ac = !cd ${GIT_PREFIX:-.} && git add . && git c
aac = !git add -A && git c
Those commands will speed up committing but needs to be used with care.
git a
will add files from our current directory and subdirectories to the index/staging area, ready to be committed. It will also show git status
right away, so you will see what is the state of your repository after the call. Remember to check if no random files were added automatically with this command by a mistake.
git aa
will do a very similar thing but will add all modified files from the repository, no matter from what directory you will call it. You can memorize these two commands as “add” and “add all”.
The other two aliases are extended versions of previous ones. They will additionally commit changes. Using them is very helpful and time-saving, but we need to be sure only what we want is committed.
Clearing Git workspace and index
[alias]
unstage = reset HEAD
cleanout = !git clean -df && git checkout -- .
The first alias, unstage
, does the opposite of git aa
, that we defined previously. It’s a shortcut for removing all files from the index/staging area. It doesn’t undo changes done in the files. They just go back to the workspace.
The next alias behaves differently. It acts on the files in the workspace (not added to the staging area with git add
yet). git cleanout
will undo all changes from the files in the workspace and remove all new, never committed files. Effectively we will get a clean repository state of the last commit.
Carefully, both discard
and cleanout
will cause you loos uncommitted changes!
Undoing commits and merges
[alias]
uncommit = reset --soft HEAD~1
unmerge = reset --hard ORIG_HEAD
How many times did you realize that you committed or merged branches too soon? Here are commands to revert it easily. They do exactly what the names suggest.
git uncommit
will remove the last commit. All committed changes will go back to the index, nothing will be lost. You can change them and commit them again. This is helpful to use instead of git commit --amend
when we need to make some bigger modifications or wait longer before committing.
The other alias does a similar thing for branch merges. When we do git merge
and then git unmerge
right away, we will go back to the repository state from before the merge. This time no files will be found in the index after the command, and if we did some merge conflicts resolution – it will be lost. It’s important to know that we can do unmerge
safely only right after the merge, as it uses special pointer ORIG_HEAD
created during the merge. It may be changed by other Git commands, so calling it in any other circumstances could lead us to lose other commits and their content.
Both these commands rewrite Git history by removing commits. A good practice is not to do such operations on commits already pushed to the remote repository. In fact, without special permissions to the remote repository, we won’t be even able to push such changes. Therefore it’s best to use uncommit
and unmerge
only when we spot a mistake right after we do it, so we can fix it before it leaves our computer.
Showing Git merge details
[alias]
merge-span = "!f() { echo $(git log -1 $2 --merges --pretty=format:%P | cut -d' ' -f1)$1$(git log -1 $2 --merges --pretty=format:%P | cut -d' ' -f2); }; f"
merge-log = "!git ls `git merge-span .. $1`"
merge-diff = "!git diff `git merge-span ... $1`"
Git branch merges may cause a lot of headache, especially for beginners. Here is a way to at least understand and review what was introduced by a given merge.
While merge-span
is only a subsidiary function, merge-log
and merge-diff
show us a list of commits added by a merge and all introduced changes. We can put a merge commit hash as a parameter to review the chosen merge, otherwise, the last found merge on the current branch will be shown.
Summary
Having aliases for most common actions and using them will speed up and simplify everyday work, allowing us to get most from the version control system.
There is nothing stopping you from adding more aliases. You can create them by yourself based on your most common actions. There are also plenty of other ready to use aliases created by various people. I’ve also taken some of my aliases from them and got inspired by others. Here they are:
- https://github.com/GitAlias/gitalias
- https://gist.github.com/robmiller/6018582
- https://gggritso.com/human-git-aliases
If you have your own favorite aliases, share them in the comments.
Posted on September 17, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.