Feature request: add option to replace remote symlinks with regular files ONLY when the local file has actual changes
📝 Description
Problem Statement
When synchronizing files with Mutagen, if the remote (beta) endpoint contains a symbolic link at a path where the local (alpha) endpoint has a regular file, Mutagen currently cannot synchronize that file.
Depending on the --symlink-mode setting:
| Mode |
Behavior with remote symlink |
portable (default) |
Synchronization halts if a non-portable symlink is detected |
ignore |
Symlink is ignored (file is not synced) |
posix-raw |
Propagates raw symlink (does not convert to file) |
None of these modes removes the remote symlink and replaces it with the regular file from the local endpoint.
Use Case
In CI/CD pipelines for creating review environments, a common optimization is to create a working directory using symlinks pointing to a base branch (e.g., main) to save disk space. For example:
cp -rns /path/to/main/* /path/to/review/branch/
This creates absolute symlinks in the review directory pointing back to main.
However, during development, the developer needs to edit files in this review environment. The desired behavior is:
- When a file is actually modified locally (content change) and synced via Mutagen
- If the remote path is currently a symlink, Mutagen should:
- Remove the symlink on the remote side
- Create a regular file on the remote side with the modified content from the local side
- If the local file has not been modified (no content change), the remote symlink should remain untouched
Why this matters
Replacing symlinks unconditionally would be destructive and inefficient:
- Unnecessary disk usage: Replacing every symlink with a regular file would defeat the space-saving purpose of using symlinks in the first place
- Unnecessary network transfers: Syncing files that haven't changed wastes bandwidth
- Unexpected behavior: Developers would lose the symlink structure for files they never intended to modify
The replacement should be strictly tied to local file modifications.
Proposed Solution
Add a new --symlink-mode option, for example:
--symlink-mode=replace-on-modify
Or a more specific flag:
--replace-remote-symlinks-on-modify
Behavior:
- Mutagen detects that the remote (beta) path is a symbolic link
- Mutagen checks if the local (alpha) file has actual content changes (not just metadata)
- If changed:
- Remove the symbolic link on the remote side
- Create a regular file on the remote side with the changed content
- If not changed:
- Leave the remote symlink untouched
- No network transfer occurs
In one-way-replica mode (local → remote), this would work as follows:
| Scenario |
Remote is symlink? |
Local has changes? |
Action |
| 1 |
Yes |
No |
⏭️ Nothing (preserve symlink) |
| 2 |
Yes |
Yes |
🔄 Remove symlink, create file |
| 3 |
No |
No |
⏭️ Nothing |
| 4 |
No |
Yes |
📝 Normal file sync |
Alternative Considered
A workaround exists: manually removing symlinks on the remote side before syncing:
ssh user@host "find /remote/path -type l -delete"
mutagen sync flush session-name
However, this requires:
- Manual intervention or additional scripting
- An extra SSH connection
- Cannot be done per-file based on whether the file actually changed
- Removes ALL symlinks, defeating the space-saving purpose
Additional Context
- Mutagen version: v0.18.1 - windows-amd64
- OS:
- Alpha: Windows 10
- Beta: Linux Debian
- Sync mode:
one-way-replica
Related documentation: https://mutagen.io/documentation/synchronization/symbolic-links/
🏷️ Labels Suggestion
enhancement
feature-request
symlinks
performance
📋 Example Scenario
Initial state on remote (symlinks pointing to main branch):
/review/branch/
├── index.php -> ../main/index.php (symlink)
├── config.php -> ../main/config.php (symlink)
├── style.css -> ../main/style.css (symlink)
└── .env -> ../main/.env (symlink)
Developer modifies only index.php locally:
index.php: CHANGED → should become a regular file on remote
config.php: unchanged → remains symlink
style.css: unchanged → remains symlink
.env: unchanged → remains symlink
Expected remote state after sync:
/review/branch/
├── index.php (regular file - REPLACED)
├── config.php -> ../main/config.php (symlink - preserved)
├── style.css -> ../main/style.css (symlink - preserved)
└── .env -> ../main/.env (symlink - preserved)
🔗 Related Discussion
This behavior is similar to how rsync handles symlinks with --copy-links and --safe-links, but with the crucial difference that replacement should be conditional on file modification.
Feature request: add option to replace remote symlinks with regular files ONLY when the local file has actual changes
📝 Description
Problem Statement
When synchronizing files with Mutagen, if the remote (beta) endpoint contains a symbolic link at a path where the local (alpha) endpoint has a regular file, Mutagen currently cannot synchronize that file.
Depending on the
--symlink-modesetting:portable(default)ignoreposix-rawNone of these modes removes the remote symlink and replaces it with the regular file from the local endpoint.
Use Case
In CI/CD pipelines for creating review environments, a common optimization is to create a working directory using symlinks pointing to a base branch (e.g.,
main) to save disk space. For example:cp -rns /path/to/main/* /path/to/review/branch/This creates absolute symlinks in the review directory pointing back to
main.However, during development, the developer needs to edit files in this review environment. The desired behavior is:
Why this matters
Replacing symlinks unconditionally would be destructive and inefficient:
The replacement should be strictly tied to local file modifications.
Proposed Solution
Add a new
--symlink-modeoption, for example:Or a more specific flag:
Behavior:
In
one-way-replicamode (local → remote), this would work as follows:Alternative Considered
A workaround exists: manually removing symlinks on the remote side before syncing:
ssh user@host "find /remote/path -type l -delete" mutagen sync flush session-nameHowever, this requires:
Additional Context
one-way-replicaRelated documentation: https://mutagen.io/documentation/synchronization/symbolic-links/
🏷️ Labels Suggestion
enhancementfeature-requestsymlinksperformance📋 Example Scenario
Initial state on remote (symlinks pointing to
mainbranch):Developer modifies only
index.phplocally:index.php: CHANGED → should become a regular file on remoteconfig.php: unchanged → remains symlinkstyle.css: unchanged → remains symlink.env: unchanged → remains symlinkExpected remote state after sync:
🔗 Related Discussion
This behavior is similar to how
rsynchandles symlinks with--copy-linksand--safe-links, but with the crucial difference that replacement should be conditional on file modification.