Handy Git Aliases
Simple customizations make using the terminal easy.
Skip the backstory and give me the code.
I spend a lot more time in the terminal since I moved from Visual Studio Code to a terminal based editor (Helix). And it’s great! The terminal based programs I rely on are fast, do their jobs well, and tend to have text based configurations that are easy to backup. But one thing I started missing very quickly was VS Code’s built-in Git integration.
At the beginning of my career I used Git from the terminal, but over time I relied on the VS Code UI for more and more Git operations. When I ditched VS Code, some Git commands were easy to start using again: git status, git stash, git checkout <branch>. git commit was slightly more annoying since commit messages have to be wrapped with quotes and have newlines escaped. Then I learned I could just drop the -m flag and Git would open my editor for me to type the commit message into. Perfect!
Unfortunatly there were a few commands that were painful to start using again, git add chief among them. I’ve since gotten better about using shell completions when typing file paths, but I missed being able to easily browse all my changed files, see their diffs, and select what I wanted to stage for a commit with no typing.
There are lots of dedicated Git clients out there and I’m sure they solve this and other Git pain points well. I enjoy learning and solving small problems with simple solutions, so instead I decided to see if I could solve this using some of the terminal programs I already had installed on my machine. Time to add a new shell alias and get cracking!
A new what?
For those who are new to terminal jargon, here's a quick breakdown of terms as I'm using them.
- Terminal
- A graphical program you open to type commands into. Examples include kitty, Ghostty, and Windows Terminal.
- Shell
- A program the terminal sends your commands to that actually runs your commands and sends output back to the terminal to be displayed. Shell's have their own scripting languages and can be configured via text configuration files. Examples include Bash, Zsh, and fish.
- Shell Alias
- A short name that executes some other command when passed to a shell. These names are configured by running a shell-provided command, typically in a shell configuration file.
gitadd
The solution I came up with feeds the output of git status into fzf, which in turn uses bat or Git to show a preview. Since I’m using Bash for my shell I added the following declarations to my .bashrc file to create a gitadd alias.
# This line isn't specific to gitadd, but I already had it set and my impelementation of gitadd depends on these options being set to look and function correctly.
export FZF_DEFAULT_OPTS="--multi --reverse --border --margin 1% --padding 2%,1% --info hidden"
gitaddPreview() {
local diffArg=()
if [ $1 != '??' ] && [ $1 != 'A' ]; then
diffArg+=(-d)
fi
bat --color=always --style=numbers,changes,snip "${diffArg[@]}" "$2"
}
alias gitadd="git status --untracked-files -z | fzf \
--read0 \
--header 'Ctrl-r: reload, Ctrl-d: view git diff' \
--bind 'ctrl-d:preview:git diff --color=always {2..}' \
--bind 'ctrl-r:reload(git status -u -z)' \
--bind 'enter:become(git add --verbose {+2..})' \
--preview 'gitaddPreview {1} {2..}'"
This worked really well for my needs, so I decided to create a few more aliases to smooth out other pain points in my workflow.
gitundo
VS Code had a menu option for undoing the most recent commit which I used every now and then. I don’t do that very often so I kept having to search for the equivalent command after I moved to the termnial (keeping git reset, git restore, and git revert straight is a pain when you don’t use them regularly). This gitundo alias takes care of that once and for all.
alias gitundo="git reset HEAD~"
gitpublish
Normally its a simple git push to move commits from your local machine up to the Git remote. An exception I often run into is when you first create a new local branch that doesn’t exist on the remote. If you try to push commits on such a branch Git will remind you that you need to use the --set-upstream option. This isn’t problematic, but it is annoying. This gitpublish alias removes the need for me to type out the option, remote name (I usually only have one remote named origin), and branch name which is really nice.
alias gitpublish="git push --set-upstream origin \$(git branch --show-current)"
Go Forth and Personalize
If you find these aliases helpful then that’s great! What I really hope you take away is how easy it can be to smooth out the rough edges of a terminal workflow with the right tweaks. If you have to (or choose to) spend significant time working in the terminal, do yourself a favor and personalize your shell’s configuration file to make your environment work for you.