dot-man
Dotfile manager with git-powered branching
Switch your entire development environment in one command.
Install · Quick Start · Commands · Config · Docs
What is dot-man?
dot-man stores your dotfiles in a git repository and uses branches as configuration profiles. Each branch is a complete, deployable snapshot of your environment.
Your Machine dot-man Repo Any Machine
────────────── ──────────── ───────────
~/.bashrc ──── save ──► branch: main ── deploy ──► ~/.bashrc
~/.config/nvim ──── save ──► branch: work ── deploy ──► ~/.config/nvim
~/.gitconfig ──── save ──► branch: server ~/.gitconfig
Secrets are never committed. API keys, tokens and passwords are automatically detected, encrypted locally in a vault, and replaced with hashes in the repository before any commit.
Features
|
Core
|
Advanced
|
Developer
|
Installation
From PyPI (recommended)
pip install dotman-git
Shell completions are installed automatically on first run.
With pipx (isolated)
pipx install dotman-git
From source
git clone https://github.com/BeshoyEhab/dot-man.git
cd dot-man
pip install .
Verify
dot-man --version
Quick Start
# 1. Initialize — runs an interactive wizard that auto-detects your dotfiles
dot-man init
# 2. Add files manually if needed
dot-man add ~/.bashrc
dot-man add ~/.config/nvim
# 3. Create a "work" profile (branch)
dot-man navigate work
# 4. Edit your work-specific configs, then switch back — changes are saved automatically
dot-man navigate main
# 5. See what's changed
dot-man status
dot-man diff
How Branching Works
Each branch is an independent configuration. Switching branches runs three phases automatically:
dot-man navigate work
│
├─► Phase 1: Save — copies your files into the repo and commits
├─► Phase 2: Switch — git checkout work
└─► Phase 3: Deploy — copies repo files back to your home directory
| Branch | Purpose |
|---|---|
main |
Personal daily driver |
work |
Office: proxy, work aliases |
server |
Minimal: headless, no GUI tools |
laptop |
Mobile: battery saving, HiDPI |
Commands
Global Flags
These apply to every command and come before the subcommand:
| Flag | Description |
|---|---|
dot-man --quiet <cmd> |
Suppress non-essential output (errors still show) |
dot-man --yes <cmd> |
Assume yes for all confirmation prompts |
dot-man --no-input <cmd> |
Never prompt; fail when input would be required |
dot-man --no-color <cmd> |
Disable coloured output |
dot-man --plain <cmd> |
Plain ASCII output: no emoji, colour, or box drawing |
dot-man --json <cmd> |
Emit machine-readable JSON where supported |
dot-man -v <cmd> |
Show detailed output on console |
dot-man --debug <cmd> |
Enable debug logging to file |
Navigation
| Command | Description |
|---|---|
dot-man navigate <target> |
Switch to branch, tag, or commit |
dot-man navigate work --preview |
Preview what will change |
dot-man navigate work --preview --diff |
Full diff before switching |
dot-man navigate work --no-save |
Discard local changes and switch |
dot-man navigate v1.0 |
Jump to a tag |
dot-man navigate abc1234 |
Checkout a specific commit |
Files & Tracking
| Command | Description |
|---|---|
dot-man init |
Initialize repository with setup wizard |
dot-man add <path> |
Track a file or directory |
dot-man status |
Show tracked files and their state |
dot-man status --secrets |
Highlight files containing secrets |
dot-man diff |
Show uncommitted changes |
dot-man diff --branch main |
Compare current branch to main |
dot-man diff --rich |
Syntax-highlighted diff |
dot-man revert <file> |
Restore file from repo |
dot-man revert <file> -c abc123 |
Restore from specific commit |
dot-man watch |
Auto-save tracked files on change |
dot-man watch --no-commit |
Watch and save without committing |
History & Tags
| Command | Description |
|---|---|
dot-man log |
Show commit history |
dot-man log --diff |
History with diffs |
dot-man log --interactive |
TUI log browser |
dot-man log --commit abc123 |
Full diff for one commit |
dot-man tag create v1.0 |
Create a tag |
dot-man tag list |
List all tags |
dot-man navigate v1.0 |
Deploy a tagged snapshot |
dot-man rollback |
Roll back to previous commit |
dot-man rollback -n 3 |
Roll back 3 commits |
dot-man rollback --backup <id> |
Restore a safety backup snapshot |
dot-man rollback --list |
Show available rollback points |
Security
| Command | Description |
|---|---|
dot-man audit |
Scan repo for secrets |
dot-man audit --strict |
Exit non-zero if any secrets found |
dot-man audit --fix |
Auto-redact detected secrets |
dot-man encrypt encrypt <section> |
Encrypt a section with GPG/AGE |
dot-man encrypt status |
Show encryption status |
dot-man vault rotate-key |
Rotate the vault encryption key |
dot-man vault status |
Show secret vault statistics |
Import / Export / Discovery
| Command | Description |
|---|---|
dot-man discover |
Auto-detect existing dotfiles |
dot-man discover --add |
Add detected configs automatically |
dot-man import chezmoi |
Import from chezmoi |
dot-man import yadm |
Import from yadm |
dot-man import stow |
Import from GNU Stow |
dot-man export tar backup.tar.gz |
Export to tar archive |
dot-man export zip dots.zip |
Export to zip |
dot-man export json manifest.json |
Export to JSON manifest |
Sync & Remote
| Command | Description |
|---|---|
dot-man sync |
Push + pull with remote |
dot-man sync --push-only |
Only push |
dot-man sync --pull-only |
Only pull |
dot-man remote set <url> |
Set remote URL |
dot-man setup |
Guided GitHub remote setup |
Diagnostics
| Command | Description |
|---|---|
dot-man doctor |
Run health checks |
dot-man verify |
Validate repo integrity |
dot-man backup create |
Create a manual backup |
dot-man rollback --backup <id> |
Restore a backup (replaces backup restore) |
Deprecated
These still work and print a warning, but are hidden from help and removed in v2.0. Use the canonical command on the right.
| Deprecated | Use instead |
|---|---|
dot-man switch <target> |
dot-man navigate <target> (nav) |
dot-man checkout <target> |
dot-man navigate <target> |
dot-man tag switch <tag> |
dot-man navigate <tag> |
dot-man restore <file> <sha> |
dot-man revert <file> --commit <sha> |
dot-man show <sha> |
dot-man log --commit <sha> |
dot-man backup restore <id> |
dot-man rollback --backup <id> |
Configuration
Configuration lives in ~/.config/dot-man/repo/dot-man.toml and is tracked per branch — different branches can track different files.
TOML (default)
# Simple file tracking
[bashrc]
paths = ["~/.bashrc"]
post_deploy = "shell_reload"
# Directory with exclusions
[nvim]
paths = ["~/.config/nvim"]
exclude = ["*.log", "plugin/packer_compiled.lua"]
post_deploy = "nvim_sync"
# SSH config with secret filtering
[ssh-config]
paths = ["~/.ssh/config"]
secrets_filter = true
update_strategy = "rename_old"
# Hyprland with notification on deploy
[hyprland]
paths = ["~/.config/hypr"]
post_deploy = "hyprland_reload"
YAML (also supported)
bashrc:
paths:
- ~/.bashrc
post_deploy: shell_reload
nvim:
paths:
- ~/.config/nvim
exclude:
- "*.log"
post_deploy: nvim_sync
Hook Aliases
Instead of writing full shell commands, use built-in aliases:
| Alias | Runs |
|---|---|
shell_reload |
source ~/.bashrc || source ~/.zshrc |
nvim_sync |
nvim --headless +PackerSync +qa |
hyprland_reload |
hyprctl reload |
fish_reload |
source ~/.config/fish/config.fish |
tmux_reload |
tmux source-file ~/.tmux.conf |
kitty_reload |
killall -SIGUSR1 kitty |
Update Strategies
| Strategy | Behaviour |
|---|---|
replace |
Overwrite existing files (default) |
rename_old |
Back up existing file before overwriting |
ignore |
Skip if file already exists |
Templates & Inheritance
# Define reusable templates
[templates.linux-desktop]
post_deploy = "notify-send 'Config updated'"
update_strategy = "rename_old"
# Inherit in sections
[hyprland]
paths = ["~/.config/hypr"]
inherits = ["linux-desktop"]
[waybar]
paths = ["~/.config/waybar"]
inherits = ["linux-desktop"]
Environment Variable Expansion
[work-files]
paths = ["$WORK_DIR/config", "~/$USER/.config/app"]
Secret Detection
Before any file enters the repository, dot-man scans it for secrets. Detected values are encrypted locally and replaced with a hash placeholder in the repo.
| Pattern | Severity | Example |
|---|---|---|
| Private keys | 🔴 CRITICAL | -----BEGIN RSA PRIVATE KEY----- |
| AWS credentials | 🔴 CRITICAL | AKIA... |
| GitHub tokens | 🟠 HIGH | ghp_xxxx |
| API keys | 🟠 HIGH | api_key = "sk-..." |
| Passwords | 🟠 HIGH | password = "hunter2" |
| JWT tokens | 🟡 MEDIUM | eyJ... |
repo file: api_key = "***REDACTED:e3b0c44298...***"
vault: { encrypted: "gAAAAABk..." } ← Fernet AES-128
system file: api_key = "sk-abc123..." ← restored on deploy
Run dot-man audit to scan at any time. Use dot-man audit --strict in CI/CD pipelines.
Custom Secret Patterns
You can define custom regular expressions to match sensitive patterns, either globally in ~/.config/dot-man/global.toml or for a specific repository in dot-man.toml.
Global custom secrets (global.toml)
[security]
use_default_patterns = true # Set to false to disable built-in patterns
[[security.patterns]]
name = "My Custom API Token"
pattern = 'my_api_key_[a-zA-Z0-9]{32}'
severity = "HIGH"
description = "Internal service API key"
Repository custom secrets (dot-man.toml)
[secrets]
use_default_patterns = true # Set to false to disable built-in patterns
patterns = [
{ name = "Special Repo Key", pattern = 'special_[0-9]+', severity = "CRITICAL" }
]
Multi-Machine Profiles
Profiles let you auto-select the right branch based on hostname:
dot-man profile create work-laptop -h work-laptop -h thinkpad
dot-man profile set-branch work-laptop work
dot-man profile detect # auto-switches to the right profile
Template Variables
Use {{VARIABLE}} placeholders in your dotfiles that get substituted on deploy:
dot-man template set EMAIL john@work.com
dot-man template set HOSTNAME work-laptop
Then in your ~/.gitconfig:
[user]
email = {{EMAIL}}
name = John Doe
System variables ({{HOSTNAME}}, {{USER}}, {{SHELL}}, etc.) are auto-populated.
Project Status
| Metric | Value |
|---|---|
| Version | 1.6.0 |
| Python | 3.10 · 3.11 · 3.12 · 3.13 |
| Platforms | Linux, macOS |
| Test Coverage | 96% (2490 tests) |
| Commands | 30+ |
| PyPI | dotman-git |
Development
git clone https://github.com/BeshoyEhab/dot-man.git
cd dot-man
uv sync --extra dev
pre-commit install
# Run tests
uv run pytest tests/ -v
# Run full quality gate
uv run black dot_man/ tests/
uv run ruff check dot_man/ tests/
uv run mypy dot_man/ --ignore-missing-imports
uv run pytest tests/ --cov=dot_man --cov-report=term-missing
See CONTRIBUTING.md and DEVELOPMENT.md for full guides.
Roadmap
- 90%+ test coverage (every module)
- Full documentation site (mkdocs)
- Symlink mode
-
dot-man watch— auto-sync on file change - Deploy rollback (transaction-style)
- Plugin system
See docs/roadmap.md for the full roadmap.
Contributing
Pull requests are welcome. Please read CONTRIBUTING.md first.
All contributions must pass the pre-push quality checklist: black, ruff, mypy, and all tests.
License
MIT © Bishoy Ehab & ZVAXEROWS
Metadata
Release files for dotman-git 1.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| dotman_git-1.6.0.tar.gz | 399.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dotman_git-1.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 591.3 kB
Release files / dotman_git-1.6.0.tar.gz
| Download URL | dotman_git-1.6.0.tar.gz |
|---|---|
| Size | 399.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
08f41bc0f3fdf03c8014f33a15ccc2b1149b12360b0525d95c88250ce4721f69
|
|
BLAKE2b-256 checksum How to use checksums |
68667c27155f5206499e3188c92b645f57269341a74b488f7b5442f317d72b05
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logRelease files / dotman_git-1.6.0-py3-none-any.whl
| Download URL | dotman_git-1.6.0-py3-none-any.whl |
|---|---|
| Size | 192.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
082d1a531bc3ca42955488ec06248c07a90448f79ae55ea5f7e7051bc0901979
|
|
BLAKE2b-256 checksum How to use checksums |
3fa147a7a682354e86dda18a2946f8273299ed6b74b252465aeefacf3d9ad8bb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logSecurity for dotman-git 1.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for dotman_git-1.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.