oh-my-dot
A cross-platform dotfile manager with an advanced shell framework written in Go.
Oh-my-dot helps you manage your dotfiles across multiple machines with git integration and provides a powerful shell framework for managing shell configurations (aliases, prompts, completions) across bash, zsh, fish, PowerShell, and POSIX sh.
Features
- Cross-Platform: Works on Windows, macOS, and Linux
- Git Integration: Store and sync your dotfiles with git
- Shell Framework: Manage shell features with advanced loading strategies
- Eager loading for instant availability
- Deferred loading for faster shell startup
- On-command loading for lazy evaluation
- Local Overrides: Per-machine customizations with security validation
- Health Checks: Built-in
doctor command to validate configuration
- Interactive Mode: Browse and manage features interactively
Install
Linux and macOS (Automatic)
Run the install script to automatically download and install the latest version:
curl -fsSL https://raw.githubusercontent.com/PatrickMatthiesen/oh-my-dot/main/install.sh | bash
Security Note: For added security, you can download and inspect the script before running it:
curl -fsSL https://raw.githubusercontent.com/PatrickMatthiesen/oh-my-dot/main/install.sh -o install.sh
# Review the script
cat install.sh
# Run it
bash install.sh
This script will:
- Detect your OS and architecture automatically
- Download the latest release from GitHub
- Install the binary to
~/.oh-my-dot/bin
- Create a symlink in
~/.local/bin
- Add the binary to your current session's PATH
If you need to install a specific version, you can set the OH_MY_DOT_VERSION environment variable:
curl -fsSL https://raw.githubusercontent.com/PatrickMatthiesen/oh-my-dot/main/install.sh | OH_MY_DOT_VERSION=v0.0.25 bash
Windows (Winget)
winget install PatrickMatthiesen.oh-my-dot
Manual Installation
- Find the latest release matching your CPU architecture and Operating system.
- Download the executable to a persistent folder.
A folder you know won't change or randomly be deleted
I recommend putting it under $HOME/oh-my-dot
- Add the folder to your PATH
- Start using oh-my-dot
Quick Start
Initialize Repository
# New fresh config
oh-my-dot init github.com/username/dotfiles
# Or with explicit remote
oh-my-dot init --remote github.com/username/dotfiles
# Existing config (use --force to override)
oh-my-dot init -r github.com/username/dotfiles -f /path/to/dotfiles --force
Apply Dotfiles
oh-my-dot apply
This will:
- Link your dotfiles to their target locations
- Install shell hooks for the shell framework
Shell Completion
Enable tab completion for your shell:
# Bash
echo 'source <(oh-my-dot completion bash)' >> ~/.bashrc
# Zsh
echo 'source <(oh-my-dot completion zsh)' >> ~/.zshrc
# Fish
oh-my-dot completion fish > ~/.config/fish/completions/oh-my-dot.fish
# PowerShell
oh-my-dot completion powershell >> $PROFILE
Shell Framework
The shell framework allows you to manage shell configurations as modular features with advanced loading strategies.
Adding Features
Interactive Mode (Recommended)
oh-my-dot feature add -i
Browse the catalog and select features to add. The interactive mode automatically detects your current shell, places it at the top of the shell selection list, and pre-selects it for your convenience.
Supported Shells: bash, zsh, fish, PowerShell, and POSIX sh
Direct Addition
# Add to current shell (auto-detected)
oh-my-dot feature add git-prompt
# Add to specific shell
oh-my-dot feature add kubectl-completion --shell bash
# Add to all supported shells
oh-my-dot feature add core-aliases --all
When no --shell flag is provided, oh-my-dot tries to detects your current shell and adds the feature to it.
Loading Strategies
Features can be loaded with different strategies to optimize shell startup:
Eager Loading (Default)
Loads immediately during shell startup:
oh-my-dot feature add git-prompt --strategy eager
Deferred Loading
Loads in background for interactive shells (faster startup):
oh-my-dot feature add kubectl-completion --strategy defer
On-Command Loading
Lazy loads when specific commands are invoked:
oh-my-dot feature add nvm --strategy on-command --on-command nvm,node,npm
Managing Features
# List features
oh-my-dot feature list
oh-my-dot feature list --shell bash
# Remove features
oh-my-dot feature remove -i # Interactive
oh-my-dot feature remove git-prompt # Direct
oh-my-dot feature remove kubectl --all # From all shells
# Update/refresh features
oh-my-dot feature update -i # Interactive
oh-my-dot feature update powershell-aliases # Direct
oh-my-dot feature update powershell-aliases --shell powershell
# Enable/disable features
oh-my-dot feature enable git-prompt
oh-my-dot feature disable kubectl --shell bash
# Show feature info
oh-my-dot feature info git-prompt
Feature Files
Features are stored in omd-shells/<shell>/features/:
# Example: omd-shells/bash/features/git-prompt.sh
# Add your custom shell code here
parse_git_branch() {
git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}
export PS1="\u@\h \W \$(parse_git_branch) $ "
Local Overrides
Create enabled.local.json for per-machine customizations:
# omd-shells/bash/enabled.local.json
{
"features": [
{
"name": "git-prompt",
"strategy": "eager"
},
{
"name": "work-vpn",
"strategy": "on-command",
"onCommand": ["vpn-connect"]
}
]
}
Security Requirements:
- File must be owned by current user
- File must not be group or world writable
- File must be a regular file (not a symlink)
Invalid local overrides are automatically ignored with warnings.
Health Checks
Validate your shell framework setup:
# Check all shells
oh-my-dot doctor
# Check specific shell
oh-my-dot doctor --shell bash
# Auto-fix issues
oh-my-dot doctor --fix
The doctor checks:
- Directory structure
- Manifest validity
- Feature file existence
- Profile hooks installation
- Local override security
- Init script syntax
PowerShell Support
Oh-my-dot fully supports PowerShell (both Windows PowerShell 5.1 and PowerShell Core 7+):
Auto-Detection: When running feature add -i in PowerShell, your current shell is automatically detected and pre-selected.
PowerShell-Specific Features:
powershell-prompt - Custom prompt with git status
powershell-aliases - Common PowerShell aliases and shortcuts
posh-git - Git integration for PowerShell
Profile Integration:
# PowerShell profile ($PROFILE)
. "$HOME\dotfiles\omd-shells\powershell\init.ps1"
The init script supports all loading strategies (eager, defer, on-command) with PowerShell-native syntax.
Directory Structure
dotfiles/
├── files/ # Your dotfiles
│ ├── .gitconfig
│ ├── .vimrc
│ └── ...
├── omd-shells/ # Shell framework
│ ├── bash/
│ │ ├── enabled.json # Base configuration (tracked)
│ │ ├── enabled.local.json # Local overrides (untracked)
│ │ ├── init.sh # Auto-generated init script
│ │ ├── features/ # Feature implementations
│ │ │ ├── git-prompt.sh
│ │ │ └── aliases.sh
│ │ └── helpers/ # Shared helper functions
│ ├── zsh/
│ ├── fish/
│ └── powershell/
└── .linkings # Dotfile link mappings
Configuration
Oh-my-dot uses a .oh-my-dot.yaml config file:
repo-path: ~/dotfiles
remote: github.com/username/dotfiles
Commands Reference
Core Commands
oh-my-dot init - Initialize dotfiles repository
oh-my-dot apply - Apply dotfiles and shell integration
oh-my-dot push - Commit and push changes to git
oh-my-dot pull - Pull changes from git
oh-my-dot status - Show repository status
Feature Commands
oh-my-dot feature add [-i] <feature> - Add shell feature
oh-my-dot feature remove [-i] <feature> - Remove shell feature
oh-my-dot feature list - List all features
oh-my-dot feature enable <feature> - Enable feature
oh-my-dot feature disable <feature> - Disable feature
oh-my-dot feature info <feature> - Show feature details
Utility Commands
oh-my-dot doctor [--fix] - Health check and diagnostics
oh-my-dot completion <shell> - Generate shell completion
oh-my-dot version - Show version information
Automatic Remote Update Checks
oh-my-dot performs a lightweight remote sync check (no full fetch) on:
oh-my-dot add
oh-my-dot remove
oh-my-dot apply
oh-my-dot push
oh-my-dot doctor
When updates are detected, oh-my-dot shows a non-blocking notice and suggests oh-my-dot pull.
Sync state messages:
- Remote ahead: prompts you to run
oh-my-dot pull
- Diverged: warns that pull may require conflict resolution
- Local ahead: suggests running
oh-my-dot push
Global Flags
-i, --interactive - Force interactive mode
--no-interactive - Disable all prompts (for CI/scripting)
Examples
Basic Workflow
# Initialize
oh-my-dot init github.com/username/dotfiles
# Add features interactively
oh-my-dot feature add -i
# Apply changes
oh-my-dot apply
# Commit and push
oh-my-dot push
Advanced Feature Management
# Add git prompt with eager loading
oh-my-dot feature add git-prompt --strategy eager --shell bash
# Add kubectl completion with deferred loading
oh-my-dot feature add kubectl --strategy defer
# Add nvm with on-command loading
oh-my-dot feature add nvm --strategy on-command --on-command nvm,node,npm
# Create local override for work machine
cat > ~/dotfiles/omd-shells/bash/enabled.local.json << 'EOF'
{
"features": [
{
"name": "work-aliases",
"strategy": "eager"
}
]
}
EOF
chmod 600 ~/dotfiles/omd-shells/bash/enabled.local.json
# Validate setup
oh-my-dot doctor --fix
Troubleshooting
# Check health
oh-my-dot doctor
# Fix common issues
oh-my-dot doctor --fix
# Re-apply shell hooks
oh-my-dot apply
# Check git status
oh-my-dot status
Known Issues
SSH
If you are using SSH to clone your dotfiles, you will need to add your SSH key to the SSH-Agent. This is because oh-my-dot uses Git under the hood:
ssh-add ~/.ssh/id_rsa
If you are having issues on Windows you might want to install a newer version of OpenSSH. The one that comes with Windows is outdated and requires a bit more work to get going.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Security
Oh-my-dot includes security features to protect against path traversal and other vulnerabilities. See docs/SECURITY.md for details on:
- Path traversal protection
- Configurable home directory restrictions
- Input validation
To report security vulnerabilities, please use GitHub Security Advisories.
License
This project is licensed under the MIT License - see the LICENSE file for details.