How I use git aliases

I talk about this not infrequently, so decided to try to better structure how I think about using git aliases in my development workflow in a consolidated (and hopefully more coherent!) way.

I’m of the opinion that you can choose to either:

  • Incorporate it (either CLI or through some tool) meaningfully into your workflows; or
  • Tack it on at the end, because you have to use it (“I’m required to check this in, ugh”)

The natural result of your choice here means git can be either a productivity and code-quality boon, or an annoying hoop to jump through. That seems like an easy decision when you frame it that way, but I actually think that’s a bit of an straw man proposition: no one says “no I want to jump through annoying hoops while receiving little-to-no value”. Much more common: I have a hundred things to do, and everything here is complex and learning all of git is daunting.


The aha! moment

When it finally clicked for me was when I realized git has a lot of magic incantations, but you don’t (generally, at least) need to know all of the feature flags, implementation details, and other arcane trivia. What you need is to know how do take a workflow that feels comfortable to you, and how to leverage git to make that workflow easier.

I do most of my work in a terminal, so it makes sense for me to use git in the terminal. So for me, the easiest way to encapsulate “how do I do this thing with git” is bash aliases. Personally I write aliases in a ~/.bash_aliases which on my machine goes through the ~/.bash_aliases > ~/.bashrc > ~/.profile source chain to be available in all of my terminal windows (your setup might be different). The goals here are:

  • Where you do development
  • With words / labels which make sense to do

Here’s a subset of my list of aliases that are most relevant:

alias gita="git add --patch"
alias gitb="git branch"
alias gitbn="git checkout -b"
alias gitc="git commit"
alias gitca="git commit --amend"
alias gits="git status"
alias gitr="git checkout --"
alias gitu="git reset HEAD --"

What my workflow looks like

Here’s how I actually use those aliases in my workflows (command, “what my brain thinks)":

  • gitbn (“git, branch, new”): create a new branch from the branch I’m currently on. Often I couple this with git fetch origin && git checkout origin/main (or equivalent) to create a fresh branch off main.

  • Make some changes

  • gita (“git, add”): add files to staged, using patch mode. This is my default way of staging changes now, and had was the single best thing I did to improve the quality of my commits. It pushes me to a default which asks me to review each chunk of changes I’m saying I want to add, and think about if/how that change should be included in the current commit. I’ll often run gita several times on a set of changes to do a first pass (selecting n for all changes), then add specific chunks and commit them (gitc), then repeat with another batch of logically related chunks.

    • gita will not stage untracked (new) files. This makes me have to do git add <filename> (or git add .) explicitly when I add new files that I want included in a commit.
  • gitr (“git, reset changes”): this is probably my favorite alias. It’s intentionally a prefix; for it to work I need to add a file path or file name which I want “reset.” I put reset in quotes because what you’re actually doing is removing changes you haven’t staged (using gita) compared to the last commit. It’s also one of the commands that I never remember because in my mind what I’m doing is “undoing” not “check out the HEAD for a set of file(s).” The git incantation doesn’t match my workflow mental model, but that alias sure does.

    • The best part of this is because of what the actual command is doing, I’m able to use gita and gitr in combination. I’ll stage the changes I want to keep in a file using gita and then clear other changes I don’t want (looking at you, print() statements) using gitr.
  • gitu (“git, undo that mistake”): sometimes I make mistakes and gita too much at once. gitu “undoes” that by unstaging a staged file name/path(s) for me.

  • gitc (“git commit”): yeah I’m lazy here. But I type gitc dozens to hundreds of times a day, so it does actually save me some time, and it matches my “four letter alias git incantation” model. Because it’s an alias, gitc -m "Commit message here" works, too. gitca does the same, except it ammends the previous commit.

  • gits (“git, show me the status”): another “four letter alias git incantation”, makes it easy to figure out where I am in the gita, gitr, gitc cycle.

  • gitb (“git, show me branches”): another “four letter alias git incantation”, I go through a lot of branches. Supports things like gitb -d <branch name> to remove branches safely, and gitb -D <branch name> to yeet a branch into oblivion.