bisync: expose deltaList/recover and require checkAccess

Wire forked rclone --delta-list: UI switches, RC outer params, and
auto-set checkAccess when deltaList is on so scheduled jobs cannot
omit the safety flag.
This commit is contained in:
2026-09-09 23:56:37 +02:00
parent caa086bdb4
commit 7286008949
2 changed files with 46 additions and 5 deletions
+8 -2
View File
@@ -492,6 +492,12 @@ export function buildBisyncRequests(args: BisyncArgs): RcRequest[] {
const { fullDirPath: srcFullDirPath, remoteName: srcRemoteName } = getFsInfo(source)
const { fullDirPath: dstFullDirPath, remoteName: dstRemoteName } = getFsInfo(destination)
const outer = { ...(options.outer || {}) }
// Forked rclone: --delta-list refuses to run without --check-access unless --force.
if (outer.deltaList && !outer.force) {
outer.checkAccess = true
}
return [
{
endpoint: '/sync/bisync',
@@ -504,9 +510,9 @@ export function buildBisyncRequests(args: BisyncArgs): RcRequest[] {
}),
...(configParam ? { _config: configParam } : {}),
...(filterParam ? { _filter: filterParam } : {}),
...(options.outer && Object.keys(options.outer).length > 0
...(Object.keys(outer).length > 0
? Object.fromEntries(
Object.entries(options.outer).map(([key, value]) => [
Object.entries(outer).map(([key, value]) => [
key,
Array.isArray(value) ? value.join(',') : value,
])
+38 -3
View File
@@ -42,9 +42,13 @@ Expand the accordion sections to customize your bisync operation. The Bisync sec
• resync — Required for the first run, or to reset bisync after an error. This makes both paths contain a matching superset of all files by copying Path2 to Path1, then Path1 to Path2. Only use resync when starting fresh, after changing filter settings, or recovering from an error — using it routinely would prevent deletions from syncing (deleted files would keep reappearing from the other side).
• checkAccess — Safety check that looks for matching RCLONE_TEST files on both paths before syncing. You must first create these files yourself in both paths. This prevents data loss if a path is temporarily unavailable or mounted incorrectly.
• checkAccess — Safety check that looks for matching RCLONE_TEST files on both paths before syncing. You must first create these files yourself in both paths. This prevents data loss if a path is temporarily unavailable or mounted incorrectly. Required when deltaList is on (unless force).
force — Override safety checks like max-delete protection. Use with caution, as this bypasses safeguards designed to prevent accidental mass deletions.
deltaList — Dropbox list_folder cursor listings instead of a full walk on the Dropbox side. First run still lists recursively; later runs apply deltas. Local path still walks. workdir must be on the shared volume (JSON: workdir). Requires checkAccess.
• recover — After an interrupted run, reconstruct listings from the last known good state instead of demanding resync.
• force — Override safety checks like max-delete protection and empty-listing abort. Use with caution, as this bypasses safeguards designed to prevent accidental mass deletions.
• createEmptySrcDirs — Sync empty directories as well as files. Without this, only files are synced and empty directories are ignored.
@@ -137,6 +141,9 @@ export default function Bisync() {
if (!source || !dest) {
throw new Error('Please select both a source and destination path')
}
if (outerBisyncOptions.deltaList && !outerBisyncOptions.checkAccess && !outerBisyncOptions.force) {
throw new Error('deltaList requires checkAccess (or force)')
}
return startBisync(buildStartArgs())
},
@@ -202,7 +209,8 @@ export default function Bisync() {
</Switch>
<Switch
isSelected={outerBisyncOptions?.checkAccess}
isSelected={outerBisyncOptions?.checkAccess || !!outerBisyncOptions?.deltaList}
isDisabled={!!outerBisyncOptions?.deltaList && !outerBisyncOptions?.force}
onValueChange={(value) =>
setOuterBisyncOptions({
...outerBisyncOptions,
@@ -214,6 +222,33 @@ export default function Bisync() {
checkAccess
</Switch>
<Switch
isSelected={outerBisyncOptions?.deltaList}
onValueChange={(value: boolean) =>
setOuterBisyncOptions({
...outerBisyncOptions,
deltaList: value,
...(value ? { checkAccess: true } : {}),
})
}
size="sm"
>
deltaList
</Switch>
<Switch
isSelected={outerBisyncOptions?.recover}
onValueChange={(value: boolean) =>
setOuterBisyncOptions({
...outerBisyncOptions,
recover: value,
})
}
size="sm"
>
recover
</Switch>
<Switch
isSelected={outerBisyncOptions?.force}
onValueChange={(value) =>