⚡ Speed up everyday work with handy Git aliases

mradzikowski

Maciej Radzikowski

Posted on September 17, 2020

⚡ Speed up everyday work with handy Git aliases

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.

carbon (3)

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.

carbon (4)

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.

carbon (5)

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!

carbon (6)

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.

carbon (7)

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:

If you have your own favorite aliases, share them in the comments.

💖 💪 🙅 🚩
mradzikowski
Maciej Radzikowski

Posted on September 17, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related