Dotfiles - Git Config with Aliases
Michael Currin
Posted on September 6, 2020
Setting up git aliases and core settings in your git config
See my full Git config on GitHub.
Most of this post is focused on git aliases, with bit of core settings at the end.
If you are new to git aliases, see this dev.to post.
Setup aliases
Here is the format - add aliases to your ~/.gitconfig
file, which uses TOML format.
[alias]
MY_ALIAS = "GIT_COMMAND"
MY_ALIAS = "! MY SHELL COMMAND"
Git aliases
Here is a sample based on my Git config file.
[alias]
st = "status -s -b"
c = "commit"
# --all
# --verbose
br = "branch -a -v"
co = "checkout"
cb = "checkout -b"
# Short hash, relative date and message.
logd = "log --pretty='%C(yellow)%h %C(cyan)%ar %Creset%s'"
# --graph:
# Draw a text-based graphical representation of the commit history on
# the left hand side of the output.
# --decorate:
# Print out the ref names of any commits that are shown. Defaults to
# short optionm such that the name prefixes refs/heads/, refs/tags/ and
# refs/remotes/ will not be printed.
lol = "log --graph --decorate --oneline"
Notes on the config:
- You must use double quotes if using spaces in an alias value, otherwise you'll get command not found error.
- You don't need to reload your terminal to get changes - git aliases are evaluated fresh each time you run a git command.
- There is a Better Toml extension for VS Code which helps handle this and I find this works better than using the Gitconfig extension and file type in VS Code.
I am going to demonstrate the usage and output of some of my git aliases next.
View git aliases
As promised from the previous part of this series, here is how to list all aliases that are available.
$ git alias
st = status -s -b
c = commit
br = branch -a -v
co = checkout
...
Git status
View a summary of your git status.
$ git st
## master...origin/master
M configs/shell/.aliases
M configs/shell/.commonrc
M configs/shell/.gitignore
That is much quieter than:
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: configs/shell/.aliases
modified: configs/shell/.commonrc
modified: configs/shell/.gitignore
no changes added to commit (use "git add" and/or "git commit -a")
Git log oneline
Show one line for each item in git log output.
$ git lol
* 9103ed0 (HEAD -> master, origin/master, origin/HEAD) Update .gitconfig
* 8a40fdb docs: Add comment
* f750060 feat: Update .gitconfig
Sync local and remote commits and tags
Do a pull with a --rebase
flag, then push.
$ git sync
Already up to date.
Current branch master is up to date.
Everything up-to-date
It is safe to rebase here, since the commits are unpushed. Also, if there have been no local commits, the pull --rebase
will just act as a plain pull
without rewriting commits.
If you want to fetch all tags and then push all tags, do this:
$ git sync-tags
Enumerating objects: 1, done.
...
* [new tag] v0.8.0 -> v0.8.0
If you want to combine both of the above aliases to pull commits and tags and then push commits and tags, do this:
$ git sync-all
Here is the setup for that last one:
[alias]
sync-all = "! git pull --rebase && git push --progress && git push --tags"
The --progress
flag makes pushing quiet but not so quiet as --quiet
.
I recently discovered this for pushing a commit and tags together:
$ git push --follow-tags
However, it only pushes tags at the current commit, so if you've tagged any older commits then those won't get pushed.
So to ensure all tags get pushes, I went back to this approach:
$ git push --progress && git push -tags
View git tags
Show git tags using semver ordering, with higher tag numbers first.
$ git tags
v0.7.0
v0.6.0
v0.5.0
Note that git tag
with no arguments also lists tags. But, will typically show older tags first and the ordering seems weird sometimes as it sorts by text and not by meaning (so 11.0.0
and 1.0.0
could appear side by side).
So my alias ensures the recent ones are first and they are sorted using semvar.
Git aliases that invoke the shell
Use an exclamation mark !
at the start of a command to use a shell command without it going through git
.
This means you can use cd
and find
for example. And chain shell commands using &&
or ||
.
[alias]
# Go to root of git repo.
grt = "! cd $(git rev-parse --show-toplevel)"
# Sync local and remote commits.
sync = "! git pull --rebase && git push"
# Sync local and remote tags.
sync-tags = "! git fetch --tags && git push --tags"
# Sync local and remote commits and tags.
sync-all = "! git pull --rebase && git push --progress && git push --tags"
Use arguments in a shell alias
Note that you can even reference arguments. Use can use $1
and $2
and so on for the position arguments for the aliases.
My use-case for this is limited but here is one that use this approach. Note that the check at the start shows a message if the count of arguments is not equal to one.
[alias]
clone-https = "! [ $# -ne 1 ] && echo 'Args: USERNAME/REPO_NAME' || git clone https://github.com/$1.git"
Sample usage:
$ git clone-https
Args: USERNAME/REPO_NAME
$ git clone-https MichaelCurrin/dotfiles
Cloning into 'MichaelCurrin/dotfiles'...
Instead of using the forward slash, you could expect two arguments and then substitute them as $1/$2.git
.
It is also possible to create a shell function instead and to define and invoke it as part of the alias, but I found using the syntax I've covered above cleaner.
Configure global ignore file
The last part I want to mention on my Git Config part is not an alias but a core setting.
This tells git to use a global git ignore file, if it exists. Note you must used double quotes so that ~
gets expanded.
[core]
editor = "nano"
excludesfile = "~/.gitignore"
You must create this file yourself, which I'll cover in the next post.
Multiple git configs
By the way, I discovered you have have multiple git configs and set it up so that a folder of work repos all use that.
See this post by @jma
.
This sounds great as I use a different email for my work projects and I don't have to remember to set it locally on each repo.
Share
If you any handy git aliases, please share them in the comments.
Next
Carry on to Part 5.
Posted on September 6, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.