---
title: "Fish Shell — abbr vs alias Patterns"
aliases: [fish-abbreviations, fish-abbr, fish-alias-vs-abbr]
tags: [fish, shell, dotfiles, terminal, abbr, alias]
sources:
  - "daily/2026-04-17.md"
created: 2026-04-17
updated: 2026-04-17
---

# Fish Shell — abbr vs alias Patterns

Fish shell offers two ways to create command shortcuts: `abbr` (abbreviations) and `alias`. The choice between them affects transparency and interaction with third-party Fish plugins like forgit. Using `abbr` for expanded commands and `alias` for invisible substitutions is the idiomatic Fish pattern.

## Key Points

- **`abbr`** expands in the command line before execution — the user sees the full command in the prompt history, making actions transparent and auditable
- **`alias`** runs as a hidden substitution — the original alias name appears in history, not the underlying command
- Use `abbr` for git/docker/uv shortcuts where seeing the expanded command is useful; use `alias` for transparent replacements like `ls→lsd`, `cat→bat`
- Fish abbreviations can conflict with forgit plugin functions — forgit defines `gco`, `grb`, `glo`, etc. as interactive functions; naming an abbreviation the same will shadow the forgit function
- Resolve forgit conflicts by renaming your abbreviation (e.g., `gco` → `gch` for `git checkout`)

## Details

### abbr vs alias Decision Table

| Use case | Use | Why |
|----------|-----|-----|
| `git checkout` → `gch` | `abbr` | Expands visibly — you see `git checkout` in prompt |
| `docker compose` → `dc` | `abbr` | Expands — clear what's running |
| `ls` → `lsd` | `alias` | Should be invisible — `ls` stays in history |
| `cat` → `bat` | `alias` | Transparent replacement — looks like `cat` |
| `forgit` interactive commands | none | Provided by forgit plugin — don't shadow |

### Defining Abbreviations

```fish
# In ~/.config/fish/config.fish or ~/.config/fish/abbreviations.fish

# Git shortcuts (expand visibly)
abbr --add gst 'git status'
abbr --add gch 'git checkout'    # not gco — conflicts with forgit
abbr --add gpl 'git pull'
abbr --add gps 'git push'
abbr --add glo 'git log --oneline'  # renamed — forgit uses glo too

# Docker
abbr --add dc 'docker compose'
abbr --add dcu 'docker compose up -d'
abbr --add dcd 'docker compose down'

# uv (Python package manager)
abbr --add uvr 'uv run'
abbr --add uvs 'uv sync'
```

### Defining Aliases (Transparent Replacements)

```fish
# In ~/.config/fish/config.fish

# These should feel like the original command
alias ls='lsd'
alias cat='bat --paging=never'
alias grep='rg'
alias find='fd'
```

### Forgit Conflict Resolution

forgit (interactive git fzf plugin) defines these functions by default:

| forgit function | What it does |
|----------------|--------------|
| `gco` | Interactive `git checkout` |
| `grb` | Interactive `git rebase` |
| `glo` | Interactive `git log` |
| `gbl` | Interactive `git blame` |
| `gd` | Interactive `git diff` |

If you have abbreviations with the same names, the abbreviation wins on expansion but the forgit function is still reachable by full name. The practical fix: rename your abbreviation to avoid the conflict (`gco` → `gch`, `glo` → `glg`).

### Viewing All Current Abbreviations

```fish
abbr          # list all abbreviations
alias         # list all aliases
functions     # list all functions (includes forgit)
```

### Persistence

Both `abbr` and `alias` defined in `config.fish` persist across sessions. `abbr --add` called interactively creates a universal variable that also persists — but storing abbreviations in `config.fish` is more portable for dotfiles repos.

## Related Concepts

- [[wiki/concepts/fish-shell-path-config]] — Fish PATH configuration and SSH aliases as Fish functions
- [[wiki/dotfiles/_index]] — full dotfiles topic: Kitty, Fish, WezTerm, LazyVim, Rust CLI tools

## Sources

- [[daily/2026-04-17.md]] — Fish abbreviations setup session; `abbr` chosen over `alias` for git/docker/uv commands; `gco/grb/glo` conflicts with forgit resolved by renaming abbreviations; transparent replacements (`ls→lsd`, `cat→bat`) kept as `alias`
