Settings

Two layers: settings that apply to the whole process, and configuration that applies to one repo. The process layer is read through Object::Configure, so a file, a universal section and environment variables can each contribute; the repo layer is plain JSON written by the tools.

On this page

Process settings

The settings file is ~/.conf/app-filesync.json when it exists, or the path in FILESYNC_SETTINGS. The section key is App__FileSync, and a UNIVERSAL section in the same directory applies to every class that uses Object::Configure. Environment variables named App__FileSync__KEY override the file.

# ~/.conf/app-filesync.json
{ "App__FileSync": {
    "log_level"       : "debug",
    "log_format"      : "%level%: %message%",
    "log_file"        : "/home/foo/.filesync/filesync.log",
    "ssh_identity"    : "~/.ssh/filesync_ed25519",
    "ssh_known_hosts" : "~/.ssh/filesync_known_hosts",
    "server_command"  : "/usr/local/bin/filesync-server"
} }

# or, for one run
export App__FileSync__log_level=debug
KeyDefaultMeaning
log_level warning One of trace, debug, info, notice, warning, error, critical, alert, emergency (and the usual short spellings). An unknown level is an error.
log_format %level%: %message% A Log::Abstraction format string.
log_file empty (standard error) Send diagnostics to this file instead. Leading directories are created.
ssh_identity empty (ssh's default) The default identity file for every SSH repo.
ssh_known_hosts empty (ssh's default) The default known-hosts file for every SSH repo.
server_command filesync-server The program the client runs over ssh, unless the repo names another.

Command output — sync summaries, plans, --json — is written to standard output by the commands themselves. The logger carries diagnostics on standard error, so a cron job can separate the two. --verbose raises the level to debug and --quiet lowers it to error for that run, overriding the file.

Precedence

Lowest to highest:

  1. the built-in default;
  2. the UNIVERSAL section;
  3. the App__FileSync section of the settings file or FILESYNC_SETTINGS;
  4. the environment variables (universal ones first, class ones last);
  5. --verbose or --quiet on the command line, which describe this run only.

For a repo, a value recorded by filesync init — --identity, --known-hosts, --server-command — wins over the process setting, so one machine can point at another identity without repeating the common settings. port and host_key_checking exist per repo only: there is no process-wide layer, and ssh's own default applies when the repo leaves them out.

Where a value came from

filesync settings prints every effective value together with the layer that supplied it, which is usually faster than reconstructing the merge by hand:

$ filesync settings
settings file: /home/foo/.conf/app-filesync.json

log_level        debug                 /home/foo/.conf/app-filesync.json [App__FileSync]
log_format       %level%: %message%    built-in default
log_file         /home/foo/f.log       App__FileSync__log_file
ssh_identity     ~/.ssh/id_ed25519     built-in default
ssh_known_hosts                        built-in default
server_command   /usr/local/bin/filesync-server  /home/foo/.conf/app-filesync.json [App__FileSync]

The source is reported as default, file, env, merged or repo in the JSON form. A value that no modelled layer accounts for is reported as merged rather than claimed as a default. filesync settings --config FILE reads another settings file, and --json returns the report as data.

Client configuration

The client keeps one JSON file listing its repos, ~/.filesync/config.json or the path in FILESYNC_CONFIG. filesync init writes it atomically; editing it by hand is fine, but keep the ids plain.

{
  "version"   : 1,
  "client_id" : "laptop",
  "ssh"       : { "command" : "ssh", "extra_args" : [] },
  "repos"     : {
    "documents" : {
      "root"          : "/home/foo/Documents",
      "transport"     : "ssh",
      "server"        : "foo@srv",
      "role"          : "client",
      "identity"      : "~/.ssh/filesync_ed25519",
      "known_hosts"   : "~/.ssh/filesync_known_hosts",
      "server_command": "/home/foo/bin/filesync-server-home",
      "snapshot_mode" : "hardlink"
    }
  }
}
KeyMeaning
client_idThis machine's id, the host name unless --id was given. It names this client's base, journal entries and conflict copies.
repos.NAME.rootThe local directory, which must contain the .filesync-root marker.
repos.NAME.transportssh or local.
repos.NAME.serverThe ssh host, as host or user@host.
repos.NAME.remote_repoThe repo name on the server, when it differs from this key.
repos.NAME.roleclient or replica; only a replica may take snapshots.
repos.NAME.identityssh identity file for this repo.
repos.NAME.known_hostsssh known-hosts file for this repo.
repos.NAME.portssh port; repo only, default 22.
repos.NAME.host_key_checkingyes or no; repo only, default yes.
repos.NAME.server_commandThe server program for this repo, such as the wrapper that adds --root.
repos.NAME.snapshot_modehardlink or copy.
repos.NAME.snapshot_keepHow many snapshots to keep; default 14.

A configuration written by a newer release is read as-is: unknown keys are kept and ignored, and there is no schema version check beyond version. A missing file is an empty configuration rather than an error.

Server repo policy

Each repo has a policy at ROOT/.filesync/repos/REPO/config.json, created by filesync-admin repo create and printed by repo show. It holds the retention and deletion limits, the ignore list, and the admitted clients.

{
  "version"            : 1,
  "name"               : "documents",
  "created"            : "2026-10-23 19:44:45 UTC",
  "trash_days"         : 30,
  "max_deletes"        : 200,
  "max_delete_percent" : 10,
  "conflicts"          : "inline",
  "preserve_mode"      : true,
  "allow_symlinks"     : false,
  "clients"            : { "laptop" : { "role" : "client" } },
  "ignore"             : [ ".filesync-root", ".filesync-tmp-*",
                           ".filesync-snapshots", "*.swp", "*~", ".#*",
                           "#*#", ".DS_Store", "._*", "Thumbs.db",
                           "desktop.ini", "*.crdownload", "*.part" ]
}
KeyDefaultMeaning
trash_days30How long the server keeps deleted files.
max_deletes200Most files one session may delete.
max_delete_percent10Largest fraction of known files one session may delete.
conflictsinlineKeep the losing version beside the winner.
preserve_modetrueCarry permission bits between POSIX systems.
allow_symlinksfalseWhether the tree may contain symlinks.
clientsemptyAdmitted client ids and their roles. An empty table admits every client.
ignorethe list abovePatterns excluded on both sides. --ignore replaces the list; a trailing / matches at any depth, and a leading / anchors to the root.

The reserved entries are not negotiable: the root marker, temporary files and snapshots must never enter a manifest, so they are excluded whatever the policy says.

Paths

PathWhereHolds
~/.conf/app-filesync.jsonclient and serverProcess settings, unless FILESYNC_SETTINGS names another file.
~/.filesync/config.jsonclientThe repo list, unless FILESYNC_CONFIG names another file.
~/.filesync/cache/REPO.jsonclientThe size-and-mtime cache and the last-run summary.
~/.filesync/logs/REPO.jsonlclientOne JSON object per run attempt.
~/.filesync/clientAlso the per-repo lock and the local trash. FILESYNC_HOME moves the whole directory.
ROOT/.filesync-rootclientThe marker that proves the sync root is the registered tree and is mounted.
ROOT/master/REPO/serverThe master tree.
ROOT/.filesync/repos/REPO/config.jsonserverThe repo policy and admitted clients.
ROOT/.filesync/repos/REPO/serverThe index, per-client bases, server trash and journal.
ROOT/.filesync-snapshots/replicaDaily snapshots, one directory per date.