Home DevOps Git Alias: Custom Commands for Faster Workflows – The Only Guide You'll Need
Beginner 4 min · July 18, 2026

Git Alias: Custom Commands for Faster Workflows – The Only Guide You'll Need

Git alias tutorial: stop typing long commands.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Production
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
Before you start⏱ 20 min
  • Basic Git knowledge (init, commit, push, pull)
  • Access to a terminal or command line
  • A Git repository to practice with
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

Create a Git alias with git config --global alias. ''. For example, git config --global alias.lg 'log --oneline --graph --all --decorate' lets you run git lg instead of that long log command. Use --global for all repos or omit it for just the current repo.

✦ Definition~90s read
What is Git Alias?

A Git alias is a custom shortcut for a Git command or a series of commands. Instead of typing git log --oneline --graph --all --decorate, you can type git lg. Aliases live in your Git config file and can include arguments, shell commands, or even external scripts.

Think of Git aliases like speed dial on your phone.
Plain-English First

Think of Git aliases like speed dial on your phone. Instead of dialing a full 10-digit number every time, you press one button. Git aliases let you map a short word to a long, complex Git command. You still get the full power of Git, but you type way less. It's like having a personal assistant who knows your most-used commands and executes them with a single word.

⚙ Browser compatibility
Latest versions — ✓ supported
ChromeFirefoxSafariEdge

You know that moment when you're in the middle of a hotfix, your boss is breathing down your neck, and you have to type git log --oneline --graph --all --decorate for the fifth time? That's time you don't have. Git aliases are the duct tape that holds my workflow together. They turn 40-character commands into 4-character ones. And no, they're not just for lazy people — they're for people who value their time.

