No description
  • Go 97.4%
  • Makefile 2.6%
Find a file
2026-02-11 12:41:07 +01:00
cmd fix: fix build by correcting package name 2026-02-10 22:30:26 +01:00
internal/models docs: clean up comments across codebase 2026-02-10 22:24:21 +01:00
man docs: add man page and update project files 2026-02-10 22:24:07 +01:00
pkg docs: clean up comments across codebase 2026-02-10 22:24:21 +01:00
.gitignore chore: add Makefile and ignore built binary 2026-02-09 17:31:10 +01:00
go.mod chore: bootstrap Go module and dependencies 2026-02-09 17:31:07 +01:00
go.sum chore: bootstrap Go module and dependencies 2026-02-09 17:31:07 +01:00
Makefile fix: fix build by correcting package name 2026-02-10 22:30:26 +01:00
README.md docs: add shell completions and update TUI docs 2026-02-10 22:24:17 +01:00
readme.md init commit 2025-10-07 12:46:56 +02:00
stowbun chore: update stowbun binary 2026-02-10 22:24:27 +01:00

Dotman

A modern dotfile management tool in Go that replaces GNU Stow. Features an interactive Bubble Tea TUI and Git integration.

Features

  • Stow Replacement: Creates and manages symlinks without GNU Stow
  • Interactive TUI: Bubble Tea-based user interface for management
  • Git Integration: Uses the system Git installation
  • Package Management: Organize dotfiles into logical packages
  • Flexible Symlinks: Choose target and source directories freely
  • Shell Completions: Auto-completion support for Bash, Zsh, Fish, and PowerShell
  • Simple CLI: Intuitive commands for all operations

Installation

Requirements

  • Go 1.21 or higher
  • Git (system installation)

Build from Source

git clone https://quelloffen.ch/zenn/dotman
cd dotman
make build
sudo make install

Or manually:

git clone https://quelloffen.ch/zenn/dotman
cd dotman
go build -o dotman ./cmd/dotman
sudo mv dotman /usr/local/bin/

Or Install Directly

go install quelloffen.ch/zenn/dotman/cmd/dotman@latest

Install Manpages

make install-man

Install Shell Completions

Dotman supports shell completions for Bash, Zsh, Fish, and PowerShell using the built-in completion command.

Bash

Add to ~/.bashrc:

eval "$(dotman completion bash)"

Or install system-wide:

sudo dotman completion bash > /etc/bash_completion.d/dotman

Zsh

Add to ~/.zshrc:

eval "$(dotman completion zsh)"

Or install system-wide:

dotman completion zsh > "${fpath[1]}/_dotman"

Fish

dotman completion fish > ~/.config/fish/completions/dotman.fish

PowerShell

Add to your PowerShell profile:

dotman completion powershell | Out-String | Invoke-Expression

Makefile Commands

When building from source, you can use the following make commands:

make build        # Compile the application
make install      # Install to /usr/local/bin (requires sudo)
make install-user # Install to ~/.local/bin (no sudo required)
make install-man  # Install manpages to /usr/local/share/man
make run          # Run without building
make clean        # Remove build artifacts
make test         # Run tests
make fmt          # Format code
make help         # Show all available commands

Quick Start

# Initialize a new dotfiles repository
dotman init

# Or clone an existing one
dotman init git@github.com:username/dotfiles.git

# Add configuration files
dotman add ~/.config/nvim
dotman add ~/.bashrc home

# Start the interactive TUI
dotman tui

# Or use CLI commands
dotman apply          # Activate all packages
dotman sync           # Commit and push changes

Directory Structure

Dotman stores dotfiles in ~/.dotfiles/ (configurable):

~/.dotfiles/
├── .config/
│   ├── nvim/
│   │   └── init.lua
│   └── kitty/
│       └── kitty.conf
├── bash/
│   ├── .bashrc
│   └── .bash_profile
└── .git/

Each folder is a "package" and contains the files to be linked.

