Dotfile manager with git-powered branching
Project description
dot-man
Dotfile manager with git-powered branching
Features • Installation • Quick Start • Commands • Configuration
Overview
dot-man manages your dotfiles across multiple machines using git branches. Each branch represents a different configuration (work, personal, minimal, server).
# Switch between configurations instantly
dot-man navigate work # Deploy work setup
dot-man navigate personal # Deploy personal setup
# Audit for secrets before pushing
dot-man audit --strict
Features
- 📦 PyPI ready - Install with
pip install dotman-git - 🌿 Git-powered branching - Each config is a branch, easy to sync
- 🔐 Secret detection - Automatically redacts API keys, passwords, tokens
- 🔒 Encryption - Encrypt/decrypt sensitive files with GPG or AGE
- 🔄 Save & deploy - One command to save current state and switch configs
- ☁️ Remote sync - Push/pull dotfiles across machines with
dot-man sync - ⚡ Pre/Post hooks - Run commands before/after deploying (e.g., reload config)
- 📝 Edit in place - Opens your
$EDITORfor quick changes - 🛡️ Dry-run mode - Preview changes before making them
- 🐚 Shell completions - Auto-installed for Bash, Zsh, and Fish
- 🏷️ Tags - Tag commits for fast navigation
- 📜 History & Diff - View commit history, compare branches, restore files
- 🎨 Rich diff - Syntax-highlighted colored diffs
- 🔄 Global hooks - System-wide hooks for any dot-man command
- 🔀 Auto-detect hooks - Automatically reload configs when switching branches
- 🌍 Import - Import from git repos, chezmoi, yadm, or GNU Stow
- 📤 Export - Export to tar, zip, or JSON
- 🔍 Discover - Auto-detect existing dotfiles (30+ locations)
- 📦 Universal merge - Manage shared content across branches with markers
- 🌐 YAML support - Config files in TOML or YAML format
Current Status
| Metric | Value |
|---|---|
| Version | 1.0.0 (Production) |
| Test Coverage | 61% |
| Commands | 30+ |
| Python | 3.9+ |
What's New in 1.0.0
- PyPI Ready - Install with
pip install dotman-git - Auto shell completions - Automatically installed on first run
dot-man init --import- Import from existing git repositoriesdot-man navigate- Unified command replacingswitchandcheckoutdot-man import- Import from other dotfile managers:dot-man import chezmoi/dot-man import yadm/dot-man import stowdot-man import all- Auto-detect and import
dot-man export- Export to portable formats:dot-man export tar backup.tar.gzdot-man export zip dots.zipdot-man export json manifest.json
dot-man discover- Auto-detect existing dotfiles (30+ locations)dot-man encrypt- Encrypt/decrypt sensitive files (GPG/AGE)dot-man diff --rich- Syntax-highlighted diffs with colors
Deprecated (use navigate instead)
switch→dot-man navigate <branch>checkout→dot-man navigate <commit>
v1.0.0 Release ✅
- Test Coverage: 61%
- PyPI: Published as
dotman-git - Shell completions: Auto-installed for Bash, Zsh, Fish
Installation
From PyPI (Recommended)
pip install dotman-git
This automatically installs shell completions for Bash, Zsh, and Fish.
With pipx
pipx install dotman-git
From Source
git clone https://github.com/BeshoyEhab/dot-man.git
cd dot-man
pip install .
Uninstall
pip uninstall dotman-git
Quick Start
1. Initialize
dot-man init
Creates ~/.config/dot-man/ with a git repository.
2. Add your dotfiles
dot-man add ~/.bashrc
dot-man add ~/.zshrc
dot-man add ~/.config/nvim
3. Save your configuration
dot-man navigate main
This copies your dotfiles to the repository and commits them.
4. Create different configurations
Create a work configuration:
dot-man navigate work # Creates 'work' branch with current files
Modify files, then switch back:
dot-man navigate main # Saves work, deploys main
How Navigation Works
The navigate Command
dot-man navigate is your main command for switching between configurations.
# Switch branches
dot-man navigate work # Switch to 'work' branch
dot-man navigate personal # Switch to 'personal' branch
# Preview before switching (recommended!)
dot-man navigate work --preview # See what changes
dot-man navigate work --preview --diff # See full diff
# Switch to specific point in history
dot-man navigate v1.0 # Go to tag
dot-man navigate abc1234 # Go to commit (detached HEAD)
# Branch at tag
dot-man navigate work@v1.0 # Switch to work branch at tag v1.0
Branch vs Commit: What's the Difference?
| Type | Purpose | Changes Saved? |
|---|---|---|
Branch (e.g., main, work) |
Your full configuration | Yes - auto-saved when you switch |
Tag (e.g., v1.0) |
Snapshot in time | No - just marks a point |
Commit (e.g., abc1234) |
Specific state | No - viewing only (detached HEAD) |
⚠️ Deprecated Commands
| Old Command | Use Instead | Why |
|---|---|---|
switch |
navigate |
Unified command with preview |
checkout |
navigate |
Same functionality |
Run these commands and they'll show deprecation warnings. Use navigate instead.
Commands
Core Commands
| Command | Description |
|---|---|
dot-man init |
Initialize repository at ~/.config/dot-man/ |
dot-man status |
Show tracked files and their status |
dot-man navigate <target> |
Navigate to branch, tag, or commit (unified) |
dot-man switch <target> |
Switch to branch, tag, or commit (legacy) |
dot-man edit |
Open dot-man.toml in your editor |
dot-man deploy <branch> |
One-way deploy (for new machines) |
dot-man audit |
Scan repository for secrets |
dot-man log |
Show commit history with optional diffs |
dot-man checkout <target> |
Checkout a specific commit or tag (detached) |
dot-man diff |
Show changes between branches or files |
dot-man revert <file> |
Revert file to repository version |
dot-man revert <file> -c <sha> |
Restore file from specific commit |
dot-man template |
Manage template variables |
dot-man profile |
Manage machine-specific profiles |
| `dot-man hooks list | create |
dot-man discover |
Auto-detect existing dotfiles |
dot-man import <source> |
Import from chezmoi, yadm, or stow |
dot-man export <format> |
Export to tar, zip, or json |
dot-man encrypt |
Encrypt/decrypt sensitive files |
Navigate Command
The navigate command supports multiple target types:
dot-man navigate work # Navigate to branch
dot-man navigate work@tag # Navigate to branch at tag position
dot-man navigate abc1234 # Navigate to specific commit
dot-man navigate my-tag # Navigate to tag
# Override default save behavior
dot-man navigate work --save # Force save current changes
dot-man navigate work --no-save # Force discard current changes
dot-man navigate --save work # Flexible argument order
Set a default behavior preference:
dot-man config set navigate.default_behavior no-save
Navigate Command (Unified)
The navigate command is the unified way to switch between branches, tags, and commits with preview capabilities:
# Basic navigation
dot-man navigate work # Switch to branch
dot-man navigate work@tag # Switch to branch at tag position
dot-man navigate abc1234 # Switch to specific commit
dot-man navigate my-tag # Switch to tag
# Preview changes before switching
dot-man navigate work --preview # Preview diff
dot-man navigate work --preview --diff # Show full diff
dot-man navigate work --preview --files-only # Only commits with file changes
# Override default save behavior
dot-man navigate work --save # Force save current changes
dot-man navigate work --no-save # Force discard current changes
Hooks
Hooks allow you to run custom scripts before or after commands:
# List available hooks
dot-man hooks list
# Create a hook (creates ~/.config/dot-man/hooks/pre_switch)
dot-man hooks create pre switch
# Create a post-deploy hook
dot-man hooks create post deploy
# Delete a hook
dot-man hooks delete pre checkout
Hook scripts have environment variables available:
DOTMAN_HOOK_COMMAND- The command being run (switch, checkout, deploy, etc.)DOTMAN_HOOK_PHASE- "pre" or "post"DOTMAN_SOURCE- Source branch/commit (for switch)DOTMAN_TARGET- Target branch/commit
Remote & Sync
| Command | Description |
|---|---|
dot-man sync |
Push/pull dotfiles with remote repository |
dot-man remote set <url> |
Set remote repository URL |
dot-man remote get |
Show current remote URL |
dot-man remote sync-branch |
Sync local/remote branch names (main vs master) |
dot-man setup |
Guided setup for GitHub remote (supports gh) |
Branch Management
| Command | Description |
|---|---|
dot-man branch list |
List all configuration branches |
dot-man branch delete <name> |
Delete a branch (prompts if unmerged) |
Tags
Tags allow you to mark specific commits for fast navigation:
| Command | Description |
|---|---|
dot-man tag list |
List all tags |
dot-man tag create <name> |
Create tag at current commit |
dot-man tag create <name> <sha> |
Create tag at specific commit |
dot-man tag delete <name> |
Delete a tag |
dot-man tag switch <name> |
Switch to tag (checkout tag) |
Diff & History
Compare changes and restore from history:
# Show uncommitted changes
dot-man diff
# Compare current branch with main
dot-man diff --branch main
# Show changes for a specific file
dot-man diff ~/.bashrc
# Show staged changes
dot-man diff --staged
# Show last 20 commits with diffs
dot-man log --diff -n 20
# Restore file from specific commit
dot-man revert ~/.bashrc -c abc1234
# View commit history for a file
dot-man log -- path/to/file
Profile Variables
Profiles allow different machine-specific configurations:
# Create a profile
dot-man profile create work-laptop -h laptop -h work-laptop -i minimal
# Set the branch for a profile
dot-man profile set-branch work-laptop work-main
# Auto-detect profile by hostname
dot-man profile detect
# Switch to a profile
dot-man profile switch work-laptop
Profile inheritance: Profiles can inherit from another profile.
Utilities
| Command | Description |
|---|---|
dot-man repo |
Print repository path for direct access |
dot-man shell |
Open a shell in the repository directory |
dot-man verify |
Validate repository integrity |
dot-man doctor |
Run diagnostics and health checks |
Options
dot-man navigate work --dry-run # Preview without changes
dot-man navigate work --force # Skip confirmation
dot-man navigate work --save # Save current changes before switching
dot-man navigate work --no-save # Discard current changes
dot-man sync --push-only # Only push, don't pull
dot-man sync --pull-only # Only pull, don't push
dot-man audit --strict # Exit with error if secrets found
dot-man audit --fix # Auto-redact detected secrets
dot-man status --secrets # Highlight files with secrets
dot-man diff --rich/--no-rich # Enable/disable rich diff colors (default: on)
dot-man discover --add # Auto-add detected configs to dot-man.toml
dot-man import chezmoi --dry-run # Preview what would be imported
dot-man export tar backup.tar.gz # Export to tar archive
dot-man encrypt status # Show encryption status
Configuration
Supported Formats
dot-man supports both TOML and YAML configuration formats:
- TOML:
dot-man.toml(default) - YAML:
dot-man.yamlordot-man.yml
Example: TOML format
Located at ~/.config/dot-man/repo/dot-man.toml:
# Global defaults (applied to all sections)
[defaults]
secrets_filter = true
update_strategy = "replace"
# Individual file sections
[bashrc]
paths = ["~/.bashrc"]
[nvim]
paths = ["~/.config/nvim"]
update_strategy = "rename_old"
[ssh-config]
paths = ["~/.ssh/config"]
secrets_filter = true
Example: YAML format
Located at ~/.config/dot-man/repo/dot-man.yaml:
defaults:
secrets_filter: true
update_strategy: replace
bashrc:
paths:
- ~/.bashrc
nvim:
paths:
- ~/.config/nvim
update_strategy: rename_old
ssh-config:
paths:
- ~/.ssh/config
secrets_filter: true
Global Configuration
Global settings are stored in ~/.config/dot-man/global.toml. Use dot-man config to manage them:
# View current settings
dot-man config list
# Set switch default behavior (save or no-save)
dot-man config set switch.default_behavior no-save
| Setting | Values | Description |
|---|---|---|
switch.default_behavior |
save / no-save | Default for switch command |
Options
| Option | Values | Description |
|---|---|---|
paths |
list of paths | Paths to track (supports $HOME, $USER, etc.) |
local_path |
path | Path on your filesystem |
repo_path |
path | Path in the repository |
secrets_filter |
true/false | Redact secrets when saving |
update_strategy |
replace/rename_old/ignore | How to deploy files |
pre_deploy |
command string | Shell command to run before file is changed |
post_deploy |
command string | Shell command to run after file is changed |
Environment Variables in Paths
Paths support environment variable expansion:
[work-files]
paths = ["$WORK_DIR/config", "~/$USER/.config/app"]
work-files:
paths:
- $WORK_DIR/config
- ~/$USER/.config/app
Troubleshooting
Common Issues
Q: I'm on a detached HEAD state. How do I get back?
# List your branches
dot-man branch list
# Return to a branch
dot-man navigate main
Q: How do I undo the last switch?
# Your previous work is saved as a commit
dot-man log
# Switch back to it
dot-man navigate <previous-branch>
Q: My changes aren't being saved when I switch
# Make sure you're using the save mode (default)
dot-man navigate work --save
# Or check if secrets are being redacted
dot-man status
Q: How do I see what changed in a branch?
# Preview changes before switching
dot-man navigate work --preview
# See full diff
dot-man navigate work --preview --diff
Q: What are the differences between branches?
# Compare two branches
dot-man diff --branch main
# Show only commits that changed tracked files
dot-man navigate main --preview --files-only
Getting Help
# See all commands
dot-man --help
# See specific command help
dot-man navigate --help
dot-man add --help
# Diagnose issues
dot-man doctor
# Check repository integrity
dot-man verify
Secret Detection
dot-man detects and redacts common secrets:
| Pattern | Severity | Example |
|---|---|---|
| Private Keys | CRITICAL | -----BEGIN RSA PRIVATE KEY----- |
| AWS Keys | CRITICAL | AKIAIOSFODNN7EXAMPLE |
| GitHub Tokens | HIGH | ghp_xxxxxxxxxxxx |
| API Keys | HIGH | api_key=sk_live_xxxxx |
| Passwords | HIGH | password=mysecret |
Run dot-man audit to scan your repository.
Documentation
- Development Guide Manual - In-depth architecture and development guide
- Command Specifications - Detailed command behavior
- Security Specification - Secret detection patterns
- Development Roadmap - Version milestones
- Architecture Overview - High-level system structure
Contributing
See DEVELOPMENT.md for setup and contribution guidelines.
# Setup development environment
python -m venv venv
source venv/bin/activate
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
License
MIT License - see LICENSE
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dotman_git-1.0.1.tar.gz.
File metadata
- Download URL: dotman_git-1.0.1.tar.gz
- Upload date:
- Size: 191.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3ce089ee43a30b6ae7eb30b93cc4444db364564c628f21f4851831e4c244d5a6
|
|
| MD5 |
2cf5935f8109efdf554b5fa69ddca9ea
|
|
| BLAKE2b-256 |
ad424f9fc80d83f03e578be1bdc4d7fe84c3aaee4484fac8c64d7c04cacab2ee
|
Provenance
The following attestation bundles were made for dotman_git-1.0.1.tar.gz:
Publisher:
publish.yml on BeshoyEhab/dot-man
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotman_git-1.0.1.tar.gz -
Subject digest:
3ce089ee43a30b6ae7eb30b93cc4444db364564c628f21f4851831e4c244d5a6 - Sigstore transparency entry: 1563766923
- Sigstore integration time:
-
Permalink:
BeshoyEhab/dot-man@88e3cefdbef3493daebd67a73303e9cb8c6d02dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/BeshoyEhab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@88e3cefdbef3493daebd67a73303e9cb8c6d02dd -
Trigger Event:
push
-
Statement type:
File details
Details for the file dotman_git-1.0.1-py3-none-any.whl.
File metadata
- Download URL: dotman_git-1.0.1-py3-none-any.whl
- Upload date:
- Size: 152.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
489a95dce30c9a6698211b0a53696ffcfa20b0eec43ab71722c7d7c4c9a1c7a5
|
|
| MD5 |
333213becff21ee8f4208f22d191cb5b
|
|
| BLAKE2b-256 |
8d000c860b31a8cebd5efa625f380ac61bf0d4e16d641840f134b78a78370875
|
Provenance
The following attestation bundles were made for dotman_git-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on BeshoyEhab/dot-man
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotman_git-1.0.1-py3-none-any.whl -
Subject digest:
489a95dce30c9a6698211b0a53696ffcfa20b0eec43ab71722c7d7c4c9a1c7a5 - Sigstore transparency entry: 1563766930
- Sigstore integration time:
-
Permalink:
BeshoyEhab/dot-man@88e3cefdbef3493daebd67a73303e9cb8c6d02dd -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/BeshoyEhab
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@88e3cefdbef3493daebd67a73303e9cb8c6d02dd -
Trigger Event:
push
-
Statement type: