Best Practices

Git aliases and productivity tips

Efficient Git alias configuration, common alias catalog, shell aliases, team-shared alias configuration, and best practices.

Who This Is For
  • Individuals or teams who want more predictable Git habits
  • Maintainers setting collaboration expectations
Prerequisites
  • At least one real collaboration loop
  • Basic command familiarity without a stable routine yet
Common Risks
  • Treating guidance as absolute law without context
  • Memorizing process without understanding team boundaries

The short version

Git Alias SystemSimplify common commands with aliases, unify team habits, reduce typos. Aliases should be self-explanatory, not just shorter abbreviations.
Common Commands
git statusgit log --oneline --graphgit branch --mergedgit diff --staged
Quick Commands
git s → statusgit lg → log --oneline --graphgit bm → branch --mergedgit ds → diff --staged
Aliases should make common ops faster, but not sacrifice readability. Teams can share alias configs.

Git aliases let you replace verbose native commands with short ones, dramatically boosting daily productivity. Configured via git config alias.xxx, they support simple argument substitution and complex shell script execution.

What are Git aliases

Git aliases are a built-in command abbreviation mechanism. Once configured, git s can equal git status.

# Basic configuration syntax
git config --global alias.alias-name 'original command'

# Example
git config --global alias.s status

Configuration is stored in ~/.gitconfig:

[alias]
    s = status

Common basic aliases

Status and log

[alias]
    # Status in short format
    s = status -s

    # List branches
    b = branch

    # View commit log (single line)
    l = log --oneline

    # View last 10 commits
    last = log -1 HEAD --stat

    # Graph log
    lg = log --oneline --graph --decorate

Branch operations

[alias]
    # List all branches (including remote)
    ba = branch -a

    # List merged branches
    bm = branch --merged

    # List unmerged branches
    bu = branch --no-merged

    # Create and switch to new branch
    co = checkout -b

Remote operations

[alias]
    # View all remotes
    r = remote -v

    # Push current branch and set upstream
    pushu = push -u origin HEAD

    # Pull with rebase
    pullr = pull --rebase

Advanced aliases

Pretty log formats

[alias]
    # Detailed pretty log
    lg1 = log --graph --format='%C(auto)%h %C(cyan)%ad %C(green)%s%C(reset) %C(yellow)%d' --date=short

    # Log with author info
    lg2 = log --graph --format='%C(auto)%h %C(bold blue)%an%C(reset) %C(cyan)%ad %C(green)%s%C(reset) %C(yellow)%d' --date=short

    # Count commits by author
    count = shortlog -sn

    # Who changed what
    who = shortlog -sn --no-merges

File change history

[alias]
    # View file modification history
    filelog = log --oneline --follow --

    # View who changed which line
    blame-compact = blame --date=short -w

    # Search commit messages
    search = log --all --grep

Diff enhancements

[alias]
    # Word-level diff
    wdiff = diff --word-diff=color

    # Change statistics
    stat = diff --stat

    # Compare two branches
    compare = diff --stat main..HEAD

Shell aliases (! prefix)

Aliases starting with ! execute in a shell, enabling more complex operations:

[alias]
    # View current branch
    current = !"git symbolic-ref --short HEAD"

    # Delete merged branches
    cleanup = !"git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"

    # View untracked files
    untracked = !"git status --porcelain | grep '^??' | cut -c4-"

    # Quick commit
    c = "!f() { git commit -m \"$*\"; }; f"

    # Most frequently modified files
    topfiles = !"git log --pretty=format: --name-only | sort | uniq -c | sort -rg | head -20"

    # Show latest tag
    latest-tag = !"git describe --tags --abbrev=0"

    # Interactive add
    addp = add -p

    # Squash recent N commits
    squash = !"f() { git reset --soft HEAD~${1} && git commit --edit -m\"$(git log --format=%B --reverse HEAD..HEAD@{1})\"; }; f"

Team-shared alias configuration

Method 1: Shared config via include

# ~/.gitconfig
[include]
    path = ~/.gitconfig-team

