Bash aliases
Ever wondered why ll
spits out something sensible on your distribution, but not on others? Even though there is no executable called ll
?
Bash allows the user (or your distribution) to set what is called an “alias”. By defining what should be done when the user types in ll
, bash knows what to do and just executes this.
For the ll
example, this is done using a line like the following:
alias ll='ls -lh'
So by typing ll
, what you are really executing is ls -l
. And when typing ll <TAB>
(ll
followed by a space and the tab key) you get all the nice bash completion features that are available when using ls
directly.
Of course, this does not only work for ls
but also for other things. Like git…
Defining git aliases
When your bash is started, some files are being read and all settings used for your current shell session. Depending on which type of shell is being started (login shell?), this can be ~/.profile
, ~/.bash_profile
or ~/.bashrc
. The exact order should be similar on all distributions, however some distributions seem to mess with this. I will go into some more detail about this in another blogpost. To make sure your efforts won’t be useless, add a line like echo "I am being executed"
to each of these files, and check which ones are being read.
After you found out which file to use, add the lines from the example file dot_bashrc to your file (shown here without comments):
This line will tell your bash to look for a file called .alias
in your home directory.
The example file contains a whole range of aliases. Of course, you can also put those into ~/.profile
or ~/.bash_profile
or maybe even somewhere in /etc/
if you want to set this for all your users on the system.
alias g='git st'
alias g.='git st .'
alias ga='git add'
alias ga.='git add .'
alias gap='clear; git add -p'
alias gbr='git br'
alias gbrd='git br -d'
alias gbra='git br -a'
alias gci='git commit'
alias gcia='git commit --amend --no-edit'
alias gcim='git commit -m'
alias gco='git checkout'
alias gcob='git checkout -b'
alias gcp='git cherry-pick'
alias gd='clear; git diff'
alias gd.='clear; git diff .'
alias gdc='clear; git diff --cached'
alias gf='git fs'
alias glg='git lg'
alias glol='git lol'
alias gm='git merge --no-edit'
alias gme='git merge --edit'
alias gmne='git merge --no-edit'
alias gmff='git merge --ff-only --no-edit'
alias gmnf='git merge --no-ff --no-edit'
alias gp='git push'
alias gpdo='git push --delete origin'
alias gpu='git push --set-upstream'
alias gre='git rebase'
alias grem='git rebase master'
alias grei='git rebase -i'
alias greim='git rebase -i master'
alias grec='git rebase --continue'
alias grea='git rebase --abort'
alias gres='git rebase --skip'
alias greh='git reset HEAD'
alias gsa='git submodule add'
As you can see, we can define lots of aliases, that come in handy during daily work. Adding files, committing, switching branches, checking out new branches, all of this is just some keys away:
Easy, isn’t it?
(For those of you who are not familiar with git, I have created a new branch and a new file, committed this file and pushed my changes to my remote).
*** Also, during rebasing the greim
, grea
or grec
aliases are very useful. Because rebasing is extremely powerful and extremely dangerous to get wrong (not for the faint of heart), we will go into detail in a later blogpost. ***
So, you can define bash aliases yourself and make them do whatever you want. Nice, eh?
More complex git aliases
A second place where you can define aliases is gits’ own configuration file ~/.gitconfig
. This allows you to either use the bash alias g
(for git status
) or use a short form with plain git, like git st
.
The example file contains some of my git aliases.
[alias]
st = status
ci = commit
co = checkout
br = branch -vv
fs = !git fetch --all && git status && git merge --ff-only
fe = fetch --all
pl = pull
ps = push
re = rebase
cp = cherry-pick
lol = log --oneline --graph --decorate
lg = log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --
You might note that some are just abbreviations of normal git commands, while others look strange. What’s with the exclamation mark for fs
? And what is all that stuff for lg
? Actually both are really simple and really useful…
git fs
does not just call for one git command, but rather runs a sequence of bash commands. I use this alias a lot in projects only I am working on, when using multiple branches is just to much of a hassle. Not using guit pull
but rather git fs
prevents you from having lots of merge commits, if your local branches are behind origin/master but you already made commits. Rebase comes in handy here.
git lg
(or glg
if you use the bash alias) allows you to have a very detailed yet easy-to-understand overview of your current branches history. It shows all commits in reverse-chronological order, including branches!
Bash completion for your own aliases
So, we have created bash aliases and git aliases, but where is that tab completion thingy I talked about?
The dot_bashrc example file not only contains the instructions to read the aliases from ~/.alias
, but also this part:
if [ -s /etc/bash_completion.d/git.sh ]
then
. /etc/bash_completion.d/git.sh
__git_complete g _git
__git_complete g. _git
__git_complete ga _git_add
__git_complete ga. _git_add
__git_complete gap _git_add
__git_complete gbr _git_branch
__git_complete gbra _git_branch
__git_complete gbrd _git_branch
__git_complete gci _git_commit
__git_complete gcia _git_commit
__git_complete gcim _git_commit
__git_complete gco _git_checkout
__git_complete gcob _git_checkout
__git_complete gcp _git_cherry_pick
__git_complete gd _git_diff
__git_complete gd. _git_diff
__git_complete gm _git_merge
__git_complete gme _git_merge
__git_complete gmff _git_merge
__git_complete gmnf _git_merge
__git_complete gdc _git_diff
__git_complete gpdo _git_push
__git_complete gp _git_push
__git_complete gpu _git_push
__git_complete gre _git_rebase
__git_complete grem _git_rebase
__git_complete grei _git_rebase
__git_complete greim _git_rebase
fi
First, we check if the git.sh
file, provided by the git or git-core package, is existing on our system. Please note that the path to this file will differ, depending on your distribution. Usually, a command like rpm -ql git-core|grep bash
or dpkg -L git|grep bash
will do the trick.
After that we make bash read that file (using the .
syntax, which is equivalent to source
). Once all those git bash completion things are available, we tell bash which alias should use which type of bash completion. ga
adds files to the index, so it should use the same bash completion as git add
, while gbrd
is used for deleting branches and should only autocomplete branch names.
Note that not every alias needs auto-completion. So things like gf
(aka git fs
) are not mentioned here.
And now for something completely different
Basically, this is all you need to do to get aliases working. But it is not all you can do. In a second blogpost, I will show how to make the bash prompt show some git information, like which branch you own or if you have modified files or a saved stash. Until then, have fun with aliases!