My git aliases are not abbreviations; they are a grammar. q is query—git status. Letters appended to it add verbs: add, delete, state, upstream, worktree-diff, commit, push. Doubling a letter escalates its scope or force. A trailing q quiets or widens the tree. A ! means danger:
alias q="git status"
alias qq="git status --short"
alias qa="git add --patch"
alias qaa="git add --all"
alias qaaq="git add --all \$(git rev-parse --show-toplevel)"
alias qd="git reset --patch"
alias qdd="git checkout --patch"
alias qdd!="git reset --hard"
alias qw="git\${_GIT_DIFF_ARGS} diff"
alias qww="git\${_GIT_DIFF_ARGS} diff --cached"
alias qc="git commit"
alias qp="git push"
alias qp!="git push --force"! is legal in both bash and zsh alias names. The convention was set while the family was still being born, with the commit message:
Aliases that end with a BANG! imply danger, ie.
--force.
The bang is the visual marker for anything destructive.
The grammar sits on a mental model, stated in the header comment above the aliases:
# Git operations framed as mutable QUERIES against three stacked TREES:
# - Input operations (eg. add/commit) start at filesystem and push data IN.
# TREE#1 [fs] -> TREE#2 [index] -> TREE#3 [repo]
# - Output operations (eg. checkout/reset) start at repository and pull data OUT.
# TREE#1 [repo] -> TREE#2 [index] -> TREE#3 [fs]
# - Other operations (eg. status/diff) use INPUT order unless OUTPUT is obvious.Filesystem, index, repository—three trees, stacked, with data flowing in or out. qw diffs the first boundary (worktree against index), qww the second (index against repository). qd removes changes from the index, qdd from the worktree. Once the model is in your head the aliases stop being memorized and start being derived.
The family initially used the prefix g. The rename commit explains itself:
Use q instead of g because 200 commands start with g and 10 start with q.
A later commit compressed the grammar further: “q: prefix enhances and suffix quiets.”
Two details worth stealing even if you keep your own letters. The diff aliases embed a literal \${_GIT_DIFF_ARGS}, escaped at definition and expanded at use, so a shell function can flip the whole diff-and-show family between pretty output and plain apply-able patches after the fact. And the zsh twins spell it \${=_GIT_DIFF_ARGS}—the ${=...} flag forces word splitting that zsh otherwise refuses.
About thirty aliases total, with Bash and zsh versions in my dotfiles and in daily use.