📂 dotfilesmanager (dfm)
Language: Chinese/中文
dotfilesmanager (or dfm for short) is a minimal, lightweight, and cross-platform configuration file (dotfiles) manager.
Unlike traditional synchronization or copying tools, dfm uses a “move the original file + automatically create a symlink” workflow. It centrally archives your configuration files in ~/dotfiles under your home directory and creates symbolic links at their original locations. This lets you synchronize and back up configurations across machines while preserving their native real-time update behavior.
✨ Core Features
- 🚀 Immediate effect: Uses symlinks, so configuration changes take effect immediately without manual copying or synchronization.
- 💻 Native cross-platform support: Consistently supports Linux, macOS, Windows, and Android (Termux).
- 🧠 Smart path recommendations: When sharing configurations across platforms, automatically recommends the most suitable path according to the target system (for example,
~/.configon macOS and an AppData path on Windows). - 🔍 Clear view: Automatically generates a read-only directory of links organized by platform under
~/dotfiles/view/for easy overview. - 🩺 Health diagnostics: Includes a one-command check to quickly locate and fix broken symlinks, configuration conflicts, and other issues.
🆚 Positioning and comparison
- Central repository + live paths:
dfmmoves originals into a central~/dotfilesrepository and places symlinks at live configuration paths, so edits take effect immediately. Its path mappings explicitly cover Linux, macOS, Windows, Android, and Termux, with platform-specific destinations recorded indfm.yaml. - Compared with GNU Stow: Both can create symlinks, but GNU Stow primarily provides a simpler Unix package-to-home-directory symlink model.
dfmadditionally provides cross-platform path mappings andshareandviewworkflows. - Encryption scope:
dfmsupports structured selected field/value encryption as well as whole-file encryption. - Boundaries:
dfmis neither a template engine nor a secret manager. Git or another external transport remains responsible for synchronizing the repository. Symlink creation and permissions are platform-dependent.
💾 Installation
Install with pip in one step:
pip install dotfilesmanager
After installation, you can use the dfm command directly from the command line.
⌨️ Shell Autocompletion
Click's completion feature only generates completion scripts; it does not install or enable them automatically. Save the script to the appropriate location for your Shell, or output it and load it manually:
# Bash: common bash-completion directory (or source into the current Shell)
_DFM_COMPLETE=bash_source dfm > ~/.local/share/bash-completion/completions/dfm
# Zsh: completion function directory
_DFM_COMPLETE=zsh_source dfm > ~/.zfunc/_dfm
# Fish: completion script directory
_DFM_COMPLETE=fish_source dfm > ~/.config/fish/completions/dfm.fish
Before first use, create the directories above yourself and configure your Shell to load the scripts: for Bash, run source or reload bash-completion; for Zsh, add ~/.zfunc to fpath and run compinit; Fish loads from its completions directory. Autocompletion is not enabled automatically by these steps.
🏁 Quick Start
🛠️ Scenario 1: Add a local configuration to management
Enter a file or directory path to add it to ~/dotfiles:
dfm add ~/.bashrc
💡 Interactive wizard
In an interactive terminal (TTY),
dfmautomatically detects and asks whether you also want to share this configuration on other platforms (such as Windows / macOS / Android), and intelligently recommends a default path.If this configuration belongs only to the current system and does not need to be shared across platforms, use the
--systemoption:dfm add ~/.bashrc --system
🔐 Encrypt a new configuration with git-crypt
Install, prepare, and unlock git-crypt yourself before using --encrypt:
dfm add ~/.secret-config --encrypt
🔄 Scenario 2: Restore configurations on a new machine or system
After cloning your ~/dotfiles repository to a new machine, rebuild all symbolic links with one command:
dfm install
To install only a specific configuration:
dfm install <保存的配置名/路径>
🤝 Scenario 3: Share an existing configuration across systems or at a new path
To use a configuration already managed by dfm on the current system at a different path:
dfm share <已保存配置项的路径> <当前系统下的新安装目标路径>
🗑️ Scenario 4: Stop managing a configuration and restore the file
When you no longer want dfm to manage a configuration and want to restore it to its original state:
dfm rm <路径>
This safely removes the symbolic link and restores the original file or directory without data loss from ~/dotfiles to its initial installation path.
[!TIP] To completely remove this configuration's associations on all systems and delete its source file from
~/dotfiles, use:dfm rm <路径> --all
📑 Common Commands
| Command | Description |
|---|---|
dfm add <path> |
Manage a configuration file or directory by moving it into ~/dotfiles and creating a link at its original location. |
dfm rm <path> |
Stop managing a configuration, remove the symbolic link, and put the file back in its original location. |
dfm install [<path>] |
Rebuild symbolic links for all (or a specified) configuration files for the current system. |
dfm share <saved> <new> |
Share an existing configuration with the current system and install it at the specified new path. |
dfm view |
Generate a clearly categorized read-only link view under ~/dotfiles/view for easy management and inspection. |
dfm doctor |
Scan and diagnose the current system's configurations for broken links, conflicts, or unregistered files. |
dfm setup |
(Windows only) Check and enable Developer Mode so ordinary user permissions can create symbolic links. |
🔧 Platform Notes
🪟 Windows Users
- Creating symbolic links on Windows usually requires administrator privileges or Developer Mode.
- If you encounter a permissions error while running a command, execute
dfm setup. It will guide you through enabling Developer Mode via UAC, after which you can usedfmnormally with standard user permissions.
🤖 Android (Termux) Users
dfmfully supports the Termux environment on Android (the system identifier isandroid).- You can rebuild or share Unix-style configuration files on mobile devices.
📂 Storage and Configuration Management
- Physical storage: The originals of all managed files are stored in
~/dotfiles/files/. - Data manifest:
dfm.yamlis the only automatically generated configuration file and persists path mappings for each configuration across platforms. - Version control recommendation: We strongly recommend initializing the entire
~/dotfilesdirectory as a Git repository and pushing it to GitHub or another platform for backup.[!TIP] We recommend adding
/view/to your.gitignoreto avoid committing generated temporary view files to the Git repository.
🔐 Partial value encryption
This feature requires cryptography and a configured GPG default/self key. In the
repository, create dfm.yaml with filename globs mapped to key lists, then run
dfm init. This creates the base configuration, wrapped key, local
.git/line-crypt.key cache, reserved .git-filters/map.yaml, and Git filter
attributes. The reserved map starts as {version: 1, mappings: {}}, is always
full-encrypted, and is not declared in dfm.yaml; repeated dfm init runs
preserve the wrapped data key and map. Normal git add, commit,
and checkout store deterministic ENCv1: values while the worktree stays
plaintext. Use dfm lock and dfm unlock to remove or restore local key access;
both require a clean tracked worktree and leave untracked files ignored.
During an interactive dfm add, regular UTF-8 files use one generic checkbox to
select detected sensitive fields and/or configured map literals. The selected modes
are applied in one encryption operation; no selection changes nothing. Directories,
binary files, non-interactive adds, and legacy --encrypt are not prompted. Map
suggestions require the plaintext .git-filters/map.yaml from dfm unlock; an
unavailable or invalid map leaves the ordinary field option usable.
The add-time candidate list is stored in dfm.yaml and can be manually edited;
users must add or remove entries themselves:
encryption:
sensitive_keys: [password, secret, token, key, email, username, user, uuid]
The scanner is deliberately format-agnostic: rules remain filename globs mapped to
keys lists. Optional patterns lists may use regular expressions; only capture
group 1 is encrypted during clean, while the rest of each match is preserved.
Patterns only need to describe plaintext; for a configured file, smudge scans and
decrypts every ENCv1: envelope directly:
Add a file-specific rule with repeated keys using:
dfm encrypt path/to/settings.conf --key password --key email
Without --key, dfm encrypt prompts for a comma-separated key list. It updates
the rule, filter attributes, and only renormalizes the selected path. The visible
command is not a command group; Git invokes the hidden internal command
dfm encrypt-filter clean|smudge %f.
Configured keys absent from a file are ignored by the filter. When adding keys
with dfm encrypt, each newly supplied key must occur in the target file; otherwise
the command fails before changing configuration or Git attributes.
For whole-file or binary content, use dfm encrypt path/to/file --full. This does
not prompt for keys and cannot be combined with --key; it creates or updates the
target rule as full: true and only renormalizes that path.
To stop encrypting one file, run dfm unencrypt path/to/file. It removes only
that file's exact rule and filter attribute, then renormalizes the path. Make
sure the repository is unlocked first. The file will be plaintext in the index
afterward, so future commits can expose its contents; review the staged diff
before committing.
encryption:
rules:
"*.ini":
patterns: ["(?m)^token\\s*=\\s*([^\\r\\n]*)$"]
For whole-file or binary content, use full: true; the complete input becomes
one ENCv1: envelope, and smudge leaves non-envelope input unchanged. A matching
full rule takes precedence over keys and patterns.
To enable reversible literal mapping for a file, use --map:
dfm encrypt path/to/settings.conf --map
dfm encrypt path/to/settings.conf --key password --map
--map does not prompt for keys and may be combined with --key, but not with
--full. Clean encrypts configured keys/patterns first, then replaces matching
map literals with frames such as {{dfm:ENDPOINT}} (longest literal first, once).
Plaintext containing any {{dfm: frame-like syntax is rejected as reserved; frames are generated only by clean. Smudge reverses generated frames before decrypting envelopes. The reserved
.git-filters/map.yaml is never map-transformed.
Map operations require its plaintext worktree copy; if it is missing or still an
ENCv1: envelope, run dfm unlock.
Key scanning remains format-agnostic and finds exact
bare or single-/double-quoted keys followed by :, =, or whitespace, with
optional whitespace around punctuation. Values may be bare or single-/double-
quoted. Clean and smudge preserve the original syntax and only replace value
interiors. Bare values extend through the logical line until a generic structural
boundary; trailing whitespace and comments remain outside the encrypted value.
This intentionally does not support multiline or block values; use simple
key/value fields when migrating fields from any configuration format.
dfm lock and dfm unlock manage the local cache without rewriting the index.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dotfilesmanager-1.17.1.tar.gz.
File metadata
- Download URL: dotfilesmanager-1.17.1.tar.gz
- Upload date:
- Size: 84.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6dd13887facfbbaa08d9182ffd081b207f643bf0f35759c1b6dd078dec719ed1
|
|
| MD5 |
8e39facaec7e9f4886c006c87dd1e185
|
|
| BLAKE2b-256 |
96082a71fac0b9b18fa79481aa0b16bad8f51f32e215df42b2e357b94899be93
|
Provenance
The following attestation bundles were made for dotfilesmanager-1.17.1.tar.gz:
Publisher:
publish.yml on xyz1001/dotfilesmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotfilesmanager-1.17.1.tar.gz -
Subject digest:
6dd13887facfbbaa08d9182ffd081b207f643bf0f35759c1b6dd078dec719ed1 - Sigstore transparency entry: 2320560408
- Sigstore integration time:
-
Permalink:
xyz1001/dotfilesmanager@3e60126fd677cf548bb6ba0d1c7214ff5753e11a -
Branch / Tag:
refs/tags/v1.17.1 - Owner: https://github.com/xyz1001
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e60126fd677cf548bb6ba0d1c7214ff5753e11a -
Trigger Event:
push
-
Statement type:
File details
Details for the file dotfilesmanager-1.17.1-py3-none-any.whl.
File metadata
- Download URL: dotfilesmanager-1.17.1-py3-none-any.whl
- Upload date:
- Size: 43.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1bc81ac891acde4b784cf3f9cd09f8fb6c1181a73aa9447c0cbadb02b0f0bc7a
|
|
| MD5 |
bdf1b9aa742ed465a04596a8714cc90c
|
|
| BLAKE2b-256 |
96471a1a3a302faf7d3e5fcf9ca82db9ecd59356ce3b75bf01ef23568fb69579
|
Provenance
The following attestation bundles were made for dotfilesmanager-1.17.1-py3-none-any.whl:
Publisher:
publish.yml on xyz1001/dotfilesmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dotfilesmanager-1.17.1-py3-none-any.whl -
Subject digest:
1bc81ac891acde4b784cf3f9cd09f8fb6c1181a73aa9447c0cbadb02b0f0bc7a - Sigstore transparency entry: 2320560496
- Sigstore integration time:
-
Permalink:
xyz1001/dotfilesmanager@3e60126fd677cf548bb6ba0d1c7214ff5753e11a -
Branch / Tag:
refs/tags/v1.17.1 - Owner: https://github.com/xyz1001
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3e60126fd677cf548bb6ba0d1c7214ff5753e11a -
Trigger Event:
push
-
Statement type: