Repository navigation
Releases: Dyse-Sofqi/SyncHub
Release list
0.2.4
这一版把「深度清理」(重写历史)从一条半截流程补成一条能走完、能中断、能续做、
并且说清代价的完整流程。修了四个真 bug,其中两个会丢东西;顺手把清理相关的
报错全部改成了中文。
起因是三条实测反馈:清理完之后点「立即同步」报一句英文的
refusing to merge unrelated histories;第二次清理直接失败;
以及「清理完.gitignore多出目录,那这些目录以后岂不是不进同步了?」——
最后这个问题界面从来没回答过,而它恰恰是这个动作最要紧的后果。
修复
- 重写不再删掉你的本地文件。
git filter-branch的最后一步会把工作区对齐到
改写后的 HEAD,于是被剔除的目录会从磁盘上消失 —— 与「只清历史」的承诺正好相反。
勾一个装着笔记的目录,笔记就没了。现在重写之后会把它们放回磁盘(内容与重写前
一模一样),确认页也把这条写成了明确的承诺。 - 第二次深度清理不再必然失败。 filter-branch 见到上一次重写留下的
refs/original/就拒绝开始,而插件只在「丢弃备份并回收」里清它 —— 等于
「清理两次之间必须先丢弃备份」,与「备份引用带时间戳(因为用户可能清理多次)」
的设计意图相矛盾。现在重写时会自动覆盖那份中间引用。 - 重写报错不再等于「什么都没发生」。 引用是边改写边更新的,收尾那次工作区同步
失败会让命令报错、但历史已经变了。原来这种情况被报成「重写失败」,于是忽略规则
不写(下次同步把刚剔掉的路径原样提交回来)、结果页也不出现,而哈希全变、远端分叉
已经发生。现在按「引用动没动」判断。 - 重写把整条历史清空时,分支会被自动还原。 勾选的路径若覆盖了每个提交的全部内容,
没有提交能活下来,git 会把当前分支整个删掉、仓库落到「没有提交」的状态。
现在检测到就当场还原,并告诉你「库是好的,请少勾一些路径」。 - 重写之后「立即同步」不再卡死。 重写后本地与远端没有任何共同提交,拉取会报
fatal: refusing to merge unrelated histories。现在这句话有中文说明、并且直接告诉你
该做什么(强制推送);拉取与 rebase 也会在动手之前就停下来(真跑起来会留下一仓库冲突)。 - 清理相关的报错全部中文化,不再出现 git 的英文原文。
新增
- 深度清理的四步收进一个窗口:体检 → 重写 → 强制推送 → 确认库没问题后丢弃备份。
推完自动进入收尾页;收尾页列出三件具体要检查的事(打开几篇笔记 / 图片能不能显示 /
别的设备重新 clone),然后才是「丢弃备份并回收」。空间要到这一步才真正释放 ——
以前结果页的次要按钮写着「完成」,会让人以为整件事结束了。 - 设置页「清理」一节多了「继续上次的清理」:只要还有未完成的清理(重写备份还在),
它就可点,点进去直接到收尾那一步。中途关掉 Obsidian、甚至重启之后都能接着做。 - 体检报告里,目录行会标出「N 篇笔记」;确认页会明确告诉你:剔掉的目录以后不再
跟着 git 同步(会被写进.gitignore),其他设备 clone 之后不会有它们。
如果勾中的目录里有笔记,会额外警告一次 —— 这是这个功能唯一会让人丢东西的路径。
修复(进行中的可见性)
- 重写进行中有进度可看了:弹窗里显示「已用 X,预计总共约 N 分钟」,左下角状态栏与
「仓库同步」面板顶部也会一直显示「正在重写历史…」。窗口可以关掉,重写完成之后
结果页会自己弹回来(关掉它不会让结果丢掉)。 - 进度不报百分比:重写是逐提交跑的,git 不会告诉你「处理到第几个提交」,
编一个百分比就是骗人。
0.2.3
这一版只修一个 bug,但它是必现的:在一个「刚建好、分支从没推过」的仓库里点
「立即同步」,会直接报错、什么也不做。
根因是同步链路里的一个死锁。链路是「提交 → 拉取 → 推送」,而拉取这一步
硬要求当前分支已经配置了上游;可建立上游的恰恰是推送(推送用的是
git push -u origin <分支>)。于是拉取先报错、链路中断、推送永远轮不到,
上游永远建不起来 —— 第一次同步必然卡死。
触发它的仓库形态很常见:远端分支和本地的
origin/<分支>都在,
只是branch.<分支>.remote/branch.<分支>.merge还没写进配置
(这两项正是推送会替你写的)。也就是说,问题不在「仓库没配好」,
而在「只差一次推送」。
修复
- 分支没有配置上游时,拉取不再报错。 改为:有配置的上游就用它;没有就退回
同名的origin/<分支>(在fetch之后判断,否则一个从没 fetch 过的仓库
看不到远端分支);远端连这个分支都还没有时,没有东西可拉 —— 直接跳过,
把建立上游交给随后的推送。这样「刚建仓库 → 点立即同步」一次就能走通。 - 只有在压根没配置远端时才会拦下,提示改为「还没有配置远端仓库,无法拉取。
请在设置中填写远端地址。」—— 指向真正该做的事,而不是让你去「先设置上游分支」。 - 游离 HEAD 的提示语从「无法推送」改为「无法同步」:它现在拉取和推送都会出现,
而「请先切换到一个分支」这条建议两边都适用。
内部
NoUpstreamError的含义收窄为「没有配置远端」(原来还把「分支没配上游」算在里面,
两者应对方式不同,混用会把用户指错方向)。- 新增 2 条真实仓库测试:抹掉上游配置后仍能拉回远端提交;远端还没有该分支时
拉取返回「已是最新」、随后的推送把上游建起来。
0.2.2
[0.2.2] — 2026-10-10
这一版做两件事:别让大文件进 git(两层预防),以及已经大了怎么办(清理)。
起因是一次实测:一个 159 次提交的笔记库有 460 MB 的 .git,其中插件构建产物 319 MB、
字体 186 MB、向量库缓存 84 MB,而真正的 markdown 只有 63 MB —— 仓库体积失控几乎从来
不是笔记造成的。而 git 的历史不可逆:大文件一旦提交进去,事后清理要重写全部提交,
那是一件按提交数计时的重活。所以预防建在「它进历史之前」,清理则是一套独立的、
把代价说在前面的动作。
还有一条独立的轴:重写历史的开销只吃提交数,与每个提交改了多少字节无关 ——
20 MB 但有 10000 个「只改一行」的提交,重写要几小时;500 MB 但只有 200 个提交,
只要十几分钟。所以「本地状态文件」(光标位置缓存、工作区布局)进 git 的代价
不是体积,而是每个同步周期白多一个提交。大文件拦截防不了这一条。
新增
- 清理:体检 / 回收 / 深度清理(设置页「仓库同步」的清理一节)。三层风险递增,
每一层都说清代价:- 体检(只读)—— 按目录汇总历史里占空间最多的部分,外加最大的单个对象。
按目录而不是按文件,是因为剔除的单位就是目录:报告里的每一行正好是一个
可以拿去执行的动作。库根目录的文件只报账、不提供勾选(剔掉它们等于清空整个库)。 - 回收空间 ——
git gc --prune=now。安全,但常常一点也回收不到:大文件基本
都在可达的历史里,只有重写才能清掉。这句话写在描述里,免得你把「没变小」当成功能坏了。 - 深度清理(不可逆)—— 把选中的路径从全部历史里剔除(重写每一个提交)。
动手前会把三件事摆出来:所有提交的哈希都会变(远端要强制推送、其他设备要重新
clone)、已经推到远端的旧历史清不掉、以及预计耗时(按提交数算,实测约
3.5 秒/提交 —— 一个 159 提交的库约 10 分钟,期间请不要关闭 Obsidian)。
执行前先建一个备份引用(refs/obsync-backup/<时间戳>),失败或后悔都能退回去;
执行后自动把那几条路径写进.gitignore,否则它们会在下次提交时原样回来。 - 丢弃备份并回收 —— 重写之后空间不会立刻变小(备份还拉着旧对象,这是刻意的:
先让你确认库还能用,再丢退路)。确认无误后点它,才真正释放空间。不可逆。
- 体检(只读)—— 按目录汇总历史里占空间最多的部分,外加最大的单个对象。
- 提交前的大文件拦截(设置页「仓库同步」的大文件阈值,默认 5 MB,填
0关闭)。
提交 / 立即同步时,待提交文件里超过阈值的会被拦下、弹窗问一次,整条链路停在
那里 —— 不会出现「同步完成」而那个文件其实没提交。弹窗把两个选择各自的代价都写清楚了:
仍然提交(它以后每次改动都会在历史里再存一份完整副本)或退出跟踪并忽略
(不再有版本历史、本地文件保留;历史里已有的副本不会消失,仓库体积不会因此变小)。
关掉弹窗 = 取消。自动同步不弹窗,改为发一条通知告诉你「同步已暂停、去哪处理」。 - 「补齐推荐的忽略规则」按钮(设置页「仓库同步」的
.gitignore一节)——
把字体(ttf/ttc/otf/woff/woff2,大小写各一条)、Office / LibreOffice 临时文件
(~$*、.~lock.*#)、本地状态文件(workspace.json、workspace-mobile.json、
workspaces.json、*-position-cache.json)这几类规则并进.gitignore。
只追加缺的那些,你自己写的规则一行都不动,可以随手点(幂等)。
它与那个覆盖式的「填入默认内容」是两回事。 - 「停止跟踪本地状态文件」按钮(同一节)—— 光加忽略规则对已经跟踪的文件没用
(.gitignore只管未跟踪的),而已经同步了一阵子的库恰恰是最需要它的。这个按钮
把已跟踪的那几个从索引里摘掉(本地文件不动),并补上忽略规则。会先让你看见
要摘哪几个再确认。 - 「忽略插件目录」开关(默认关)—— 打开后把整个插件目录也加进推荐规则。
插件是仓库体积最大的单一来源,但忽略之后换设备 clone 时插件不会自动就位,得重新装。
这是个取舍,所以做成开关交给你,而不是替你选。 - 面板每一行的「放弃更改」(仓库同步面板的「更改」列表,2026-10-10)——
一键把那个文件退回上次提交的样子。两种场景共用一个动作,因为它们在 git 眼里是同一件事:
改坏了想退回、以及误删了想找回(被删的文件会从上次提交里重新写出来)。
它是本插件唯一会丢用户编辑的动作,而且不可逆(放弃的编辑从来没被提交过、
不在 git 里),所以:确认弹窗会列出具体哪几个文件、把「不可逆」写在正文里、
确认按钮用警示色。两类行不给这个入口:未跟踪的新文件(它们没有「上次提交」
可退,而「放弃」对它们等于删掉一个新文件 —— 丢的东西一点退路都没有)、
冲突行(冲突区已经有「放弃本次合并」,而面板看不到文件内容,
在这里替用户决定「用哪一边」正是不该做的事)。 - 「文件恢复关着」的警告框(仓库同步页最上方,只在它关着时才出现)——
Obsidian 的「文件恢复」核心插件默认每 5 分钟给每个改过的文件存一份快照、保留 7 天,
存在 IndexedDB 里,完全不碰 git。它才是「高频防丢失」该用的机制:git 的恢复粒度是
全库提交,用它做高频恢复会让提交数等于编辑次数。所以想靠缩短同步间隔来防丢数据时,
这个警告框会先把你指到那里。(第一版是塞进「注意事项」的一条,太不显眼 ——
它讲的是数据安全,现在有独立的警告配色与标题。)
变更
- 定时同步的默认周期 10 分钟 → 30 分钟(只影响新装的库与缺这个字段的库,
已经存过这个值的库不受影响)。理由:高频保护已经明确交给「文件恢复」,定时同步剩下的
职责是「云端新鲜度」与「跨设备」,而灾难恢复本身要花几小时 —— 丢 30 分钟与丢 5 分钟
没有实际差别。反过来,间隔越短提交数越线性增长,而重写历史的开销只吃提交数。
想让云端更实时请用「立即同步」(命令 / 面板 / 功能区都有)。 - 去掉了仓库同步面板上的逐文件暂存(「暂存此文件 / 取消暂存」与「全部暂存 /
全部取消暂存」)—— 它们做不到看起来在做的事:SyncHub 的「提交」是git add -A,
手动暂存了什么对最终提交毫无影响;更要紧的是定时同步到点会把它们一起提交掉,
也就是说这个按钮连「暂时不提交」都做不到。用户暂存 A 想只提交 A,结果 B 一起进去了。
SyncHub 不做选择性提交 —— 它的定位是「把整个库同步上去」。按暂存状态的分组保留
(冲突文件落在「已暂存」那一组)。 - 自动同步被大文件拦下时会给一条通知(以前是静默停住)。只要那些文件还在,自动同步
就一直停着 —— 这条通知是它唯一的表现,所以每次到点都会提示一次。 - 文案口径改了:「已经写进历史的图片 / 文件不会让仓库变小」那几处,以前一律接
「本插件不做重写历史」—— 现在指向设置页「清理」里的深度清理。
修复
- 设置页里
.gitignore代码框的全宽失效了。 它那条width: 100%被 CSS 解析器
整条丢弃:上面那句注释里写了`**/` 递归,而**/里的*/提前结束了注释,
剩下的文字被当成下一条规则的选择器,于是规则连同它一起被丢掉 —— 不报错、样式就是不生效。
代码框因此只有 173px 宽(容器 660px)。同一段注释里min-height、white-space、
padding也一起失效了。
pnpm check新增第 8 项CSS 注释完整性守住这类问题:现有「CSS 类覆盖」那一项拦不住它
(被丢弃的规则在文本上仍然「有定义」)。
0.2.1
[0.2.1] — 2026-10-09
这一版把功能区头像从「一张只能看的图」变成设置页的入口:点它打开设置窗口并停靠
「通用」页(换平台、改令牌都在那一页),头像外侧常驻一圈柔灰虚影环、悬停时环加深并晕开
一团保守的模糊扩散,而光标保持默认 —— 它首先是一张头像,点击只是顺手的入口。
另给状态栏条目加了一个「贴靠最左侧」开关(默认开),并删掉了「状态栏占满整屏宽」
开关与那条拉全宽的 CSS 规则 —— 状态栏恢复 Obsidian 原生形态(右下角一簇),
条目仍排在这一簇的最左侧。
新增
- 功能区头像可以点了(2026-10-05 加的那个头像):点它打开设置窗口并停靠
「通用」页(换平台、改令牌都在那一页)。两条刻意的「不摆出按钮样子」的设计:
头像外侧常驻一圈虚影环(2px 柔灰,紧贴头像边缘、中间没有缝),悬停时
环加深并晕开一团模糊扩散(范围保守,不超出功能区),而光标保持默认 ——
它首先回答「这是谁」,点击只是顺手的入口 - 「状态栏同步条目贴靠最左侧」开关(设置页「通用」,默认开)。开着就是一直以来的
表现:同步条目排在状态栏那一簇的最左侧(只改自己的视觉顺序,不动其他条目)。
关掉后条目不作特殊处理,按 Obsidian 默认顺序排在其他条目后面。
它与下面删掉的「状态栏占满整屏宽」是两回事:那个碰的是状态栏的宽度
(为了贴屏幕最左,代价是整体观感从「右下角一簇」变成「底部一条」),已整条删除;
这个只管条目在状态栏里的顺序,状态栏本身两种状态下都是 Obsidian 原样
变更
- 「状态栏占满整屏宽」开关删掉了,状态栏不再拉成全屏宽。 同步条目仍然排在
状态栏那一簇的最左侧(只改自己的视觉顺序,不动别人的条目),只是不再贴
屏幕最左。理由:拉宽能让条目贴到屏幕最左,但代价是状态栏的整体观感
从「右下角一簇」变成「底部一条」—— 那是用户自己的界面。设置项、那条 CSS
规则与main.ts里给body加/摘类的代码一并删除;老 data.json 里残留的
statusBarFullWidth字段会被自然忽略,不需要迁移
0.2.0
[0.2.0] — 2026-10-08
这一版补上了一整块**「看得见的状态」(功能区头像、同步特效横幅、状态栏忙碌圆环、
初始化徽标),把主题从「只能绑定 / 更新」补成「也能新装」,给图片同步加了
变动后自动同步,并修掉一个在 Obsidian 1.14 上让功能区头像静默消失**的选择器问题。
新增
-
功能区头像(设置页「通用」)—— 打开后在左侧功能区(ribbon)底部挂一张
当前令牌账号的圆形头像。它回答的是「现在配的令牌是哪个账号」(镜像探测拿的
也是这个账号名),没有点击动作。地址与账号名来自同一次
validateToken()(Gitee 的GET /v5/user一个响应里
两个字段都有),所以不多打一次接口;那个平台没配令牌时一个请求都不发 ——
匿名问那个接口只有 401,而 Gitee 的匿名配额实测极低。平台由下面新增的「使用 Gitee 头像」决定(默认开 = Gitee,关 = GitHub)。
头像是账号资料、插件改不了,所以那一行的描述末尾直接给了换头像的个人资料页
链接,并且跟着平台走(Gitee →gitee.com/profile、GitHub →
github.com/settings/profile)—— 点一下就到换头像的地方。 -
主题也能新装了。 在它之前主题只有两条路:绑定库里已经装好的、更新
已跟踪的 —— SyncHub 从来没能把一个主题装到磁盘上。现在多了「添加主题仓库」
按钮与命令,主题写进{configDir}/themes/{主题名}/,装完不替你切换
(到「设置 → 外观 → 主题」里选它)。三处刻意与插件不同:目录名取远端 manifest 的
name(不能当目录名时回落到仓库名)、
不做镜像发现(主题的镜像判据依赖本地已装的那一版,新装时手上还没有)、
绝不调setTheme。另外立了一条安全线:目标目录里已经装着另一个主题时
拒绝写盘(同名不同主题确实存在,而被覆盖的很可能是你当前正在用的那个,
且它不一定在跟踪列表里、没有「重新下载」这条路)。把主题地址填进「添加插件仓库」(或反方向)时,失败后会探一次对面的标志性文件
(main.js/theme.css),确有就给一个「改为按主题安装」的按钮 ——
而不是只留一句「缺少 main.js」。 -
「正在同步」看得见(状态栏 + 侧边栏面板)。
状态栏那一格忙碌时挂一个转动的圆环并把文字改成强调色(原来忙碌态与常态
只差几个字,一样是 12px 灰字,在一排条目里扫过去看不出区别,而同步可能要跑几十秒);
文案也从「正在提交…」改成「正在同步:提交中…」—— 点「立即同步」时一眼能分出
这是三步链路里的一步,后面还有拉取与推送。侧边栏仓库同步面板的工具条正下方加了一条同步特效横幅(转圈 + 三个阶段 +
一根不确定进度条 —— git 不会报「推到第几个对象」,编一个百分比就是骗人;
三个阶段本身才是真实可得的进度)。动作进行中四个动作按钮禁用(刷新不在其中,
它只读,随时可点)。横幅不整块重绘:一次「立即同步」三个阶段各变一次,
走整块重绘会白跑三遍「分支 / 远端 / 体积 / 历史」(实测一次重绘 10 个 git 子进程)。 -
图片「变动后自动同步」(设置页「图片同步」,默认开)—— 在受管文件夹里
新增或改动图片之后,停手 30 秒(5–600 可调)自动跑一轮。一次编辑会话
(拖进一批图、批量压缩)会被合并成一轮,也不会在你还在写文件的时候开始。
它只管本机的改动。周期同步的职责因此改成「拉回其他设备上的变化」(另一台设备传的图、云端被
手工改动的对象 —— 那些在本机不会产生任何事件),默认周期从 10 分钟改成 30 分钟
(它默认仍是关的)。完整推导(成本模型、四个触发器的分工、明确不做的事)见
docs/image-sync-design.md。 -
设置页「仓库同步」能独立走完全部基本设置 —— 「初始化 git 仓库」从侧边栏
面板搬进设置页,与远端地址、git 可执行文件路径排在同一张卡片里(这三项都是
「连接测试能通过」的充要条件),排在「连接测试」之前。那一行带状态徽标
(「已是 / 还不是 git 仓库」,已是时按钮置灰)。 -
插件安装器页重排 + 标签数字徽标。 页内顺序改为:状态小字 → SyncHub 自身更新
卡片 → 「启用 Gitee 镜像源更新 SyncHub」开关 → 「进入设置页时自动检查」→
「启动时检查更新」→ 启动检查延迟 → 「自动发现 Gitee 镜像」。「进入设置页时自动检查」现在同时查跟踪列表与 SyncHub 自身 —— 一个插件都没跟踪的
用户同样该知道自己有没有新版本。SyncHub 自身有可用更新时,「插件安装器」标签上挂
数字徽标(原来只在页面里一行小字,Notice 一闪就错过)。
变更
-
访问令牌移进「通用」页(原来在「插件安装器」页)。它和头像同处一页 —— 两者讲的
是同一件事(当前配的是哪个平台的哪个账号)。 -
自身更新来源从自由文本框改成开关「启用 Gitee 镜像源更新 SyncHub」(默认开 =
走 Gitee 镜像sofqi/SyncHub,关 = 走官方 GitHub 仓库)。两个固定地址之间切换本来
就是二选一,而原先的自由文本框要用户先读懂一串规则(空串算默认、owner/repo简写
按 GitHub 解释、非法地址抛错)才敢动。代价是不再支持自定义来源(如自己的 fork)—— 那个场景本来也不成立:写盘前校验
远端 manifest 的id必须是ob-sync,fork 改了 id 就会被拒。 -
删掉「启用插件安装器」总开关。 它在
src里只有两个读取点,且都是自动检查的
前置条件(功能区那个图标、5 条安装器命令、设置页按钮与列表从来不看它)。
于是「关掉它」与「把两个检查开关都关掉」完全等价 —— 一个 off 的第二种说法,
而名字让人以为「不装了」。 -
按钮行的外观与图标:「添加主题」→「添加主题仓库」;「绑定已安装的插件与主题」
→「绑定已有插件或主题」(并在文字前加 lucidelink图标);「检查全部更新」→
「检查更新」(加refresh-cw图标)。这一排按钮的卡片(连同标题与说明)去掉,
只留按钮 —— 页签名已经是页名,列表下方还有空状态提示,标题与说明都是重复信息。 -
四个设置页的页首标题删掉(插件安装器 / 仓库同步 / 图片同步 / 通用)—— 标签页
已经写着页名,再顶一行同名标题是重复。节内的小标题(「访问令牌」、R2 连接、
连接测试…)留着。
修复
-
Obsidian 1.14 上功能区头像「静默消失」。 1.14 把功能区容器的修饰类从
mod-left
改成了mod-primary,而findRibbonContainer()的四个选择器全都写着mod-left
→ 一个都匹配不到 → 恒返回 null →render()静默 return,没有任何报错(所以
它看起来像「某个改动弄坏了」)。现在补上mod-primary(保留mod-left),再加一条
不依赖版本修饰类的兜底.workspace-ribbon .side-dock-settings(只有左 / 主功能区
才有这一组,不会误取右侧)。教训:选择器不要依赖版本修饰类,永远留一条不依赖它的兜底;升级 Obsidian 后要
重抠.probe的app.css并重跑对应探针。 -
「初始化 git 仓库」的状态徽标每切一次设置页就重问一次。 每次重绘都起一个
git is-repo子进程,结果回来才填徽标 —— 于是能看到徽标「弹」出来,布局还被撑高
(.obsync-badge的line-height: 1.6+padding: 0.05em让药丸 20px,而标题那一行
只有 17px,整行被顶高 3px、说明文字往下移)。现在问过一次就缓存(只在内存:
这个值会变 —— 别处rm -rf .git、从别的设备同步回一个没初始化的库 —— 写进
data.json就是一句没人纠正的假话),并把徽标改成line-height: 1+
padding: 0.15em 0.5em(改完重量一遍:「有徽标」与「没徽标」逐项相同)。 -
点完「初始化仓库」后按钮又亮回来 ——
apply()改成同步之后,点击处理finally
里的setDisabled(false)会把刚被置灰的按钮重新点亮;改成按已知事实恢复。 -
setButtonText与setIcon连用只剩图标。setButtonText是「清空整个按钮再写
文字」,而ButtonComponent.setIcon会先删掉第一个子节点再 append 图标 —— 两者连用,
文字被当成「第一个子节点」删掉。按钮行那两个图标因此自己建一个容器装图标、再 prepend
到文字前面(换文字之后还要重调一次)。
内部
-
平台列表移进
host/types.ts,HostKind由它推导 —— 此前「有哪些平台」有 4 份
副本,其中settings那份(持久化校验)漏掉某个平台时,用户在那个平台上装的插件会在
下次加载data.json时被当成非法条目无声丢弃(不报错,列表里就没了)。 -
删掉两处死代码:
InstallerService.checkForUpdate(判据用requestedVersion,跟踪
最新版时那个值是字符串"latest",几乎恒报「有更新」)与isManifestCompatible。 -
设置迁移 v8 → v9(自身更新来源从「自由地址」折算成布尔)与 v9 → v10
(删总开关时把两个检查开关置 false)。折算规则与当年那套解析同源,坏形状一律按当年
同一口径处理 —— 老用户升级时行为不变。 -
新增两个能脱离 Obsidian 单测的纯逻辑模块:
ImageChangeQueue(攒批器:静默期 +
硬上限 + 正在跑时不丢)与features/avatar/ribbonAvatar.ts。测试增至 88 文件 /
1871 用例。 -
.probe的app.css随 Obsidian 1.14.4 重抠,头像探针的功能区类名改用
mod-primary并把两档类名都跑一遍;README 补了「升级 Obsidian 后要重抠 + 两档都要跑」。
0.1.9
[0.1.9] — 2026-10-05
这一版集中在仓库同步面板与**设置页「仓库同步」**的可用性,另有一批文案与布局修复。
新增
- 面板顶部重排 + 「更改 / 最近提交」标签组。 状态摘要(
与远端一致/ 领先落后)与
「仓库大小 / 待提交改动」两栏搬进「更改」页顶部;列表按标签组切换,长列表不再互相挤占滚动位置。
切换标签只换可见性,不重跑那几条 git 命令。冲突区留在标签之外(它是「现在就得处理」的状态)。 - 更改列表的格式筛选。
全部 / Markdown / .png / …,选项由这一轮真实出现过的格式生成并带
数量 —— 只想看笔记时一眼筛出.md。筛选只影响列表,「待提交改动」那一栏始终是总数。 - 「嵌套仓库」行(gitlink)识别与一键「不再跟踪」。 在库的插件目录里就地开发时,那些目录自带
.git,库把它们记成指针(索引模式160000):看着像文件夹、没有文件级差异、怎么点「全部暂存」
都消不掉。面板现在给它加徽标、写明原因,并给一个「不再跟踪」(摘索引 + 写.gitignore,
本地文件与它自己的.git一个都不动)。 - 差异视图改成主工作区标签页(原来是弹窗 —— 太小,长行读不了),并加了 双栏对照模式
(像 VS Code:删除在左、新增在右,同一段改动按序号对齐,多出来的那一行只有一边有内容)。
视图模式跟着标签页记住;文件差异会跟着库状态自己刷新。 - 面板工具栏显示距离下一次同步的倒计时(与设置页那一行同一份数据),后移到「与远端一致」
同一行展示 —— 两者都是「我现在处于什么状态」。 - 设置页「仓库同步」重排: 远端地址(就地可改的输入框)+「打开仓库同步面板」同一行、
git 可执行文件路径,这两项排在「连接测试」之前(它们是「测试能通过」的充要条件)。 - 标签栏照 MDRazor 重做(只有当前那一个是贴着内容区的卡片),工具条按钮去阴影、
间隙收紧到 4px,刷新按钮改成与前面三个同样的文字按钮。
变更
- 「与远端一致」文案更准确:工作区还有没提交的改动时改为
「与远端一致,但有未提交的改动」(而且不标绿)——ahead = behind = 0只说明已提交的部分
对齐了,原来那句话会让人以为可以关电脑了。 - 面板不再显示可编辑的远端地址(配置归设置页);
renderRepo与safeRemoteUrl一并删除,
面板渲染少一次getRemoteUrl()。 - 「最近提交」页里那行与标签同名的标题删掉(多余)。
- 远端地址的校验逻辑抽到
features/sync/remoteUrl.ts(输入框与命令面板的「编辑远端地址」弹窗共用)。
修复
Setting.setClass("a b")会抛InvalidCharacterError(它走classList.add,一次只能一个
类名)—— 真机上整页设置渲染不出来。测试替身现在照真机那样抛错,同样的错在单测里就会红。- 面板按钮的悬停效果:上一版给所有按钮换了浅底,把「立即同步」(强调色填充 + 白字)也一起改了,
悬停时变成浅底白字、整颗糊掉;现在主按钮用自己的强调色悬停色。 - diff 内容框的高度限制:
.obsync-diff-body上那条max-height: 68vh是弹窗时代留下的,
改成标签页之后变成「框里一条滚动轴、框下空一片」;去掉之后整页滚一条轴。 与远端一致那一行与倒计时胶囊没对齐(段落自带外边距),现在两者中线一致。- 工具条的 padding 从 16px 收到 8px —— 侧边栏窄一点就不得不换行。
0.1.8
SyncHub 把三件事合在一起:用 git 同步笔记仓库、把图片镜像到 Cloudflare R2、
从 GitHub 或 Gitee 安装社区插件与主题 —— 并且都不只认 GitHub。界面中文优先、英文对等。
本次更新(0.1.8)
新增
- 图片管理面板里可以单独重命名一张图了 —— 列表每行右侧一颗铅笔按钮,点开一个
预填当前文件名的输入框。它与底部的「批量重命名」是两条路:一个管「就这一张」,
一个管「勾选了一批」—— 改一张图的名字不该要求先勾上它。 - 点列表里的缩略图可以放大看 —— 就地弹出预览,不离开面板。滚轮直接缩放
(25% – 400%),放大时弹窗整体跟着变大直到窗口上限,再大就按住图片拖动看
其余部分。100% 的含义是「图片完整装进窗口」,不是原始像素 1:1。
变更
- 图片管理面板底部那颗按钮从「重命名…」改成「批量重命名」。
修复
- 「仓库同步」设置页里
.gitignore代码框的宽度 —— 它此前只靠样式表里的一条
width: 100%,而插件样式表不保证在热重载时被重新读入,于是改了 CSS、界面却没变,
框缩回了右侧那几百像素。现在宽度与box-sizing直接写在元素上,不再依赖样式表。
安装
下载 main.js / manifest.json / styles.css,放进
<你的库>/.obsidian/plugins/ob-sync/,然后在 Obsidian 的「第三方插件」里启用。
国内访问 GitHub 慢或被阻断时,用 Gitee 镜像:
https://gitee.com/sofqi/SyncHub/releases
要求
- Obsidian ≥ 1.8.7
- 笔记同步需要系统 git,仅桌面端;插件安装与图片同步在移动端也可用
已知限制
- 同步只支持桌面端(移动端没有系统 git)
- 主题:支持绑定库里已装的主题并更新,不支持从仓库新装
完整更新记录见 CHANGELOG。
0.1.7
SyncHub 把三件事合在一起:用 git 同步笔记仓库 + 把图片同步到 Cloudflare R2 + 安装社区插件与主题,三者都支持 GitHub 与 Gitee,界面中文优先、英文对等。
这一版:图片同步 · 差异视图 · 可直接编辑的 .gitignore
🖼️ 图片同步(Cloudflare R2)
库里的图片在 R2 上存一份副本 —— 笔记走 git,图片走对象存储。
- 只复制,从不删除:每一轮只补齐缺的那一边。删除只在你删掉本地那张图、并被问过之后才发生 —— 「一边少了 = 用户删的」本质上判断不准(清单丢失、两台设备各删一边都会错),判断错的代价是删掉你没打算删的东西。
- 删本地时问一句(默认)。也可以设成「永远同步云端」(不问,直接一起删 —— R2 没有回收站)或「永不同步云端」(云端永远不动;那一份会被下一轮同步下载回本地,因为镜像是双向补齐的)。
- 图片管理面板:把「本地有哪些图」「云端有哪些图」「哪些图被引用着」三条轴摊平成一张可筛选的表 —— 批量同步 / 压缩 / 重命名 / 删除都在那里。「已链接」徽标悬停能看到是谁在引用它。
- 笔记内裁剪与压缩:阅读视图里每张库内图片都有悬浮工具条;压缩保持原格式,而且只在变小时才写回。
- Excalidraw 画布里的引用也认得出:画布数据是压缩后写进
.excalidraw.md的,不解压就会把正在用的图当成失联删掉。 - 另有公网外链、受管文件夹(默认整个库)、密钥进系统密钥库。
🔍 差异视图
仓库同步面板上每个文件(含冲突行)、每条提交都能点开看改了什么;命令面板里也有「SyncHub:查看当前文件的差异」。
- 工作区改动与已暂存改动分两节显示 —— 同一个文件完全可能两边都有内容(
git status里的MM),只给一边等于把另一半藏起来; - 逐行给新旧两个行号、增删分色、保留
@@段落头; - 未跟踪的新文件按「全部新增」显示内容;二进制文件、纯重命名、内容被截断、文件过大各有明确说明(一片空白会被读成「没有改动」);
- 合并提交也能看(git 默认对它不输出差异)。
⚙️ 「仓库同步」设置页里可直接编辑 .gitignore
多行代码框 + 状态徽标(已保存 / 有未保存的修改 / 尚未创建)+ 保存 / 填入默认内容(只填进框里,不直接覆盖)/ 在编辑器中打开。改动在失焦时也会保存;文件不存在时不会自动创建(打开设置页不该往库里多出文件)。
顺带修好两处:模板里的配置目录名不再写死 .obsidian(配置目录改名后那些排除规则一条都不会匹配),以及「在编辑器中打开」打不开时会明说原因并指回这个框,而不是点了没反应。
🧹 按社区审核规范复查
按 eslint-plugin-obsidianmd 的规则本体过了一遍:18 处降到 1 处(剩的那条是「建议迁到 Obsidian 1.13 的声明式设置 API」—— 设置页整体是手写渲染的,留作独立改造)。修的都是规则明确要求的形态:不写内联样式、不静态 import Node 内置模块、console.info → console.debug、定时器走 window、不用 document.createElement、不写死配置目录路径。
环境要求
- Obsidian ≥ 1.8.7
- 笔记同步需要系统 git,仅桌面端;插件安装与图片同步在移动端也可用
已知限制
- 笔记同步只支持桌面端(移动端没有系统 git)
- 主题:支持绑定库里已装的主题并更新,不支持从仓库新装;不做版本钉选与主题 beta 通道
- 逐文件 hunk 级暂存、树形文件视图、行作者(blame)等 obsidian-git 的增强功能仍未做
—— 文件级 diff 查看已在 0.1.7 补上
完整变更见 CHANGELOG。
0.1.6
SyncHub 把两件事合在一起:用 git 同步笔记仓库 + 安装社区插件,两者都支持 GitHub 与 Gitee,界面中文优先、英文对等。
这一版:插件 id 回退为 ob-sync
上一版(0.1.5)把插件 id 从 ob-sync 改成了 synchub,被社区审核打回:
The plugin ID in (manifest.json) does not match the existing plugin ID
原因是审核系统在更早的提交里就把本插件登记为 ob-sync,id 与既有登记绑定,
不能自行更改。这一版把它改回去。
显示名 SyncHub 保持不变 —— 商标那条审核已经通过,本次没有再报名字问题。
所以最终形态是 显示名 SyncHub + id ob-sync,两者不一致是有意的:
审核登记决定 id,商标规则决定显示名,来源不同。
⚠️ 如果你装过 0.1.5
Obsidian 是按 id 找插件的,所以安装目录要从
.obsidian/plugins/synchub/ 回到 .obsidian/plugins/ob-sync/:
- 把
data.json(设置 + 跟踪列表)复制回ob-sync/目录,
否则插件会以默认设置启动; - 删掉
synchub/目录,否则插件列表里会出现两份; - 跨 id 不能用「检查更新」(自我更新会校验远端 id,对不上就拒绝写盘),
需要手动装一次。
访问令牌始终不受影响:它们存在 obsync-token-* 这个密钥 id 下,与插件 id 无关 ——
这一来一回都没有作废过凭据。
本版其他内容(承接 0.1.5)
- 插件改名为 SyncHub(原名
OBSync以全大写OBS开头,命中商标规则) - 修复英文界面的
.gitignore模板:补上排除本插件自己的data.json
(中文模板一直有这条),避免英文用户的设置被同步、两台设备互相覆盖 - 修掉两处社区审核打回:SecretStorage 的 API 版本守卫、
以及一条 eslint 指令注释缺少理由
安装
下载 main.js / manifest.json / styles.css,放进
<你的库>/.obsidian/plugins/ob-sync/,然后在 Obsidian 里启用。
要求
- Obsidian ≥ 1.8.7
- 笔记同步需要系统 git,仅桌面端;插件安装在移动端也可用
已知限制
- 同步只支持桌面端(移动端没有系统 git)
- 主题:支持绑定库里已装的主题并更新,不支持从仓库新装;不做版本钉选与主题 beta 通道
- 逐文件暂存、diff 查看、行作者等 obsidian-git 的增强功能不在首版范围内
0.1.5
SyncHub 把两件事合在一起:用 git 同步笔记仓库 + 安装社区插件,两者都支持 GitHub 与 Gitee,界面中文优先、英文对等。
⚠️ 这一版需要手动重装
插件改名为 SyncHub,id 从 ob-sync 改为 synchub。
旧名 OBSync 被社区审核以 Plugin name must not include parts of the name "Obsidian" 打回 ——
它以全大写 OBS 开头,正是 "Obsidian" 前三字母的缩写写法。
因为 Obsidian 是按 id 找插件的:
- 安装目录从
.obsidian/plugins/ob-sync/变成.obsidian/plugins/synchub/; data.json(设置 + 跟踪列表)不会自动跟着走 —— 请手动复制到新目录,
否则插件会以默认设置启动;- 旧的
ob-sync/目录请删掉,否则插件列表里会出现两份; - 跨 id 这一跳不能用「检查更新」 —— 自我更新会校验远端 manifest 的 id,
对不上就拒绝写盘(这道守卫本是为了防止覆盖别的插件),所以必须手动重装一次。
你的访问令牌不受影响:它们存在 obsync-token-* 这个密钥 id 下,与插件 id 无关,
所以不需要重新填。
这一版
- 改名与 id 统一:显示名、仓库地址、插件 id 现在都是 SyncHub /
synchub - 修复英文界面的
.gitignore模板:它漏了排除本插件自己的data.json
(中文模板一直有这条)。英文用户初始化仓库时,插件设置会被同步,
导致两台设备互相覆盖设置 —— 正是该模板注释里警告的那个坑 - 修掉两处社区审核打回:SecretStorage 的 API 版本守卫、
以及一条 eslint 指令注释缺少理由
安装
下载 main.js / manifest.json / styles.css,放进
<你的库>/.obsidian/plugins/synchub/,然后在 Obsidian 里启用。
要求
- Obsidian ≥ 1.8.7
- 笔记同步需要系统 git,仅桌面端;插件安装在移动端也可用
已知限制
- 同步只支持桌面端(移动端没有系统 git)
- 主题:支持绑定库里已装的主题并更新,不支持从仓库新装;不做版本钉选与主题 beta 通道
- 逐文件暂存、diff 查看、行作者等 obsidian-git 的增强功能不在首版范围内