Skip to content

Commit 5836a43

Browse files
Your Nameclaude
andcommitted
release: v2.0.6
Fix: 本地删除的空目录同步后不再被远端重建。 reconcileDirectories 新增判断:之前同步过的目录若仅在远端存在, 视为本地有意删除,执行远端删除而非本地重建。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent eb2fc4d commit 5836a43

6 files changed

Lines changed: 68 additions & 17 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# 更新日志
22

3+
## 2.0.6 — 修复目录同步:本地删除的空目录不应被重建
4+
5+
### Bug 修复
6+
7+
- **修复本地删除的空目录同步后被远端重建**`reconcileDirectories` 原来只会创建目录从不删除,当本地删除之前同步过的空目录后,远端目录仍存在,被归为 `remoteOnly` 后直接重建到本地。修复后,之前同步过的目录只在远端存在时视为本地有意删除,执行远端删除。
8+
- **同步状态消息合并目录删除统计**`deletedRemoteDirectories``deletedLocalDirectories` 现在纳入同步完成消息的删除计数。
9+
310
## 2.0.5 — 精简非核心功能,保留纯三向对比同步 + 图片转存
411

512
### 重大精简

main.js

Lines changed: 30 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"id": "secure-webdav-images",
33
"name": "Secure WebDAV Images",
4-
"version": "2.0.5",
4+
"version": "2.0.6",
55
"minAppVersion": "1.5.0",
66
"description": "Separate note images to a dedicated WebDAV folder, sync the rest of the vault to a remote notes folder, and optionally keep Markdown notes in lazy on-demand mode.",
77
"author": "Kim-Huang-JunKai"

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "secure-webdav-images",
3-
"version": "2.0.5",
3+
"version": "2.0.6",
44
"private": true,
55
"scripts": {
66
"check": "node --check main.js",

tests/regression.cjs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,10 +1150,11 @@ async function testReconcileDirectoriesPreservesRemoteDir() {
11501150

11511151
const stats = await plugin.reconcileDirectories(remoteDirs);
11521152

1153-
assert.equal(stats.deletedRemote, 0, "directory reconcile should not delete remote dirs");
1154-
assert.equal(stats.createdLocal, 1, "remote-only dir should be recreated locally");
1155-
assert.equal(deleteCalls.length, 0, "remote-only dir should not be deleted");
1156-
assert.ok(app.vault.folders.has("RemovedFolder"), "RemovedFolder should be restored locally");
1153+
// Was synced before + remote only → user deleted locally → delete from remote
1154+
assert.equal(stats.createdLocal, 0, "previously-synced remote-only dir should NOT be recreated locally");
1155+
assert.ok(stats.deletedRemote > 0, "previously-synced remote-only dir should be deleted from remote");
1156+
assert.ok(deleteCalls.length > 0, "should issue DELETE for previously-synced remote-only dir");
1157+
assert.ok(!app.vault.folders.has("RemovedFolder"), "RemovedFolder should NOT be restored locally");
11571158
}
11581159

11591160
async function testReconcileDirectoriesCreatesLocalDir() {
@@ -1401,6 +1402,27 @@ async function testCopyDedupChinesePath() {
14011402
assert.ok(plugin.syncIndex.has(pathB), "pathB should remain in syncIndex");
14021403
}
14031404

1405+
async function testReconcileDirectoriesDeletesRemoteDirWhenLocalDeleted() {
1406+
const deleteCalls = [];
1407+
const { plugin, app } = createHarness(async (options) => {
1408+
const { url, method } = options;
1409+
if (method === "DELETE") { deleteCalls.push(url); return { status: 204, headers: {}, arrayBuffer: new ArrayBuffer(0) }; }
1410+
return { status: 200, headers: {}, arrayBuffer: new ArrayBuffer(0) };
1411+
});
1412+
// Simulate: directory was previously synced, user deleted it locally, but it still exists remotely
1413+
plugin.syncedDirectories = new Set(["DeletedLocally"]);
1414+
const rootFolder = plugin.normalizeFolder(plugin.settings.vaultSyncRemoteFolder);
1415+
const remoteDirs = new Set([rootFolder, rootFolder + "DeletedLocally/"]);
1416+
// Note: NOT creating "DeletedLocally" locally — simulating user deleted it
1417+
1418+
const stats = await plugin.reconcileDirectories(remoteDirs);
1419+
1420+
assert.equal(stats.createdLocal, 0, "previously-synced remote-only dir should NOT be recreated locally");
1421+
assert.ok(stats.deletedRemote > 0, "previously-synced remote-only dir should be deleted from remote");
1422+
assert.ok(deleteCalls.length > 0, "should issue DELETE for the directory");
1423+
assert.ok(!app.vault.folders.has("DeletedLocally"), "DeletedLocally should NOT be restored locally");
1424+
}
1425+
14041426
async function testReconcileDirectoriesKeepsNonEmptyLocalDir() {
14051427
const { plugin, app } = createHarness(async () => ({ status: 200, headers: {}, arrayBuffer: new ArrayBuffer(0) }));
14061428
await app.vault.createFolder("HasFiles");
@@ -1435,6 +1457,7 @@ async function run() {
14351457
["目录同步:保留本地缺失的远端目录", testReconcileDirectoriesPreservesRemoteDir],
14361458
["目录同步:远端新目录在本地创建", testReconcileDirectoriesCreatesLocalDir],
14371459
["目录同步:非空本地目录不会被删除", testReconcileDirectoriesKeepsNonEmptyLocalDir],
1460+
["目录同步:本地删除空目录后同步应删除远端而非重建", testReconcileDirectoriesDeletesRemoteDirWhenLocalDeleted],
14381461
["非ASCII路径:Emoji 目录名同步", testEmojiDirNameSync],
14391462
["非ASCII路径:中文目录名同步", testChineseDirNameSync],
14401463
["去重:中文路径内容感知去重", testCopyDedupChinesePath],

versions.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@
4343
"2.0.2": "1.5.0",
4444
"2.0.3": "1.5.0",
4545
"2.0.4": "1.5.0",
46-
"2.0.5": "1.5.0"
46+
"2.0.5": "1.5.0",
47+
"2.0.6": "1.5.0"
4748
}

0 commit comments

Comments
 (0)