Field notes

dot

dot is a type-safe dotfiles manager written in Go. It symlinks packages from a dotfiles repository into your home directory, with conflict detection, incremental relinking, profiles and git sync.

Set up

Install and shell setup9

Install with Homebrew on macOS or Linux
Install from the flake into a Nix profile
Run without installing
Build and install from source
Print the installed version
Install fish completions
Install zsh completions
Install bash completions
Show help for one command

Clone a new machine9

Clone into ./dotfiles and install packages
Clone over SSH
Clone a specific branch
Install a named profile from .dotbootstrap.yaml
Pick packages interactively, skipping machine mapping
Clone into a chosen package directory
Overwrite an existing package directory
Preview what would be installed
Token auth, tried before GIT_TOKEN, SSH keys, and gh

Bootstrap and profiles12

Generate .dotbootstrap.yaml from the package directory
Print the generated file to stdout
Only include packages recorded in the manifest
Set the default policy, also fail, overwrite, skip
Write elsewhere and overwrite an existing file
Required schema version at the top of the file
Declare a package and mark it mandatory
Limit a package to linux, darwin, windows, or freebsd
Named package set for a scenario
Profile inherits the packages of its single parent
Map hostname globs to profiles, first match wins
Fallback profile when no machine entry matches

Upgrades5

Check for and install a newer dot
Only report whether an update exists
Upgrade without a confirmation prompt
Turn off the startup update check
Pin the upgrade method, default auto

Everyday

Manage packages8

Install a package by creating symlinks
Install several packages at once
Preview the plan without touching files
Use an explicit package directory
Link into a target other than $HOME
Show info level detail while linking
Relink incrementally and restore missing symlinks
Preview what remanage would change

Adopt existing files11

Discover and select dotfiles interactively
Move one file into auto-named package vimrc and link it
Adopt a directory into package ssh
Adopt several files into a named package
Name the package explicitly when using a shell glob
Paths starting ./ or ../ resolve from the current directory
Bare paths resolve from the target directory
Scan extra directories in interactive mode
Skip directories during interactive discovery
Cap file size in interactive mode, default 10M
Preview an adoption

Unmanage7

Remove links, restoring adopted files to their origin
Remove links, leave adopted files in the package
Remove links and delete the package directory
Drop an orphaned manifest entry, no filesystem changes
Remove every managed package after confirmation
Remove every package without a prompt
Preview removing everything

Sync across machines5

Pull with rebase and autostash, then remanage every package
Also commit and push local edits made through symlinks
Preview without touching git
Sync a repository outside the current directory
Pull and relink, then confirm health

Status and list8

Show links and files for every package
Show status for specific packages
Machine readable status, also yaml or table
List installed packages with health and link counts
Sort by link count or date, default name
Include the target directory in output
List with health status as JSON
Disable color for status, list, or doctor

Workflows

Recipes7

Always preview, then apply
Bring an existing config under management safely
Publish edits made through symlinks on this machine
Quick health pass before or after a sync
Run from scripts with no prompts
Feed package state into other tools
Debug why a link is missing or unexpected

Configure

Ignore patterns10

Add a glob ignore pattern, repeatable
Negate to re-include, last matching pattern wins
Disable built-in ignores like .git and .DS_Store
Skip per-package .dotignore files
Per-package rules, only read at the package root
In .dotignore, re-include a default ignore such as .gnupg
Exclude a directory by bare name, never with a slash
Basename patterns match at any depth
Add these, the default .ssh/ key rules never match
Size limit in bytes, 0 means none

Configuration14

Create ~/.config/dot/config.yaml with defaults
Show which config file is in use
Show the final merged configuration
Read one key in section.field form
Set a key with type coercion
Raise the log level
Migrate to the latest format with a timestamped backup
Repository config, replaces the user config entirely
Quote a bare tilde, unquoted ~ is YAML null
Move conflicting files to the backup directory
Replace conflicting files, wins over backup
Point at another config file, including JSON or TOML
Set the package directory from the environment
Any key works as DOT_ plus SECTION_KEY uppercased

Reference

Global flags13

Show what would be done without applying changes
Info, debug, or trace verbosity
Suppress all non-error output
Non-interactive scripting mode, implies --quiet
Source directory containing packages
Target directory for symlinks, default $HOME
Where conflict backups go, default TARGET/.dot-backup
Skip files larger than this, 0 means no limit
Emit logs as JSON
Disable color output
Write a CPU profile for diagnostics
Write a memory profile for diagnostics
Serve pprof over HTTP on an address

Package layout9

A dot- prefix becomes a leading dot, so this links as .vimrc
Full-tree layout, package contents mirror the target like Stow
Full-tree example, links to ~/.config/APP/config
Same link using a dot- name instead of a real dotfile
Name-mapped layout, the default, package name is the target dir
Name-mapped example, links to ~/.ssh/config
Toggle dot- prefix translation
Prefix that marks a translated name
Split per-OS packages and gate each by platform in bootstrap

Troubleshoot

Doctor14

Health check with the default scoped orphan scan
Skip orphan detection for the fastest check
Scan the whole target for orphaned links
Limit deep scan recursion, default 10
Deep diagnostic mode, default fast
Expand each issue with type, path, and suggestion
Interactively categorize orphaned symlinks
Auto ignore high confidence categories in triage
JSON report for scripts
Exit 0 healthy, 1 warnings, 2 errors
Ignore one foreign symlink in future runs
Ignore target-relative paths by glob
Show the doctor ignore list
Remove an entry, or pass --pattern GLOB