Git config tips and aliases for a better workflow
Your ~/.gitconfig is one of the most underutilized tools in a developer's arsenal. Configs and aliases we've accumulated over the years.
Your ~/.gitconfig file is one of the most underutilized tools in a
developer’s arsenal. A well-tuned git config can save you keystrokes, surface
useful information faster, and eliminate friction from your daily workflow.
Here’s a collection of configs and aliases I’ve accumulated over the years.
Note that I’m breaking these into logical sections, but your actual
~/.gitconfig should only have one [alias] block with all aliases grouped
together.
Sensible defaults
Default branch
Recent git versions default to main for new repositories. If you prefer
master:
[init]
defaultBranch = master
Push behavior
Older git versions would push all branches when you ran git push without
arguments. That’s almost never what you want. Modern git defaults to safer
behavior, but you can be explicit:
[push]
default = current
Now git push only operates on the currently checked out branch.
Pull with rebase
If you prefer rebasing over merge commits when pulling:
[pull]
rebase = true
Auto-prune on fetch
Tired of seeing stale remote branches that were merged weeks ago? Tell git to clean them up automatically:
[fetch]
prune = true
Making output more readable
Enable colors
Colors everywhere:
[color]
ui = auto
You can customize specific colors too (see man git-config for all options):
[color "status"]
header = yellow bold
added = green bold
updated = green reverse
changed = magenta bold
untracked = red
[color "diff"]
meta = yellow bold
frag = magenta bold
old = red bold
new = green bold
whitespace = red reverse
Compact log format
The default git log output is verbose. You can set a custom format that
shows commits on a single line with just the essentials:
[format]
pretty = format:%C(red)%h%Creset%C(yellow)%d%Creset %C(magenta)%an%Creset: %s %C(green)(%ar)%Creset
When you need full details, use git show --format=fuller [sha].
Compact status
For a more concise git status:
[status]
short = true
branch = true
This gives you git status -sb behavior by default. Use git status --no-short when you want the verbose output.
Sort branches by date
See your most recently worked-on branches first:
[branch]
sort = -authordate
Disable advice messages
Git helpfully explains how to use commands. Once you know what you’re doing, this can get noisy:
[advice]
statusHints = false
pushNonFastForward = false
Check man git-config for the full list of advice.* options.
Useful aliases
Viewing commits
A graph view showing branch structure and merge points:
[alias]
lg = log --graph --abbrev-commit --date=relative
Full commit details when you need them:
[alias]
showf = show --format=fuller
full-log = log --format=fuller
Get the last commit SHA (useful for pasting into PRs or issue trackers):
[alias]
last-sha = rev-parse --short HEAD
See commits you haven’t pushed yet:
[alias]
pending = !git --no-pager log @{u}.. && echo
Just the last commit’s subject line (great for copy-pasting):
[alias]
last-subject = !git --no-pager log --pretty="%s" -1
Show only the filenames changed in a commit:
[alias]
show-files = !git --no-pager show --name-only --format=
This also works on ranges: git show-files main..HEAD shows everything
changed on your branch.
Working with branches
Get the current branch name:
[alias]
branch-name = rev-parse --abbrev-ref HEAD
Combine with pbcopy on macOS: git branch-name | pbcopy
List the 10 most recent branches:
[alias]
recent-branches = for-each-ref --count=10 --sort=-committerdate --format=\"%(refname:short)\" refs/heads/
Clean up merged local branches:
[alias]
prune-branches = !git branch --merged | grep -v '^master$' | grep -v "\\\\*" | xargs -n 1 git branch -d
Undoing mistakes
Unstage files (use git unstage -- . for everything, or specify files):
[alias]
unstage = reset HEAD -- ...
Undo the last commit but keep changes staged:
[alias]
undo = reset --soft HEAD^
Amend the last commit (updates the date so it sorts correctly):
[alias]
amend = !git commit --amend --date=\"$(date)\" -C HEAD
Utilities
Find the root directory of a repo:
[alias]
root = rev-parse --show-toplevel
Scan for TODO and FIXME comments:
[alias]
todo = grep -wniI -e TODO -e FIXME
Create an empty commit (useful for initializing repos):
[alias]
msg = commit --allow-empty -m
Usage: git msg "Initial commit"
Editor configuration
Set your preferred editor for commit messages:
[core]
editor = vim
For VS Code:
[core]
editor = code --wait
Or set the GIT_EDITOR environment variable in your shell profile.
Managing multiple identities
Include files
Keep work and personal configs separate with includes. In ~/.gitconfig:
[user]
email = personal@example.com
[include]
path = ~/.gitconfig.local
Then in ~/.gitconfig.local on your work machine:
[user]
email = work@example.com
Directory-based author with direnv
If you use direnv, you can set git author info per-directory. Create a
.envrc in your work projects folder:
export GIT_AUTHOR_EMAIL=work@example.com
export GIT_COMMITTER_EMAIL=work@example.com
Now any commit under that directory tree uses your work email automatically.
Local gitignore
Need to ignore files in your local checkout without affecting the shared
.gitignore? Add patterns to .git/info/exclude:
_my_scripts/*
.local-notes.md
Use this sparingly. If multiple developers need the same ignores, put them in
.gitignore.
Shell aliases
These shell aliases cover the most common operations. Add to ~/.bashrc or
~/.zshrc:
alias gb='git branch'
alias gbd='git branch -d'
alias gco='git checkout'
alias gd='git diff'
alias gdc='git diff --cached'
alias gs='git status'
Checkout main, pull, then return to your previous branch:
alias gcomp='git checkout main; git pull'
alias gcomp-='git checkout main; git pull; git checkout -'
Before pushing a PR: gcomp- && git rebase main
Remove deleted files from git tracking:
alias grm="git status --porcelain | awk '\$1 == \"D\" {print \$2}' | xargs git --git-dir=\$(git rev-parse --git-dir) rm --ignore-unmatch"
These configs have evolved over years of daily use. Start with the ones that address friction you actually experience, and build from there.