Skip to main content

Dotfile manager with git-powered branching

Project description

dot-man

Dotfile manager with git-powered branching

CI PyPI version PyPI downloads Python License: MIT Code style: black Ruff Checked with mypy Coverage Docs PRs Welcome


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

  • 🌿 Git-powered branch profiles
  • 🔐 Automatic secret detection & vault
  • 🔄 Save → switch → deploy in one command
  • ⚡ Pre/post deploy hooks with aliases
  • 🏷️ Tag snapshots for fast rollback

Advanced

  • 🔒 GPG / AGE file encryption
  • 🌍 Import from chezmoi, yadm, stow
  • 📤 Export to tar, zip, JSON
  • 🔍 Auto-discover 30+ dotfile locations
  • 🌐 YAML + TOML config support

Developer

  • 🐚 Shell completions (bash/zsh/fish)
  • 🎨 Syntax-highlighted rich diffs
  • 🩺 doctor and verify diagnostics
  • 📦 PyPI — pip install dotman-git
  • 🔁 Remote sync via dot-man sync

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
# btw it was "switch" instead of "navigate" untill Bishoy decided to change it to "navigate" for some silly reasons and push that changes so as community help us to make it "switch" again.

# 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

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 show <commit> Full diff for a commit
dot-man tag create v1.0 Create a tag
dot-man tag list List all tags
dot-man tag switch v1.0 Checkout a tag
dot-man rollback Roll back to previous commit
dot-man rollback -n 3 Roll back 3 commits
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

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 backup restore <id> Restore from backup

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.2.3
Python 3.10 · 3.11 · 3.12 · 3.13
Platforms Linux, macOS
Test Coverage 81% (1526 tests)
Commands 30+
PyPI dotman-git

Development

git clone https://github.com/BeshoyEhab/dot-man.git
cd dot-man
pip install -e ".[dev]"

# Run tests
pytest tests/ -v

# Run full quality gate
black dot_man/ tests/
ruff check dot_man/ tests/
mypy dot_man/ --ignore-missing-imports
pytest tests/ --cov=dot_man --cov-report=term-missing

See CONTRIBUTING.md and DEVELOPMENT.md for full guides.


Roadmap

  • 80%+ test coverage
  • 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

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

dotman_git-1.3.1.tar.gz (266.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dotman_git-1.3.1-py3-none-any.whl (170.0 kB view details)

Uploaded Python 3

File details

Details for the file dotman_git-1.3.1.tar.gz.

File metadata

  • Download URL: dotman_git-1.3.1.tar.gz
  • Upload date:
  • Size: 266.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dotman_git-1.3.1.tar.gz
Algorithm Hash digest
SHA256 781c7528defa74c3156ddcda8d74f253bcf23a391d11f06810beb5511dcea104
MD5 c445dc497b5acfac8b0e4610d0bd8867
BLAKE2b-256 c6d2f9546999d3a462a8800d88136dfe1a8efca2ae1c0841ffc90c464918f97c

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotman_git-1.3.1.tar.gz:

Publisher: publish.yml on BeshoyEhab/dot-man

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dotman_git-1.3.1-py3-none-any.whl.

File metadata

  • Download URL: dotman_git-1.3.1-py3-none-any.whl
  • Upload date:
  • Size: 170.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dotman_git-1.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 561697d4ac8b102b2e97f0e9f8720712d51cb5499231b3db1e496aa93d5c0116
MD5 a2d4f256ef7569932926151187c994a6
BLAKE2b-256 76d3ff4be0623fc666b0d715b522e19a2e6fc56c4ee8bcdbaa805e09b26cd6c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for dotman_git-1.3.1-py3-none-any.whl:

Publisher: publish.yml on BeshoyEhab/dot-man

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page