# ~/.gitconfig-team
[alias]
    lg = log --oneline --graph --decorate
    s = status -s
    cleanup = "!git branch --merged | grep -v '\\*\\|main' | xargs -n 1 git branch -d"

Method 2: Repo-level configuration

# Create .gitconfig in repo root
cat > .gitconfig << EOF
[alias]
    lg = log --oneline --graph --decorate
    s = status -s
EOF

# Include it for the repo
git config include.path .gitconfig

Method 3: Distribution via script

#!/bin/bash
# setup-git-aliases.sh

git config --global alias.s 'status -s'
git config --global alias.lg 'log --oneline --graph --decorate'
git config --global alias.cleanup "!git branch --merged | grep -v '\\*\\|main' | xargs -n 1 git branch -d"
git config --global alias.lg1 "log --graph --format='%C(auto)%h %C(cyan)%ad %C(green)%s%C(reset) %C(yellow)%d' --date=short"

echo "Git aliases configured."

New team members just run:

bash setup-git-aliases.sh

Aliases and auto-completion

Bash completion

Ensure git-completion.bash is installed:

# Ubuntu/Debian
sudo apt install git bash-completion

# macOS (Homebrew)
brew install git bash-completion@2

Git alias auto-completion requires adding to .bashrc:

# Make completion script recognize custom aliases
__git_complete gc _git_checkout  # if your alias is gc

Zsh completion

Using oh-my-zsh git plugin:

# ~/.zshrc
plugins=(git zsh-autosuggestions)

oh-my-zsh ships with many Git aliases:

AliasCommand
ggit
gstgit status
glgit pull
gcgit commit -v
gbgit branch
gdgit diff
gcogit checkout
gloggit log --oneline --graph --decorate

Recommended personal alias configuration

[alias]
    # Daily high-frequency
    s = status -sb
    b = branch -vv
    l = log --oneline -20
    lg = log --oneline --graph --decorate --all

    # Commit-related
    c = commit
    ca = commit --amend
    cn = commit --no-verify

    # Branch operations
    co = checkout
    nb = checkout -b
    del = branch -d
    force-del = branch -D

    # Remote operations
    p = push
    pf = push --force-with-lease
    pl = pull --rebase
    f = fetch --all --prune

    # Advanced
    stash-all = stash save --include-untracked
    unstage = reset HEAD --
    undo = reset --soft HEAD~1
    who = shortlog -sn --no-merges

    # Shell aliases
    root = rev-parse --show-toplevel
    current = !"git symbolic-ref --short HEAD"
    cleanup = "!git branch --merged | grep -v '\\*\\|main\\|master' | xargs -n 1 git branch -d"

Common pitfalls

Over-abbreviation reduces readability

# Bad — too short, hard to remember
[alias]
    q = status
    w = log
    e = commit

# Good — abbreviations are meaningful
[alias]
    s = status -s
    l = log --oneline
    c = commit

Alias and subcommand conflicts

# Avoid using existing Git subcommand names as aliases
# Don't use checkout as an alias (checkout already exists)
# Don't use commit as an alias (commit already exists)

Using aliases in scripts

# Wrong: Aliases may not expand in scripts
#!/bin/bash
git s  # may not work in non-interactive mode

# Correct: Use full commands
#!/bin/bash
git status -s

Git aliases are primarily expanded in interactive command-line sessions; scripts should use full commands.

Key takeaways

  1. Global vs local alias config: --global affects all repos, without it only affects the current repo
  2. Shell aliases need quotes: ! prefixed aliases must be quoted
  3. Aliases can chain: git s expands to git status -s
  4. View configured aliases: git config --get-regexp alias
  5. Delete an alias: git config --global --unset alias.xxx
  6. Don't confuse with shell aliases: Git aliases only work after git

Summary

CategoryRecommended aliasEffect
Statuss = status -sbShort + branch info
Loglg = log --oneline --graph --decorate --allGraph full-branch log
Commitca = commit --amendAmend last commit
Branchnb = checkout -bCreate and switch branch
Pushpf = push --force-with-leaseSafe force push
Cleanupcleanup (shell)Delete merged branches

Good alias configuration saves a lot of typing, but stay disciplined — only abbreviate commands you use multiple times daily.