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.
Here is the format - add aliases to your
~/.gitconfig file, which uses TOML format.
[alias] MY_ALIAS = "GIT_COMMAND" MY_ALIAS = "! MY SHELL COMMAND"
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.
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 ...
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")
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
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"
--progress flag makes pushing quiet but not so quiet as
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
Show git tags using semver ordering, with higher tag numbers first.
$ git tags v0.7.0 v0.6.0 v0.5.0
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
1.0.0 could appear side by side).
So my alias ensures the recent ones are first and they are sorted using semvar.
Use an exclamation mark
! at the start of a command to use a shell command without it going through
This means you can use
find for example. And chain shell commands using
[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"
Note that you can even reference arguments. Use can use
$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"
$ 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
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.
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.
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
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.
If you any handy git aliases, please share them in the comments.
Carry on to Part 5.