|
49 | 49 |
|
50 | 50 | ### 重点修复 |
51 | 51 |
|
52 | | -- **删除同步改为完全按 Remotely Save 的三方比较执行**:移除自定义的删除宽限判断,统一使用“本地当前状态 + 远端当前状态 + 上次成功同步记录”的决策方式处理删除、重命名和移动。 |
| 52 | +- **删除同步改为完全按 Remotely Save 的三方比较执行**:移除自定义的删除宽限判断,统一使用"本地当前状态 + 远端当前状态 + 上次成功同步记录"的决策方式处理删除、重命名和移动。 |
53 | 53 | - **修复本地删除后误删远端已修改文件的问题**:当本地已删除、但远端在上次同步后又发生修改时,现在会按 Remotely Save 方案拉回远端版本,而不是继续删除远端。 |
54 | 54 | - **修复旧同步索引升级后导致旧路径被错误恢复的问题**:旧 `syncIndex` 迁移到三方同步基线时,若历史签名不是标准 `mtime:size` / `mtime:size:hash`,现在会回退到当前本地/远端状态补齐基线,避免创建、重命名、移动后的旧路径被误判并重新下载回来。 |
55 | 55 |
|
56 | 56 | ### 回归测试 |
57 | 57 |
|
58 | | -- 新增并通过“本地删除但远端已修改时应拉回远端”的 Remotely Save 对齐回归测试。 |
| 58 | +- 新增并通过"本地删除但远端已修改时应拉回远端"的 Remotely Save 对齐回归测试。 |
59 | 59 | - 修正重命名与双端修改场景的历史同步基线测试数据,确保回归测试使用真实可比较的签名。 |
60 | 60 | - 全部回归测试与多客户端模拟测试通过。 |
61 | 61 |
|
62 | 62 | ## 2.0.2 — 修复误判冲突与冲突副本被同步 |
63 | 63 |
|
64 | 64 | ### 重点修复 |
65 | 65 |
|
66 | | -- **修复首次成功同步后再次编辑就被误判为冲突**:此前全量同步完成后,`syncIndex.remoteSignature` 被错误写成了本地签名,后续快速同步会把正常本地修改误判成“远端也已修改”,从而为新建、重命名、移动后的笔记错误生成 `.sync-conflict-*` 冲突副本。现在改为持久化真实的远端 `mtime:size` 签名,后续编辑会正确走上传分支。 |
| 66 | +- **修复首次成功同步后再次编辑就被误判为冲突**:此前全量同步完成后,`syncIndex.remoteSignature` 被错误写成了本地签名,后续快速同步会把正常本地修改误判成"远端也已修改",从而为新建、重命名、移动后的笔记错误生成 `.sync-conflict-*` 冲突副本。现在改为持久化真实的远端 `mtime:size` 签名,后续编辑会正确走上传分支。 |
67 | 67 | - **修复冲突副本在下一轮同步时被上传到服务器**:`.sync-conflict-*` 本地备份笔记现在会被排除在内容同步之外,只保留在本地供人工比对和合并,不再在第二次同步时被当作普通笔记传到 WebDAV。 |
68 | 68 |
|
69 | 69 | ### 回归测试 |
70 | 70 |
|
71 | | -- 新增“全量同步后再次修改不会误判冲突”的回归测试。 |
72 | | -- 新增“冲突副本不会在后续同步中上传到服务器”的回归测试。 |
| 71 | +- 新增"全量同步后再次修改不会误判冲突"的回归测试。 |
| 72 | +- 新增"冲突副本不会在后续同步中上传到服务器"的回归测试。 |
73 | 73 | - 全部回归测试通过。 |
74 | 74 |
|
75 | 75 | ## 2.0.1 — 修复改名冲突文件 |
|
103 | 103 | - 移除旧对账函数:`reconcileRemoteAndLocal`、`reconcileLocalFiles`、`reconcileRemoteOnlyFiles`、`reconcileOrphanedSyncEntries` |
104 | 104 | - 移除快速同步 ribbon 图标(zap)、快速同步命令、`fastSyncRecentChangeLimit` 设置项 |
105 | 105 | - 移除插件状态中的 `appliedRemoteEventIds`、`lastAppliedRemoteEventCursor`、`lastFastSyncEventAt`、`pendingRemoteEventWrites` |
| 106 | +- 墓碑机制移除:6 个 `syncSupport` 方法和 6 个插件方法(`writeDeletionTombstone`、`readDeletionTombstones`、`resolveTombstoneDecisions` 等),~170 行 |
106 | 107 |
|
107 | 108 | ### 新增文件 |
108 | 109 |
|
109 | 110 | - **`localdb.js`**:localforage (IndexedDB) 封装,负责 `prevSyncRecords` 和插件元数据的持久化 |
110 | 111 | - **`tests/support/mock-localforage.cjs`**:基于 Map 的内存 mock,用于 Node.js 测试环境 |
111 | 112 |
|
112 | | -### UI 调整 |
113 | | - |
114 | | -- Ribbon:「完整对账」图标 tooltip 改为「同步到 WebDAV」 |
115 | | -- 命令面板:「Full reconcile vault content」改为「Sync vault content to WebDAV」 |
116 | | -- 设置页:「Full reconcile」按钮改为「Sync now」,「Fast sync recent change limit」滑块已移除 |
117 | | - |
118 | 113 | ### 数据迁移 |
119 | 114 |
|
120 | 115 | - 首次启动 v2.0.0 时自动将旧 `syncIndex` 条目迁移为 `prevSyncRecords` 写入 localforage |
121 | 116 | - 旧远端 `__secure-webdav-sync-events/` 目录不再使用(需手动清理) |
122 | 117 |
|
123 | | -- **墓碑机制移除**:删除 6 个 `syncSupport` 方法和 6 个插件方法(`writeDeletionTombstone`、`readDeletionTombstones`、`resolveTombstoneDecisions` 等),~170 行代码。`processPendingVaultRenames` 中的远端删除和 syncIndex 更新交由三向对比处理。 |
124 | | - |
125 | | -### 回归测试 |
126 | | - |
127 | | -- 全部 20 个回归测试通过 |
128 | | -- 移除 7 个墓碑专用测试,新增/更新 3 个三向对比重命名测试 |
129 | | -- 新增 6 个多客户端模拟测试全部通过 |
130 | | - |
131 | | -## 1.2.0 — 内容签名与副本去重 |
132 | | - |
133 | | -### 重点修复 |
134 | | - |
135 | | -- **内容签名启用**:`.md` 文件签名从 `mtime:size` 升级为 `mtime:size:contentHash16`,实现内容级别的变更检测。同名文件在不同路径复制时,会被识别为相同内容而非冲突。 |
136 | | -- **内容感知去重**:在冲突检测阶段,若远程文件的内容哈希与另一个本地文件匹配,则跳过冲突创建,避免 LLM/AI 工具「复制+删除」模式导致副本在三设备间持续传播。 |
137 | | -- **remotePath 虚假冲突修复**:修复 `reconcileLocalFiles` 中因 `remotePath` 变化而错误触发双方变更检测的问题。当仅路径变化而签名一致时,只更新索引不产生冲突。 |
138 | | -- **Phase 2 本地签名修复**:下载远端文件后使用实际本地文件签名,避免 Phase 4 因签名不一致而重复上传。 |
139 | | -- **删除宽限期生效**:修复 `markPendingVaultDeletion` 中 `recordedAt` 未设置的死代码问题,删除宽限期现在可以正确工作。 |
140 | | -- **冲突计数传递**:修复 `reconcileRemoteAndLocal` 中的冲突计数未传递到主计数器的问题。 |
141 | | - |
142 | | -### 回归测试 |
143 | | - |
144 | | -- 新增 Emoji 目录名同步测试(`📚 技术文章`) |
145 | | -- 新增中文/Emoji 复合目录名同步测试(`🧑💻 开发笔记`) |
146 | | -- 新增中文路径内容感知去重测试 |
147 | | -- 全部 37 个回归测试通过 |
148 | | - |
149 | | -## 1.1.5 — 远端残留旧文件清理修复 |
150 | | - |
151 | | -### 重点修复 |
152 | | - |
153 | | -- 修复全量同步时远端残留的旧路径文件不会被清理、反而被重新下载回本地的 bug。 |
154 | | -- 在 `reconcileRemoteAndLocal` 和 `reconcileRemoteOnlyFiles` 中增加陈旧副本检测:若远端文件的最后修改时间在上次同步之前、且本地已无对应文件,则判定为残留并删除,而不是恢复下载。 |
155 | | -- 修复后,笔记从扁平目录迁移到子目录时,远端旧路径的残留文件会被自动清理,不再出现新旧路径各有一份副本的问题。 |
156 | | - |
157 | | -### 回归测试 |
158 | | - |
159 | | -- 新增陈旧远端文件删除验证(无墓碑、无待处理重命名场景)。 |
160 | | -- 确认新远端文件仍能正常下载。 |
161 | | -- 确认首次同步不受陈旧检测影响。 |
162 | | - |
163 | | -## 1.1.4 — 同步一致性验证与回归测试补充 |
164 | | - |
165 | | -### 回归测试覆盖 |
166 | | - |
167 | | -- 新增创建文件 + 全量同步 / 快速同步 / 自动同步的回归验证。 |
168 | | -- 新增更名文件 + 全量同步 / 快速同步 / 自动同步 / 连续更名的回归验证。 |
169 | | -- 新增移动文件到新目录 + 全量同步 / 快速同步的回归验证。 |
170 | | -- 新增移动目录(批量更名)+ 全量同步 / 快速同步的回归验证。 |
171 | | -- 新增积压多操作(创建、更名、删除、再创建)后全量同步的一致性验证。 |
172 | | -- 新增快速同步后全量同步的无重复上传验证。 |
173 | | -- 新增本地与远端文件列表端到端一致性检查。 |
174 | | - |
175 | | -以上场景均通过 TDD 回归测试,覆盖无快速同步 / 有快速同步 / 依赖自动全局同步 / 手动触发全局同步四种同步路径,确认当前版本在文件创建、更名、移动、目录迁移场景下不会出现远端与本地不一致的 bug。 |
176 | | - |
177 | | -## 1.1.3 — 重命名与目录迁移稳定性修复 |
178 | | - |
179 | | -### 重点修复 |
180 | | - |
181 | | -- 修复远端 `rename` 事件回放时旧路径识别错误的问题,避免笔记迁移到新目录后,又被错误处理成旧位置恢复或新位置覆盖。 |
182 | | -- 快速同步不再只处理单批远端事件;当另一台客户端一次性移动或重命名大量笔记时,会连续消费多批事件,直到把本轮积压的迁移事件处理完。 |
183 | | -- 新增远端事件游标,避免已经处理过的历史事件被反复扫描或错误重放。 |
184 | | - |
185 | | -### 目录迁移可靠性 |
186 | | - |
187 | | -- 本地发起重命名/迁移目录时,删除旧远端文件后会继续清理已经变空的旧远端目录,避免后续完整同步再次把旧空目录拉回本地。 |
188 | | -- 远端重命名落地到本地后,会自动清理已经没有正文文件的旧本地空目录,减少“看起来像又回到原位置”的错觉。 |
189 | | -- 本次发布前已顺手清理当前库里 `mybook/📒项管笔记` 这类确认无正文的旧空目录,本地和远端都已处理。 |
190 | | - |
191 | | -### 回归测试 |
192 | | - |
193 | | -- 新增并通过以下关键回归: |
194 | | - - 远端事件游标会跳过已消费历史事件 |
195 | | - - 快速同步会连续吃完多批远端事件 |
196 | | - - 远端重命名会删除旧路径、落到新路径并清理空旧目录 |
197 | | - |
198 | | -## 1.1.2 — 快速同步删除修复与发布流程整理 |
199 | | - |
200 | | -### 快速同步可靠性修复 |
201 | | - |
202 | | -- 修复“远端已经明确删除,但本地仍残留文件”的场景,快速同步现在可以正确清理**未在本地继续修改**的旧副本。 |
203 | | -- 修复远端 `delete event` 被后续事件挤出最近窗口的问题,快速同步改为优先处理**最早未处理**的远端事件,避免旧删除事件长期饿死。 |
204 | | -- 当远端 `delete event` 仍在,但 tombstone 文件已经缺失时,增加安全兜底: |
205 | | - - 仅在本地文件自上次同步以来**未修改** |
206 | | - - 且远端文件确实已经不存在 |
207 | | - - 且事件签名能对上 |
208 | | - - 才允许删除本地文件 |
209 | | -- 同时补上保护条件,防止这类兜底逻辑误删本地后续新修改。 |
210 | | - |
211 | | -### 同步与冲突体验改进 |
212 | | - |
213 | | -- 完整同步修复了“本地重命名后,旧路径又被远端重新拉回”的问题。 |
214 | | -- 冲突中心现在会显示文章名、原文路径、冲突位置和片段预览,更容易定位和处理冲突。 |
215 | | -- 本地同步日志改为直接在系统文件管理器中定位日志文件,便于后续排查同步问题。 |
216 | | - |
217 | | -### 本地版本与恢复能力 |
218 | | - |
219 | | -- 本地版本快照、冲突副本与恢复入口继续完善,恢复前会自动备份当前内容。 |
220 | | -- 版本恢复与冲突清理相关的按钮和文案已经调整得更贴近实际使用语义。 |
221 | | - |
222 | | -### 仓库与发布流程整理 |
223 | | - |
224 | | -- 本地开发仓库已收口到正式目录,避免继续沿用 `demo3` 这类容易误删或误判用途的名称。 |
225 | | -- 发布流程改为显式同步 `main.js`、`manifest.json`、`styles.css` 到 Obsidian 插件目录。 |
226 | | -- 旧 TypeScript 构建入口保留为历史参考,不再默认覆盖当前正式发布产物。 |
227 | | - |
228 | | -### 回归测试 |
229 | | - |
230 | | -- 新增并通过以下关键回归: |
231 | | - - 快速同步会优先处理最早未处理的远端事件 |
232 | | - - 明确远端删除事件在 tombstone 缺失时也能删除未改动本地副本 |
233 | | - - 明确远端删除事件不会误删本地后续修改 |
234 | | - - 远端删除墓碑不会误删本地新修改 |
235 | | - |
236 | | -## 0.0.32 — 签名体系重构与完整同步修复 |
237 | | - |
238 | | -### 签名体系重构 |
239 | | - |
240 | | -文件签名从 MD5 哈希改为基于时间戳的三元组 `{ctime}:{mtime}:{size}`: |
241 | | - |
242 | | -- **ctime(创建时间)**:标识文件身份,区分同名不同文件 |
243 | | -- **mtime(修改时间)**:检测文件变化 |
244 | | -- **size(文件大小)**:辅助校验 |
245 | | - |
246 | | -本地和远端使用统一的签名格式,消除了之前本地用哈希、远端用时间戳的不一致问题。 |
247 | | - |
248 | | -### 墓碑机制增强 |
249 | | - |
250 | | -- 墓碑记录 `creationTime` 字段,删除时与远端/本地文件的 `ctime` 匹配 |
251 | | -- 防止同名不同文件被误删(`isTombstoneAuthoritative` 先检查 creationTime) |
252 | | -- `shouldDeleteLocalFromTombstone` 用 creationTime 判断是否同一文件,5 秒容差 |
253 | | - |
254 | | -### 完整同步修复 |
255 | | - |
256 | | -- **恢复孤立索引清理**:重新接入 `reconcileOrphanedSyncEntries`,处理索引中存在但本地已删除的路径(如重命名后的旧路径) |
257 | | -- **远端对账增加墓碑检查**:`reconcileRemoteAndLocal` 在下载远端文件前检查墓碑,避免已删除文件被恢复 |
258 | | - |
259 | | -### 快速同步与完整同步策略说明 |
260 | | - |
261 | | -| | 快速同步 | 完整同步 | |
262 | | -|---|---|---| |
263 | | -| 扫描范围 | 队列中的文件 + 远端事件 | 全量扫描远端 + 本地所有文件 | |
264 | | -| 远端请求量 | 少量 | 大量 | |
265 | | -| 适用场景 | 日常高频操作 | 首次同步、定期同步、手动触发 | |
266 | | -| 删除处理 | 队列驱动,30 秒宽限期 | 全局墓碑扫描 + 孤立索引清理 | |
267 | | -| 冲突检测 | 不检测 | 完整双向签名比较 + 冲突副本 | |
268 | | - |
269 | 118 | --- |
270 | 119 |
|
271 | | -## 0.0.31 — 快速同步索引全量扫描 |
272 | | - |
273 | | -修复 `detectRemoteChangesBySignature` 只检查前 20 条索引记录的问题,改为扫描全部索引条目。 |
274 | | - |
275 | | ---- |
276 | | - |
277 | | -## 0.0.30 — 远端回收站 |
278 | | - |
279 | | -- 删除操作改为将远端文件移至 `.__secure-webdav-trash__/` 回收站目录 |
280 | | -- 回收站文件保留用户设定的天数(默认 30 天),到期自动清理 |
281 | | -- 墓碑增加 `trashedRemotePath` 字段指向回收站位置 |
282 | | -- 设置页新增「回收站保留天数」 |
283 | | - |
284 | | ---- |
285 | | - |
286 | | -## 0.0.29 — 时间戳签名与上传前检查 |
287 | | - |
288 | | -- 文件签名从 MD5 哈希改为 `mtime:size` 时间戳格式 |
289 | | -- `processPendingVaultUploads` 上传前检查远端状态,避免覆盖新版本 |
290 | | -- 修复 `ensureRemoteEventFolder` 未创建最终目录的问题 |
291 | | - |
292 | | ---- |
| 120 | +## 1.x 系列(v1.0.0 – v1.2.0) |
293 | 121 |
|
294 | | -## 0.0.28 — 事件目录创建修复 |
| 122 | +v1.x 是插件从时间戳签名向内容签名过渡的阶段: |
295 | 123 |
|
296 | | -修复远端事件目录未正确创建导致事件写入失败的问题。 |
| 124 | +- **v1.2.0** — 内容签名启用(`mtime:size:contentHash16`),内容感知去重,中文/Emoji 路径支持,37 个回归测试通过 |
| 125 | +- **v1.1.5** — 远端残留旧文件清理,修复笔记迁移到子目录后旧路径文件被重新下载的问题 |
| 126 | +- **v1.1.4** — 同步一致性验证与回归测试补充(创建、更名、移动、目录迁移场景) |
| 127 | +- **v1.1.3** — 重命名与目录迁移稳定性修复(远端事件游标、连续消费多批事件、空目录清理) |
| 128 | +- **v1.1.2** — 快速同步删除修复(最早未处理事件优先、tombstone 缺失兜底)、冲突中心 UI |
| 129 | +- **v1.0.0** — 初始发布,双路径同步架构(快速同步 + 完整对账)、墓碑删除、远端回收站 |
297 | 130 |
|
298 | 131 | --- |
299 | 132 |
|
300 | | -## 0.0.27 — 自动更新 |
| 133 | +## 0.x 系列(v0.0.8 – v0.0.37) |
301 | 134 |
|
302 | | -- 新增 GitHub Releases 自动检查更新 |
303 | | -- 支持配置自动检查间隔(默认 24 小时) |
304 | | -- 设置页新增「检查更新」按钮 |
| 135 | +0.x 是插件早期探索阶段,经历 30+ 个版本迭代。核心演进路径:MD5 哈希签名 → 时间戳三元组签名 → 墓碑删除机制 → 远端事件流快速同步 → 远端回收站。这些版本为 v2.0.0 的三向对比架构积累了关键经验。 |
0 commit comments