Here's the problem Git aliases solve: Git commands are verbose. Some are downright painful to type repeatedly. git commit --amend --no-edit? That's 30 keystrokes for something you might do 20 times a day. Aliases cut that down to git amend (or even git ca if you're feeling spicy). They also reduce typos — fewer keystrokes means fewer chances to fat-finger a flag and mess up your repo.

By the end of this article, you'll be able to create your own Git aliases, use advanced tricks like shell commands and external scripts, and avoid the common pitfalls that have burned me (and many others) in production. You'll never type git log --oneline --graph --all --decorate again. I promise.

Why You Need Git Aliases (And Why You've Been Wasting Time)

Every time you type a long Git command, you're wasting mental energy and risking typos. I've seen developers type git commit -m "fix: typo" a hundred times a day. That's fine. But when you need git log --oneline --graph --all --decorate --since="2 weeks ago" --author="John", you're going to mess it up. Aliases let you bundle that into git mylog. The payoff is immediate: less typing, fewer errors, faster workflow.

But aliases aren't just about saving keystrokes. They're about creating a personal vocabulary for your Git workflow. You can chain commands, run shell scripts, and even integrate with external tools. In a team, shared aliases can enforce conventions — like a git wip that stages everything and commits with a standard message. The key is to start small and build up.

create-first-alias.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// io.thecodeforge — DevOps tutorial

# Create a simple alias for git status
# Instead of typing 'git status', you can type 'git st'
git config --global alias.st status

# Verify it works
git st
# Output: On branch main, nothing to commit, working tree clean

# Another common one: git co for checkout
git config --global alias.co checkout

# Now you can do: git co -b new-feature
# Instead of: git checkout -b new-feature
Output
On branch main
nothing to commit, working tree clean
💡Senior Shortcut:
Use --global for aliases you want in every repo. Use --local (or omit) for project-specific aliases. I keep a set of global aliases for common operations and repo-specific ones for custom workflows.

Creating Your First Alias: The Anatomy of a Git Alias

A Git alias is just a config entry. The syntax is git config [--global] alias.<name> '<command>'. The command can be any Git command (without the git prefix) or a shell command prefixed with !. Let's break it down.

First, decide the scope: --global for your user (all repos), --system for all users on the machine (rare), or no flag for just the current repo. Then pick a short name — I use st for status, co for checkout, ci for commit (old SVN habit). The value is the command string in quotes.

Important: If your command has arguments (like --oneline), include them in the alias. The alias replaces the entire command, so git lg becomes git log --oneline --graph --all --decorate. You can also append additional arguments when you run the alias — they get appended to the end of the command.

alias-examples.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// io.thecodeforge — DevOps tutorial

# Alias for a pretty log
git config --global alias.lg 'log --oneline --graph --all --decorate'

# Usage: git lg
# Output: a compact graph of all branches

# Alias with arguments: git last 5 shows last 5 commits
git config --global alias.last 'log -1 HEAD'
# But wait, we want to specify count. Better:
git config --global alias.last '!f() { git log -$1 HEAD; }; f'
# Now: git last 5 shows last 5 commits

# Alias for amending without editing message
git config --global alias.amend 'commit --amend --no-edit'

# Usage: git amend (after staging changes)
Output
* 1a2b3c4 (HEAD -> main) Fix login bug
* 5e6f7g8 Add user authentication
* 9h0i1j2 Initial commit
⚠ Production Trap:
Don't use ! for simple Git commands — it's slower because it spawns a shell. Only use ! when you need shell features like pipes, loops, or arguments. For simple aliases, just use the Git command without !.

Advanced Aliases: Shell Commands and External Scripts

When a simple Git command isn't enough, you can prefix the alias value with ! to run a shell command. This opens up infinite possibilities: pipes, loops, conditionals, even calling external scripts. But with great power comes great responsibility — and potential disaster.

For example, I have an alias git wip that stages all changes and commits with a timestamp: !git add -A && git commit -m "WIP $(date)". Another one: git cleanup that deletes merged local branches (but be careful — see the production incident above).

You can also point an alias to an external script. Just use !path/to/script.sh. The script runs in the repo root. This is useful for complex multi-step workflows that you want to version-control with your project.

advanced-aliases.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// io.thecodeforge — DevOps tutorial

# Shell alias: add all and commit with timestamp
git config --global alias.wip '!git add -A && git commit -m "WIP $(date)"'

# Usage: git wip
# Stages everything and commits with message like "WIP Mon Jan 15 14:30:00 UTC 2024"

# Alias with argument: delete merged branches except main
git config --global alias.cleanup '!git branch --merged | grep -v -E "(\*|main|staging)" | xargs -r git branch -d'

# Usage: git cleanup
# Deletes all merged branches except main and staging

# Alias that calls an external script
git config --global alias.deploy '!./scripts/deploy.sh'

# Usage: git deploy (runs deploy.sh from repo root)
Output
Deleted branch feature/login (was abc1234).
Deleted branch bugfix/typo (was def5678).
⚠ Never Do This:
Never create an alias that force-pushes without confirmation. I've seen git pushf defined as !git push --force-with-lease origin $(git rev-parse --abbrev-ref HEAD). One wrong branch and you've rewritten history. Always add a safety check or use --force-with-lease at minimum.

Managing and Sharing Aliases: The Git Config File

All your aliases live in your Git config file. Global aliases are in ~/.gitconfig (or ~/.config/git/config). Local aliases are in .git/config of the repo. You can edit these files directly — sometimes faster than using git config commands.

To list all aliases: git config --global --get-regexp alias. Or open the file and look under the [alias] section. To remove an alias: git config --global --unset alias.<name>.

Sharing aliases with your team? Put them in a script that everyone sources, or use a .gitconfig file in the repo that you include via git config --local include.path ../.gitconfig. But be careful — local config can override global, and you don't want to force aliases on teammates who might not want them.

manage-aliases.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// io.thecodeforge — DevOps tutorial

# List all global aliases
git config --global --get-regexp alias
# Output:
# alias.st status
# alias.co checkout
# alias.lg log --oneline --graph --all --decorate

# Remove an alias
git config --global --unset alias.st

# Edit global config directly (opens in default editor)
git config --global --edit

# Inside ~/.gitconfig, the [alias] section looks like:
# [alias]
#   st = status
#   co = checkout
#   lg = log --oneline --graph --all --decorate

# Share aliases via a file that others can include
echo "[alias]" > team-aliases.gitconfig
echo "  wip = !git add -A && git commit -m \"WIP\"" >> team-aliases.gitconfig
# Then teammates can run:
# git config --global include.path /path/to/team-aliases.gitconfig
Output
alias.st status
alias.co checkout
alias.lg log --oneline --graph --all --decorate
🔥The Classic Bug:
If you edit ~/.gitconfig manually, make sure there's no trailing whitespace or missing newlines. Git's parser is picky. One stray space can break all your aliases. I've spent 30 minutes debugging why git st suddenly stopped working — turned out I had a tab instead of a space.

Alias Gotchas: What Can Go Wrong and How to Fix It

Aliases seem simple, but they have sharp edges. Here are the ones that have bitten me and my teams.

1. Argument handling: If your alias is !f() { git log -$1 HEAD; }; f, and you run git last, it passes no argument, so $1 is empty, and the command becomes git log - HEAD — which errors. Always provide a default: !f() { git log -${1:-10} HEAD; }; f.

2. Quoting: If your command contains spaces or special characters, wrap the whole value in single quotes. Inside, use double quotes if needed. For example: git config --global alias.wip '!git add -A && git commit -m "WIP"'. The outer single quotes protect the inner double quotes.

3. Shell expansion: When using !, the command runs in a shell. Variables like $HOME get expanded. If you want a literal $, escape it with \$. This is especially tricky in aliases that use $(...) for command substitution.

4. Performance: Each ! alias spawns a new shell. For simple commands, avoid !. For complex ones, the overhead is negligible.

alias-gotchas.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// io.thecodeforge — DevOps tutorial

# Gotcha 1: Missing default argument
# Bad: no default
git config --global alias.last '!f() { git log -$1 HEAD; }; f'
# git last -> error: unknown switch `'
# Fix: add default
git config --global alias.last '!f() { git log -${1:-1} HEAD; }; f'
# Now git last shows 1 commit, git last 5 shows 5

# Gotcha 2: Quoting issues
# This fails because outer quotes are double, inner quotes conflict
git config --global alias.wip "!git add -A && git commit -m 'WIP'"
# Error: unexpected EOF while looking for matching `"'
# Fix: use single quotes outside
git config --global alias.wip '!git add -A && git commit -m "WIP"'

# Gotcha 3: Shell expansion
# This alias tries to echo $HOME, but it gets expanded at definition time
git config --global alias.home '!echo $HOME'
# git home prints the path, but if you want literal $HOME, escape: \$HOME

# Gotcha 4: Using ! unnecessarily
# Instead of:
git config --global alias.st '!git status'
# Just use:
git config --global alias.st status
Output
commit 1a2b3c4d5e6f7g8h9i0j1k2l3m4n5o6p7q8r9s0 (HEAD -> main)
Author: John Doe <john@example.com>
Date: Mon Jan 15 14:30:00 2024 +0000
Fix login bug
⚠ Production Trap:
If you use ! aliases in a CI/CD pipeline, the shell environment might be different (e.g., no $HOME set, or a different shell). Always test your aliases in the exact environment where they'll run. I've seen git deploy fail on Jenkins because the script assumed Bash but the default was Dash.

When Not to Use Aliases: The Overkill Trap

Aliases are great, but they're not always the right tool. Here's when you should skip them.

1. One-off commands: If you only run a command once a month, don't alias it. You'll forget the alias name and waste time looking it up. Just type the full command or use shell history (Ctrl+R).

2. Complex workflows that need branching logic: If your alias has multiple conditions, loops, or interactive prompts, put it in a proper script. Aliases with complex shell functions become unreadable and hard to debug. Use a script and alias to that script.

3. Team-wide enforcement: Don't force aliases on your team via .gitconfig includes unless everyone agrees. Some developers prefer their own aliases or none at all. Instead, document recommended commands in a README or provide a script that sets up optional aliases.

4. Commands that change behavior based on context: If an alias needs to behave differently depending on the branch or repo, a script is better. Aliases are static — they always run the same command.

when-not-to-alias.shBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// io.thecodeforge — DevOps tutorial

# Example of an alias that's too complex — better as a script
# This alias tries to rebase interactively on last N commits
git config --global alias.rebaselast '!f() { GIT_SEQUENCE_EDITOR=: git rebase -i HEAD~$1; }; f'
# It works, but it's cryptic. Better to create a script:
# scripts/git-rebase-last.sh:
#   #!/bin/bash
#   GIT_SEQUENCE_EDITOR=: git rebase -i HEAD~$1
# Then alias: git config --global alias.rebaselast '!scripts/git-rebase-last.sh'

# Another example: interactive alias that asks for confirmation
# This is messy in a one-liner. Use a script.

# When to just type: if you use it less than once a week, don't alias.
# Instead, rely on shell history: Ctrl+R then type part of the command.
💡Senior Shortcut:
I keep a ~/.git-aliases.sh script that defines all my aliases via git config commands. When I set up a new machine, I just run that script. It's also version-controlled in my dotfiles repo. That way I never lose my aliases.
● Production incidentPOST-MORTEMseverity: high

The Alias That Deleted Our Staging Branch

Symptom
A developer ran git cleanup and the staging branch disappeared. The team spent 2 hours recovering from a remote backup.
Assumption
Someone force-pushed a bad commit that deleted the branch.
Root cause
The alias cleanup was defined as !git branch --merged | grep -v '\*\|main\|staging' | xargs git branch -d. It worked locally but on a shared machine, the branch list included staging because it was merged, and grep -v didn't filter it correctly (regex issue). The xargs git branch -d deleted it.
Fix
Changed the alias to: !git branch --merged | grep -v -E '(\*|main|staging|production)' | xargs git branch -d. Added -E for extended regex and escaped parentheses properly. Also added a --dry-run option first.
Key lesson
  • Always test aliases with --dry-run or echo before running destructive commands.
  • And never trust grep -v without testing the regex on the exact output.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
Alias not found: git: 'xyz' is not a git command. See 'git --help'.
Fix
1. Check alias exists: git config --global --get alias.xyz. 2. If empty, alias wasn't created or was removed. 3. Re-create alias. 4. If alias exists but still fails, check for typos in the alias name when running.
Symptom · 02
Alias runs but produces wrong output or errors
Fix
1. Print the alias definition: git config --global --get alias.<name>. 2. Manually run the expanded command to isolate the issue. 3. Check for shell expansion issues: if using !, test the shell command separately. 4. Verify quoting: ensure single quotes around the alias value.
Symptom · 03
Alias works locally but fails on CI/CD
Fix
1. Check if CI/CD environment has the same global config. 2. Use git config --local in the repo for CI/CD-specific aliases. 3. Define aliases in a setup script that runs before Git commands. 4. Avoid ! aliases that depend on specific shell features (e.g., Bash-specific syntax).
★ Git Alias Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
`git: 'xyz' is not a git command`
Immediate action
Check if alias exists
Commands
git config --global --get alias.xyz
git config --global --list | grep alias
Fix now
Re-create alias: git config --global alias.xyz '<command>'
Alias runs but shows error like `fatal: ambiguous argument`+
Immediate action
Print the expanded command
Commands
git config --global --get alias.<name>
Run the expanded command manually
Fix now
Fix quoting or argument handling in alias definition
Alias with `!` does nothing or hangs+
Immediate action
Check if shell command works standalone
Commands
Run the shell part directly in terminal
Check for missing dependencies or environment variables
Fix now
Simplify the alias or move logic to a script
Alias works but is slow+
Immediate action
Check if `!` is unnecessary
Commands
Remove `!` and use plain Git command if possible
Profile the shell command
Fix now
Convert to simple alias without !
FeatureSimple Alias (no !)Shell Alias (!)
PerformanceFast (no shell spawn)Slower (spawns shell)
CapabilitiesOnly Git commandsAny shell command, pipes, loops
Argument handlingAppended to commandMust handle via shell function
ComplexitySimple, easy to readCan become complex and fragile
Use caseShortening common Git commandsMulti-step workflows, external scripts
⚙ Quick Reference
6 commands from this guide
FileCommand / CodePurpose
create-first-alias.shgit config --global alias.st statusWhy You Need Git Aliases (And Why You've Been Wasting Time)
alias-examples.shgit config --global alias.lg 'log --oneline --graph --all --decorate'Creating Your First Alias
advanced-aliases.shgit config --global alias.wip '!git add -A && git commit -m "WIP $(date)"'Advanced Aliases
manage-aliases.shgit config --global --get-regexp aliasManaging and Sharing Aliases
alias-gotchas.shgit config --global alias.last '!f() { git log -$1 HEAD; }; f'Alias Gotchas
when-not-to-alias.shgit config --global alias.rebaselast '!f() { GIT_SEQUENCE_EDITOR=: git rebase -i...When Not to Use Aliases

Key takeaways

1
Git aliases turn long commands into short ones
less typing, fewer errors, faster workflow.
2
Use ! only when you need shell features; for simple Git commands, omit it for better performance.
3
Always test destructive aliases with --dry-run or on a safe branch first
one bad alias can delete branches or rewrite history.
4
Share aliases via a script or include file, but don't force them on your team
let each developer opt in.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does Git handle argument passing in aliases? What happens if you run...
Q02SENIOR
When would you choose a shell alias (`!`) over a simple alias, and what ...
Q03SENIOR
What happens if you define an alias with the same name as an existing Gi...
Q04JUNIOR
How do you list all Git aliases currently configured?
Q05SENIOR
A developer reports that `git cleanup` deleted their feature branch. How...
Q06SENIOR
How would you design a set of Git aliases for a team to enforce consiste...
Q01 of 06SENIOR

How does Git handle argument passing in aliases? What happens if you run `git lg -5` when `lg` is defined as `log --oneline --graph --all --decorate`?

ANSWER
Git appends any additional arguments to the end of the alias command. So git lg -5 becomes git log --oneline --graph --all --decorate -5. This works because Git's log command accepts -5 as a limit. However, if the alias uses ! with a shell function, arguments must be handled explicitly via $@ or $1.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
How do I create a Git alias with arguments?
02
What's the difference between `git config --global` and `git config --local` for aliases?
03
How do I remove a Git alias?
04
Can Git aliases run external scripts?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 18, 2026
last updated
2,466
articles · all by Naren
🔥

That's Git. Mark it forged?

4 min read · try the examples if you haven't

Previous
Git Worktrees: Work on Multiple Branches Simultaneously
51 / 51 · Git
Next
Containerization vs Virtualization