Using Git Aliases and Custom Scripts to Work Faster
Tags: git, productivity
Published: 2020-05-12 02:06:34

Configuration is one of Git's greatest strengths. It can be
tweaked to work exactly as you need. Git has multiple features
to help you work in the way that is best for you.

One of the most common custom configuration methods is creating
aliases.  These are useful for command abbreviations,
correcting common typos, and composing commands. Git also
supports writing your own custom commands that can also be
leveraged with aliases to create some seriously powerful
workflows.

This article will provide basic aliases that can be used as a
starting point if you are not already using them. We will also
discuss more complex aliases and hint at some possible custom commands to automate common workflows. Let's get started!


# Simple Aliases
An alias is a shorthand name for a command. Git recognizes
the shorthand name and runs the full command. It may seem
trivial, but they can be a significant time saver.

The most frequently used commands in git are typically at
least five letters long. People typically add two-letter
aliases for each such as:

| Alias | Command     |
|-------+-------------|
| `ci`    | `commit`      |
| `br`    | `branch`      |
| `co`    | `checkout`    |
| `rb`    | `rebase`      |
| `sb`    | `show-branch` |
| `st`    | `status`      |

Aliases are most frequently defined globally in the user's
configuration file found at `$HOME/.gitconfig`. They can also be
defined [system-wide and for a specific repository][1].

Try adding a global alias for the `status` command by using the
command below:

`git config --global alias.st status`

Test it out by running `git st`. The status should be
displayed. Simple abbreviation aliases are the most frequently
used aliases. Aliases also support more complex configurations
as well.


# Complex Aliases
Aliases support arguments or even running as shell
functions. Using an alias in place of a frequently used
command with arguments can make commands more intuitive and
significantly speed up your workflow.

Complex aliases are created in the same way as simple aliases
but the arguments need to be quoted:

`git config --global alias.staged "diff --staged"`

Running `git staged` now shows the diff of the last commit to
the index. Here are some ideas for more complex aliases:

| Alias   | Command                             |
|---------+-------------------------------------|
| `staged`  | `diff --cached`                       |
| `unstage` | `reset HEAD --`                       |
| `whoops`  | `commit --amend`                      |
| `redo`    | `commit --amend --reuse-message=HEAD` |
| `last`    | `log -1 HEAD`                         |
	
Although Git supports running shell functions as aliases, it
becomes challenging to accept arguments to these scripts
without complex escaping. There is actually a simpler way to
handle these more complex scenarios though &#x2013; custom commands!


# Custom Commands
Git supports writing your own custom commands that can be
called as you would use a regular git command. This is often
the most maintainable way to add complex functionality. The
logic can be contained in a completely separate script instead
of inside your git configuration. Arguments to the git command
are instead passed as arguments to the script which makes
parsing or using them much simpler.

To write a custom command, add an executable in your `$PATH`
prefixed with the name `git-` so it can be discovered. For
example, if you want a custom command called `custom-command`,
add an executable to your `$PATH` named
`git-custom-command`. That's it! Git will find it and run it.

This opens up the door for some really cool custom
functionality. Many of the tasks that we perform each day can
be automated. I use custom commands for everything in the
table below:

| Command              | Alias | Functionality |
|----------------------+-------+---------------+
| `create-merge-request` | `cmr`   | Create a GitLab merge request for the current branch and link it to its JIRA ticket.                        |
| `diff-branch`          | `db`    | Show the differences between the provided branches. Often called by other commands.                         |
| `find-branch`          | `fb`    | Do a search for a branch with the provided name. Run a `fetch` if the name cannot be found then search again. |
| `find-branch-checkout` | `fco`   | Same as above but then check the branch out.                                                                |
| `merge-diff`           | `md`    | Display the resulting diff from the provided merge commit.                                                  |
| `name-branch`          | `nb`    | Append a string to the local branch name to help distinguish it.                                            |
| `remove-merged`        | `rmm`   | Remove all local branches that have been merged to the primary branch such as `master`.                |
| `repo`                 |       | Open the current repo in the browser at GitLab or GitHub.                                                   |
| `since-master`            | `sd`    | Show the diff of changes from the current branch compared to its merge-base with `master`.                                           |
| `ticket`               |       | List the ticket name associated with the current branch. Often called by other commands.                    |
| `when-merged`          | `wm`    | Display the commit from when the provided commit was merged into the current branch.                        |
| `jira`                 |       | Open the provided issues or current branch's ticket in JIRA.                                                |


You can see in the table above I included aliases for the
custom commands. The names of these commands are often longer
due to the more complex behavior. Fortunately, Git allows us
to create aliases for custom commands just as we would for a
builtin command!

If you are interested in using any of these custom commands
for your own use, you can find the source in my [local
repository][2]. These get installed to my home directory at
`$HOME/bin` which is included in my `$PATH`. If you want to set
this up for yourself locally, run the following commands:

```shell
  mkdir -p $HOME/bin/
  [ -e ~/.bashrc ] && echo "export PATH=\$HOME/bin:\$PATH" >> ~/.bashrc
  [ -e ~/.zshrc ] && echo "export PATH=\$HOME/bin:\$PATH" >> ~/.zshrc
```

You can also see my complete [Git configuration][3] if you want to
see what aliases I have configured. Finally, here are some
other good guides on using Git aliases:

-   <https://git-scm.com/book/en/v2/Git-Basics-Git-Aliases>
-   <https://githowto.com/aliases>
-   <https://www.atlassian.com/git/tutorials/git-alias>

Finally, please share with me your favorite aliases or custom commands!

[1]: <https://git-scm.com/docs/git-config#FILES>
[2]: <https://github.com/briehman/dotfiles/tree/master/bin>
[3]: <https://raw.githubusercontent.com/briehman/dotfiles/master/.gitconfig>