Commands
dotsync <command> [flags] [arguments]- Flags can come before, between or after arguments.
-flagand--flagare the same, and a value can follow a space or an=:--interval 600or--interval=600.--ends flag parsing. dotsync help <command>, or-hafter any command, prints its usage and flags.- Every command that changes something (
add,remove,set,describe,exclude,includeandresolve) runs a sync straight away, so you see the result immediately. - A command that needs the lock waits up to a minute for a running sync to finish.
Setup
Managing files (changes apply to every machine)
This machine only
Everyday
dotsync init [options] <git-url>Sets up this machine. It clones the repository into ~/.local/share/dotsync/repo and, if the repository is empty, creates the manifest there and pushes it. Then it writes the machine configuration, copies the running binary to ~/.local/bin/dotsync (unless Homebrew or apt installed it), runs the first sync, and installs the background agent.
init is safe to run again, for example to re-install the agent or to change the branch or interval. Flags you don’t pass keep their saved values. A machine can only sync with one repository; to switch, change the remote first.
| Flag | Description |
|---|---|
--branch branch | The branch to sync (default main) |
--interval seconds | Seconds between automatic syncs (default 300) |
--keep-existing | Report existing differing local files as conflicts instead of replacing them (after a backup) |
--no-agent | Do not install the background agent |
--no-install | Do not copy dotsync to ~/.local/bin |
With --keep-existing, existing local files that differ from the shared version become conflicts instead of being backed up and replaced. It’s saved as on_existing, so it also applies to entries added later. See Add another machine.
doctor
Section titled “doctor”dotsync doctorChecks everything dotsync depends on, in order, and says how to fix what’s wrong:
- this version, and whether a newer release exists
- that
gitis installed, and version 2.20 or newer - the configuration, and that the cache clone exists and points at the configured remote
- that the remote is reachable without prompts, exactly as the background agent will reach it, and has the configured branch
- that the agent is installed and loaded, that the binary it runs exists, and that its definition is current
- that
dotsyncis on yourPATH - when the last sync ran, and whether it reached the remote
- conflicts, blocked files, errors and queued changes, judged against the last fetched state
- how many backups there are, and how much space they use
dotsync doctor
dotsync doctor
✓ dotsync 0.5.0 (ed63c37, 2026-09-21T06:18:53Z) go1.27.1 darwin/arm64
· update available: 0.5.0 → 0.6.0
→ dotsync update
✓ git version 2.50.1 (Apple Git-155)
✓ configuration: ~/.config/dotsync/config.json
remote git@github.com:you/dotfiles.git, branch main
✓ remote reachable without prompts
✓ background agent: launchd agent loaded
✓ last sync 3m0s ago (ok)
✓ 12 managed entries, 148 files
! 1 conflict(s)
→ dotsync status; then dotsync resolve <path> --keep local|remote
· backups: 6 file(s), 41.2 KiB in ~/.local/state/dotsync/backups (older than 90 days are pruned)
Working, with warnings.Each line starts with ✓ (fine), · (information), ! (a warning) or ✗ (a failure), and problems come with a → line saying what to do. doctor exits with status 1 if any check failed; warnings don’t change the exit status. It never changes your files, the repository or the agent.
update
Section titled “update”dotsync update [--check] [--version vX.Y.Z] [--require-attestation]Replaces this binary with the latest release, after the same checks as the install script: the SHA-256 checksum always, and the signed build provenance when the GitHub CLI is installed. If the background agent runs a different copy (~/.local/bin/dotsync), that copy is replaced too, and the agent is then re-installed so its next run uses the new version with matching settings.
| Flag | Description |
|---|---|
--check | Only report whether an update is available |
--require-attestation | Fail unless the build provenance can be verified with the GitHub CLI |
--version vX.Y.Z | Install release vX.Y.Z instead of the latest (also allows downgrades) |
dotsync update
downloading dotsync 0.6.0 (darwin/arm64)
checksum verified
build provenance verified (built by pungoyal/dotsync's release workflow)
installed ~/.local/bin/dotsync
dotsync 0.5.0 → 0.6.0
background agent refreshed: launchd agent io.github.dotsync, every 300sIf Homebrew or apt installed dotsync, update changes nothing and prints the package manager’s command instead (brew upgrade dotsync, or sudo apt install --only-upgrade dotsync); --check works as usual.
Binaries are replaced atomically, and nothing is replaced if a check fails. A development build, one without a release version, is only replaced when you pass --version. update looks up the latest release through the GitHub API; set GITHUB_TOKEN if you hit its rate limit.
dotsync add [options] <path>...Starts managing files or directories, on every machine. Paths must be inside your home directory. A file that looks like a secret is refused; for a directory, add tells you how many files will be held back instead. See Manage files and directories for how sources are chosen and what can’t be added.
| Flag | Description |
|---|---|
--allow-secrets | Allow content that looks like credentials |
-d text, --description text | Describe the entry with text (default: the file name) |
--ignore glob | For directories: a glob of names or paths not to sync (repeatable) |
--no-sync | Only queue the change; the next sync pushes it |
--os OS | Only manage the entry on this OS: darwin or linux (repeatable) |
--source path | Path of the content under the repository's files/ (default: derived from the path) |
-d and --source can only be used with a single path.
remove
Section titled “remove”dotsync remove [-no-sync] <path|source>...alias rmStops managing entries on every machine. The local copies stay where they are, everywhere, as ordinary files. The content stays in the repository’s history. Name an entry by its path on this machine or by its source.
| Flag | Description |
|---|---|
--no-sync | Only queue the change |
dotsync set <path|source> [changes]Changes one entry in the shared manifest, for every machine. Name the entry by its path on this machine or by its source.
| Flag | Description |
|---|---|
--allow-secrets | Allow content that looks like credentials (use --allow-secrets=false to undo) |
--any-os | Manage on every OS (removes the os restriction) |
--clear-ignore | Remove every ignore pattern |
-d text, --description text | Describe the entry with text |
--ignore glob | Add an ignore glob (repeatable) |
--mode mode | Force these octal permissions (mode, e.g. 0600) on every machine |
--no-mode | Stop forcing permissions |
--no-sync | Only queue the change |
--os OS | Only manage the entry on this OS: darwin or linux (repeatable; replaces the current list) |
--unignore glob | Remove an ignore glob (repeatable) |
--write atomic|inplace | How local files are replaced (atomic|inplace) |
--osreplaces the whole list;--any-osremoves it. They can’t be combined, and neither can--modewith--no-mode, or--clear-ignorewith--unignore.- Ignore changes are recorded as additions and removals, so changes made on two machines at once combine.
- The result is checked before anything is queued, so an invalid mode, OS or write strategy is refused straight away.
- Boolean flags take
=falseto turn something off:--allow-secrets=falseturns the secret rules back on. - To change an entry’s source or target,
removeit andaddit again.
describe
Section titled “describe”dotsync describe <path|source> <description>A shortcut for dotsync set <path|source> --description <description>.
exclude
Section titled “exclude”dotsync exclude [--no-sync] <path|source>...Stops managing entries on this machine only. The entries stay in the shared manifest, and the local files are left exactly as they are. With no arguments, lists what’s excluded here. Exclusions are saved as exclude in the machine configuration.
| Flag | Description |
|---|---|
--no-sync | Don't sync afterwards |
include
Section titled “include”dotsync include [--no-sync] <path|source>...Manages an excluded entry on this machine again. On its first sync, a local file that differs from the shared version is handled as on a new machine: backed up and replaced, or reported as a conflict if the machine uses --keep-existing.
| Flag | Description |
|---|---|
--no-sync | Don't sync afterwards |
status
Section titled “status”dotsync status [-fetch] [-v] [-json]alias stShows every entry and its state on this machine, with the last sync’s result, the agent’s state, changes queued but not yet pushed, and conflicts. Directory entries also list the files that need attention. Output and exit codes explains every state.
| Flag | Description |
|---|---|
--fetch | Fetch from the remote first |
--json | Machine-readable output |
-v | List every file |
Without --fetch, status compares against the last fetched state, which is at most one sync interval old and works offline. It always exits with status 0 once it has run.
dotsync list [-json]alias lsPrints the shared manifest, sorted by source, including entries this machine skips. Entries limited to some operating systems show them in brackets.
dotsync list
gitconfig -> ~/.gitconfig
Git identity and aliases
karabiner/karabiner.json -> ~/.config/karabiner/karabiner.json [[darwin]]
Keyboard remapping
nvim -> ~/.config/nvim
Neovim| Flag | Description |
|---|---|
--json | Machine-readable output |
dotsync sync [-q]Runs one synchronization now, rather than waiting for the agent. How sync works describes what it does, and Output and exit codes its output.
| Flag | Description |
|---|---|
-q, --quiet | No output; exit silently if a sync is already running (used by the agent) |
The background agent runs dotsync sync -q. Besides silencing output, -q makes sync exit straight away, with status 0, if another sync is running, and lets it post desktop notifications for new conflicts and git problems.
dotsync diff [-fetch] [path...]Shows a unified diff from the repository’s version (-) to this machine’s (+) for every managed file that differs, or only for the given paths. A directory path covers everything below it. Binary files are reported as differing, without a diff.
| Flag | Description |
|---|---|
--fetch | Fetch from the remote first |
resolve
Section titled “resolve”dotsync resolve <path>... --keep local|remoteSettles conflicts. It fetches first, then syncs straight away. --keep local sends this machine’s version; --keep remote backs up the local file and installs the repository’s. A directory path resolves every conflict below it. It fails if there’s no conflict at the paths you give.
| Flag | Description |
|---|---|
--keep local|remote | Which version wins (local|remote): this machine's, or the repository's |
dotsync log [-n N]Shows recent commits to the shared repository as of the last fetch: short hash, date and time, and message. Every message starts with the name of the machine that made it.
| Flag | Description |
|---|---|
-n N | Show the last N commits |
dotsync agent install|uninstall|statusManages the background agent.
| Action | What it does |
|---|---|
install |
writes the launchd agent, systemd units or crontab line and loads it, replacing any previous definition. Run it after changing interval, moving git, or changing XDG_* variables |
uninstall |
unloads and removes it |
status |
says whether it’s installed and loaded |
version
Section titled “version”dotsync versiondotsync --versionPrints the version, the commit it was built from and that commit’s date, the Go version, and the platform.
dotsync helpdotsync help <command>Lists every command, or shows one command’s usage and flags. dotsync, dotsync -h and dotsync --help also list every command.