More Awesome Git Aliases
In the last article in this series, Awesome Git Aliases, we took a look at some awesome aliases for Git. However, the true power of Git aliases comes from writing custom scripts. These allow you to build Git commands that can do anything you can imagine.
In this article, I'll show you how you can create script aliases with Git. We're going to take a look at several awesome scripts you can use for Git that are super useful and will save you a bunch of time.
Script Aliases
We'll be using Bash for our scripts. Bash is an ugly language, but it has the benefit of working almost anywhere. For your own scripts, you can use any scripting language you'd like.
If you're not familiar with Bash scripting, don't panic! While some of the syntax may look funky, you can mostly muddle your way through. (That's not something you typically hear from a coding article, right?) I recommend reading Learn Bash in Y Minutes and rifling through Google or Stack Overflow for anything that doesn't make sense.
The first step is to create a file for your script. I like to store these files in my Dotfile's bin
directory, but you can put them anywhere you'd like on your computer. Just make sure it's somewhere easy to remember.
touch bin/git/git-example
Next, you'll need to add some boilerplate to the top of your script.
#!/usr/bin/env bash set -euo pipefail
The first line is called a shebang), and it tells your computer that the file is a script that should be run with Bash. This specific runs the script with Bash. To use a different language, substitute bash
for something else, like ruby
or python3
.
The second line tells bash to exit if there are any errors, undefined variables, or errors in a pipeline. I don't know why this isn't the default in Bash, but at least it's easy to set up with this line.
You could run your script as-is with (bash bin/git/git-example
), but who has time to write out bash
every time they want to run something? Instead, make your script executable.
chmod +x bin/git/git-example
Now you can run your script without prepending bash
to it (e.g. bin/git/git-example
).
Finally, you should add your script to Git's aliases. Substitute the path for your script below.
[alias] example = "!$HOME/.dotfiles/bin/git/git-example"
That's it! Now you can run git example
to run a script that doesn't do anything!
List All Branches
By default, when you run git branch
, you get the branches you have stored locally. But what if you want to see all of the branches available to you? You can achieve this by adding the --all
flag to your branches.
git branch --all
I like to package this into a git-branches
script and add a few extras to it.
#!/usr/bin/env bash set -euo pipefail # Only output color if the command isn't being piped. if [ -t 1 ]; then COLOR="always" else COLOR="auto" fi git branch \ --all \ --color="$COLOR" \ --sort=authordate \ --format="%(color:blue)%(authordate:relative);%(color:red)%(authorname);%(color:white)%(color:bold)%(refname:short)" \ "$@" \ | column -s ";" -t
Don't forget to save this to a file and make it executable!
This does several things:
- It only outputs color when the script is being run directly from the CLI. This allows you to use
git-branches
in other scripts. - It sorts the branches by when they were authored. This puts the most recent branches at the bottom.
- It allows you to pass additional arguments to the
branch
command using the$@
Bash variable. This will come in useful in themy-branches
command we'll add next. - It adds some nice formatting to your branches. For example, this is why my
branches
output looks like in my dotfiles repo. This works by using a trick with thecolumn
command and replacing semicolons in the output so the items line up nicely.
Add an alias for this command (and a short alias if you like brevity).
[alias] branches = "!$HOME/.dotfiles/bin/git/git-branches" bs = branches
You're all set! You can now run git branches
(or just git bs
) to see all off of the available branches.
List My Branches
The branches
command you just added is very handy, but when you're working with a large team, it can be a pain to see everyone's branches. I like to create a second alias that only includes my branches. You can easily accomplish this with a new script.
#!/usr/bin/env bash set -euo pipefail # Only output color if the command isn't being piped. if [ -t 1 ]; then COLOR="always" else COLOR="auto" fi "$HOME/.dotfiles/bin/git/git-branches" --color="$COLOR" | grep "$(git config user.name)"
This script runs git-branches
and then pipes the output through grep
to filter it down to the current user's branches.
Create aliases for both of these commands.
[alias] my-branches = "!git branches | grep -i '$()'" my-bs = my-branches
You could reduce the short alias to git mbs
, but I don't because writing git my-bs
makes me smile every time I run it.
Stash Staged
Git has a git stash
command, which is useful for setting aside work for later. By default, it only stashes tracked files. If you have new files you want to stash new files, you have to include the --include-untracked
flag, or use git stash --all
.
What do you do if you only want to stash some of your files? The built-in way to do this is Git funky.
Let's say you want to stash the files apple
and banana
, but keep cherry
and date
. To do that, you add the files you don't want to stash to the index, and then run git stash --keep-index --include-untracked
.
git add cherry date git stash --keep-index --include-untracked
This is strange because it's the exact opposite way that git commit
works. Plus, you now have a couple of files floating around in your index that you'll have to run git restore
on.
To fix this, let's create a git stash-staged
command.
#!/usr/bin/env bash set -euo pipefail git diff --staged --name-only | xargs git stash push "$@" --
That's it! This command uses git diff --staged --name-only
to print out a list of all of the files that are in the index. Then, it pipes those arguments to xargs
. xargs
splits up the arguments by newlines and passes them to git stash --
.
Add your alias, and you're done!
Aliases
You sure have been writing a lot of aliases lately. Wouldn't it be nice if there was a command we could run to list all of the aliases you've created? We can add an alias for that!
[alias] aliases = "config --get-regexp alias"
That's All For Now!
That's it! Hopefully, you've enjoyed this article, and you'll make good use of the aliases here.
Do you have a favorite Git alias? Let me know about it down in the comments!
About Landon Schropp
Landon is a developer, designer and entrepreneur based in Kansas City. He's the author of the Unraveling Flexbox. He's passionate about building simple apps people love to use.
I really like your
script and would like to augment it by 2 things which I can’t figure out how to do:
1. Somehow highlight local branches (e.g. name not bold, different color, …)
2. (Minor) “2 level sort”: 1st sort by local/remote branch (i.e. local branches before remote ones), 2nd sort by authordate
Could you somehow help me with that or point me in the right direction?
Is
git config user.name
missing inside the parens ($()
) in the snippet below?I colleded some git alias in the last years, maybe there is something helpfully for you: e.g. https://github.com/voku/dotfiles/blob/master/.gitconfig#L110
Hey, what font is that in the image?