Commands

init [repository-url]

Initializes a new repository or clones an existing one.

dotman init
dotman init git@github.com:user/dotfiles.git

add <path> [package]

Adds a file or directory to the dotfiles.

dotman add ~/.config/nvim
dotman add ~/.bashrc home
dotman add ~/.zshrc zsh

remove <path>

Removes a file from dotfiles and restores it.

dotman remove ~/.config/nvim

list [package]

Lists all managed files.

dotman list
dotman list .config

apply [package]

Activates (creates symlinks for) all or a specific package.

dotman apply
dotman apply .config

unapply [package]

Deactivates (removes symlinks) all or a specific package.

dotman unapply
dotman unapply .config

sync [message]

Commits and pushes all changes.

dotman sync
dotman sync "Updated nvim config"

tui

Starts the interactive user interface.

dotman tui

Keyboard shortcuts in the TUI:

  • j/k or /: Navigate up/down
  • h/l: Switch between panes
  • Space/Enter: Toggle package/directory expansion
  • o: Expand all directories
  • q: Quit

status

Shows the current status.

dotman status

completion [shell]

Generates shell completion scripts. Supported shells: bash, zsh, fish, powershell.

dotman completion bash
dotman completion zsh
dotman completion fish
dotman completion powershell

Configuration

The configuration is stored in ~/.dotman.json:

{
  "dotfiles_dir": "/home/username/.dotfiles",
  "target_dir": "/home/username",
  "packages": [],
  "updated_at": "2024-01-15T10:30:00Z"
}

How It Works

Adding a File

  1. File is moved to the dotfiles directory
  2. Original file is replaced by a symlink
  3. Change is added to Git
Before:
~/.config/nvim/init.lua

After dotman add ~/.config/nvim:
~/.dotfiles/.config/nvim/init.lua    (actual file)
~/.config/nvim/ → ~/.dotfiles/.config/nvim    (symlink)

Package Structure

Packages are simply folders in the dotfiles directory:

~/.dotfiles/.config/nvim/
~/.dotfiles/.config/kitty/
~/.dotfiles/bash/

When you run dotman apply, symlinks are created:

~/.config/nvim → ~/.dotfiles/.config/nvim
~/.config/kitty → ~/.dotfiles/.config/kitty
~/.bashrc → ~/.dotfiles/bash/.bashrc

Git Workflow

Dotman uses your system Git:

# Edit your dotfiles normally (they are linked)
vim ~/.config/nvim/init.lua

# Check changes
cd ~/.dotfiles && git status

# Sync with dotman
dotman sync "Updated nvim config"

# Or manually
git add .
git commit -m "Updated nvim config"
git push

Tips & Tricks

Different Packages for Different Machines

Create package-specific configurations:

# Laptop-specific
dotman add ~/.config/i3 laptop

# Server-specific
dotman add ~/.ssh/config server

Then activate only the needed packages:

dotman apply laptop
dotman apply .config

Ignoring Files

Create a .gitignore in ~/.dotfiles/:

*.log
.DS_Store
secrets/

Backup Before Changes

Before major changes:

dotman sync "Backup before reorganization"

Troubleshooting

"target already exists"

A file already exists at the target location:

# Backup and then apply
mv ~/.config/nvim ~/.config/nvim.backup
dotman apply .config

Check if the file was really moved:

ls -la ~/.dotfiles/
ls -la ~/.config/

Git Errors

Make sure Git is configured:

git config --global user.name "Your Name"
git config --global user.email "your@email.com"

Comparison with Stow

Feature GNU Stow Dotman
Symlink Management Yes Yes
Interactive TUI No Yes
Integrated Git No Yes
Shell Completions No Yes
Simple CLI Partial Yes
Package Structure Yes Yes
Selectable Target Directory Partial Yes

License

MIT License - See LICENSE file

Contributing

Contributions are welcome! Open an issue or pull request at quelloffen.ch/zenn/dotman.


Made with love in Go