My Setting Sync
通过普通 Git 仓库自动同步 VS Code、Cursor 等 VS Code 兼容 IDE 以及它们全部用户 Profiles 的便携配置。插件支持多个 IDE 窗口同时运行:同一 User Data 目录只会选出一个 leader 执行 Git 与 AI 操作,其余窗口作为 follower 转发同步请求。
当前能力
- 一次快照默认 Profile 与全部命名 Profile 的
settings.json、keybindings.json、tasks.json、mcp.json、snippets/ 和 prompts/,以及宿主级已安装扩展清单;Cursor 还会同步用户主目录下的全局 MCP 配置 ~/.cursor/mcp.json。
- 每种宿主单独存放在
.profile-git-sync/hosts/<宿主> 下,互不覆盖。已识别的有 vscode、vscode-insiders、cursor、vscodium、windsurf、antigravity;其他 VS Code 兼容 IDE 在 User Data 布局能解析时,按应用名生成独立宿主目录后启用。宿主目录名取决于应用名,IDE 升级后若应用名改变,会按新名称另建目录、等同首次接入。得不到合法宿主 id 或标准布局(User 目录)的不会启用,避免归到别的宿主名下互相覆盖、反复装卸扩展。
- 快捷键按平台分文件存放(
keybindings.win32.json、keybindings.darwin.json 等),Windows 与 macOS 的快捷键互不覆盖;推送时保留云端其他平台的那份。
- 遵循 IDE 内置同步的
settingsSync.ignoredSettings:其中列出的设置只属于本机,不提交到仓库,写回时也保留本机原值,适合解释器路径、终端配置等机器专属设置。
- 软链接管理的配置文件(dotfiles)写回时写到链接目标,不替换链接本身;本机文件原本是 CRLF 时按 CRLF 写回。
- 支持两种运行模式:备份模式(只上传,不写回本机)与同步模式(双向同步,会写回本机);默认备份模式,可在侧边栏直接切换,切到同步模式前会先确认。
- 同步模式下自动拉取、比较、提交和推送;历史保持线性,不会使用 force push。
- 侧边栏标题栏提供“云端提交历史”:在侧边栏内打开历史页面,逐条显示提交说明、标签和提交时间,可一键回滚到任意一条历史提交,也可以给提交新增或删除标签。回滚以追加新提交的方式推送,不回退分支、不改写远端历史。
- 优先通过 AI 生成中文 commit message;AI 不可用或结果无效时使用固定的中文 Conventional Commit,不阻塞同步。
- 不做内容合并:仓库里永远是某一台机器的完整配置快照。只有本机与云端都改过时才需要用户选一方,选之前两侧都不改写,两份完整配置也会先备份。
- 配置同步仓库地址、分支、Git 提交身份、运行模式和同步间隔参数在同一设备的全部窗口与 Profiles 间保持一致;启用宿主 Settings Sync 后,也会在同类 IDE 的设备间自动恢复。
- 多设备同时修改插件配置时自动以当前机器配置为准,并生成包含双方版本历史的新修订写回宿主 Settings Sync,不阻塞 Profile 配置同步。
- 优先使用 VS Code
chat.utilitySmallModel 指定的小模型,无法使用时回退到 IDE 通过 Language Model API 开放的默认模型,无需配置 API Key;疑似含有明文凭据的配置会被拒绝提交。
- Profile 按名称对应,插件不新建也不删除 Profile:IDE 运行期间 Profile 列表由主进程持有,外部改写会被它覆盖。两侧 Profile 不一致时见下文「Profile 不一致」。
- 任一活动窗口存在未保存的 Profile 配置(包括经「打开用户设置 (JSON)」打开的文件)时暂停同步,保存后由 leader 自动重试,避免其他窗口的旧缓冲区覆盖同步结果。
- follower 会接收 leader 发布的同步进度、结果和上次成功同步时间;leader 窗口关闭后,其余窗口会自动接管定时同步。
- 同步过程不弹通知,状态只出现在状态栏图标和侧边栏概览中,对外只有「已关闭 / 未配置 / 未同步 / 同步中 / 已同步 / 同步失败 / 需要处理」七种;侧边栏保留当前状态和上次成功同步时间,时间在 IDE 重启后保留。
- 同步开关默认关闭,需要在侧边栏显式开启:同步模式下本机没有仓库时首轮同步会整包采用云端配置覆盖本机,不应在用户无感知时发生。关闭后不会自动同步:不创建本地仓库、不访问远程仓库,也不写回本机配置(手动查看云端提交历史与“以本机覆盖云端”不受此限);同步进行中关闭开关会在当前步骤安全结束后停止。
- 开关、上次同步时间和本机与远端的关系存放在扩展运行目录的共享文件中,同一设备的全部窗口与 Profiles 共用一份,但不会同步到其他设备。
- 侧边栏可设置本地检测与远程轮询间隔,默认分别为 10 秒和 300 秒。
同步策略
触发与安全检查
同步开关开启后,IDE 启动、本地 Profile 指纹变化和命令面板中的“立即同步”都会触发同步;同步模式下还会按间隔轮询远程仓库,轮询先用一次 ls-remote 探测,远端分支没有前进就不跑整轮。开关关闭时这些触发一律不执行,“立即同步”会提示先开启同步。同一 User Data 目录中只有 leader 窗口执行 Git、AI 和 Profile 写入操作,follower 窗口只把请求转发给 leader。另一窗口正在执行同步时,当前请求会等待后续重试。侧边栏保存配置后自动同步;本地缓存与远端不同源时,leader 会询问是否废弃缓存:同步模式按云端覆盖本机,备份模式则重新克隆后继续把本机配置备份到云端。
同步开始前会检查全部活动窗口。只要存在未保存的 Profile 配置文档,或有窗口状态无法确认,本轮同步就会暂停,条件恢复后由 leader 重试。插件在创建本机快照后以及写入仓库后都会扫描疑似凭据;命中时停止同步,不写入远程仓库。
择一而不是合并
以下流程只适用于同步模式。备份模式每轮都用本机快照整包覆盖仓库中本宿主的目录,不参与比较,也不进行远程轮询。
插件对配置文件不做任何内容合并(扩展清单除外,见下文「扩展」):仓库里本宿主的配置永远等于某一台机器的完整真实快照,历史保持线性、不会分叉。判断依据是「相对上次成功同步的基准改没改」——基准是上次整轮成功(含推送成功)时两侧的快照指纹,保存在扩展运行目录的共享状态里。
| 本机相对基准 |
云端相对基准 |
处理方式 |
| 未改动 |
未改动 |
两侧都不改写;仓库中若有上次未推送成功的提交仍会补推 |
| 未改动 |
已改动 |
用云端快照整份覆盖本机,本机原配置先备份 |
| 已改动 |
未改动 |
用本机快照整份覆盖仓库并推送 |
| 已改动 |
已改动 |
暂停同步,由用户选择以哪一方为准;选定前两侧都不改写 |
| 没有基准 |
— |
两侧内容一致时直接建立基准;不一致时同样交给用户选择 |
要点:
- 「云端有没有改」按本宿主的快照指纹判定,不看提交号——同一个仓库里另一个宿主(Cursor)推送不会被误判成本宿主有改动。
- 指纹在比较前会把键序归一,两台机器写出的元数据顺序不同不算改动。
- 基准只在整轮成功后前移。推送失败、拉取失败、因 Profile 不一致暂停的轮次都不前移,改动不会因此丢失。
- 本地仓库只是缓存:每轮拉取后直接对齐远端,上次推送失败留下的提交会被丢弃,并由「本机相对基准已改动」在本轮重新生成。
- 采集本机快照之后、写回本机之前若发现本机配置又被改动,本轮放弃写回,稍后重新开始一轮,避免那次改动被覆盖后再也推不上去。
两边都改时的选择
不设超时,也不自动选边。发现两侧都有改动时:
- 状态变为「需要处理」,侧边栏出现「以本机为准 / 以云端为准」两个按钮,leader 窗口同时弹一次确认框(只弹一次,忽略后可随时在侧边栏选择)。
- 提示中会说明差异配置的数量与文件。扩展清单另行合并,不会引起这种暂停。
- 进入暂停时立即把本机与云端两份完整快照存入扩展运行目录的
conflict-backups(只保留最近 5 份),暂停期间本机改动也有副本。
- 选定之后按所选一方整份覆盖另一方;若该轮推送失败,选择会保留到下一轮继续沿用,不会重复询问。
- 工作区与 Profile 的关联关系是本机专属数据,不参与同步。
Profile 不一致
Profile 按名称对应,插件不会新建或删除 Profile。两侧命名 Profile 不一致时,能从基准判断来源的随正常流程传播,其余暂停并交给用户:
| 情况 |
处理方式 |
| 云端有、本机没有,且是本机删掉的 |
视为本机改动,随本机推送从云端删除 |
| 云端有、本机没有,其他情况 |
暂停同步。在本机新建同名 Profile 后,新 Profile 先套用云端配置再继续;也可以确认「从云端删除」 |
| 本机有、云端没有,且是云端删掉的 |
暂停同步。在本机手动删除该 Profile 后自动继续;也可以确认「保留本机 Profile」,它会随本机下次改动重新上传 |
| 本机有、云端没有,其他情况 |
视为本机新建,随本机推送上云 |
暂停时 leader 窗口弹一次确认框,之后可随时在侧边栏处理。首次接入整包采用云端时不暂停:云端多出的 Profile 在状态说明中提示,本机多出的 Profile 原样保留。
AI 只用于生成提交信息,不参与任何配置内容的决定。
提交、应用与失败处理
插件只暂存和提交 .profile-git-sync/hosts/<宿主>,不会操作当前工作区项目的 Git 仓库,也不会 force push。同步模式下,推送成功后才恢复本机 Profile 文件。
扩展清单取自默认 Profile,同步模式下按增删合并,不跟随配置整份择一:
- 本机新装的扩展加进云端,本机卸载的从云端删掉;别的机器删掉的扩展会在本机卸载。
- 云端有、本机从没装上过的扩展(安装失败、还在下载、市场里没有)保留在云端,本机会尝试安装,不会因为一台机器装不上就让所有机器卸载它。
- 两台机器各自新装了不同的扩展时自动合并,不会暂停询问。第一次同步时两侧取并集,只装不卸。
- 插件只向 IDE 发出安装或卸载命令就结束本轮,不等待下载完成;进度可在 IDE 的扩展面板查看,装好后会自动触发下一轮确认。安装失败的扩展在状态说明里列出,本次运行内不再重试,重启 IDE 后会再试一次。
- 是否已安装以扩展清单文件为准,被禁用的扩展也算已安装。
- IDE 的装卸命令只作用于当前窗口的 Profile,因此 leader 窗口不在默认 Profile 时本轮不装卸扩展,等默认 Profile 的窗口同步时再补上。
- 插件刚装好的扩展如果在下一轮同步之前就被你卸载,会被再装一次,再卸载一次即可。
备份模式用本机扩展清单整份覆盖云端,且不写回本机,不会触发扩展装卸。
后台同步没有终端可以回答 SSH 的主机密钥确认或私钥口令,插件默认以 BatchMode=yes 调用 SSH,让这类情况立即失败并提示先在终端完成一次认证;已配置 core.sshCommand、GIT_SSH_COMMAND 或 GIT_SSH 时沿用用户配置。
窗口不安全、独占锁被其他窗口占用等可恢复情况会延迟重试,重试间隔逐步退避;失败原因显示在状态栏与侧边栏,不弹出通知。本轮未完整成功时不会更新“上次成功同步”时间。
推送失败会在本地留下未推送的提交,本轮不更新基准。下一轮拉取时这些提交会被丢弃并重新对齐云端,本机配置仍被判为「相对基准已改动」,据此重新生成快照,因此不会停留在无法恢复的失败状态,改动也不会丢。恢复本机文件时产生的备份保存在扩展运行目录,只保留最近 10 份。
云端历史还原
侧边栏标题栏的历史图标会在侧边栏内打开历史页面,列出仓库中动过本宿主目录的最近 30 条提交,每条显示提交说明、标签、提交时间和短 hash,底部的“加载更多”每次多取 30 条,不设固定条数上限,直到本地没有更早的提交为止。
页面打开时如果本机已有云端记录的缓存,会立即显示列表并在顶部提示“正在刷新”,同时在后台向远端核对分支最新提交与标签;两者都没有变化就不再传输数据,变了才拉取并重新渲染。本机还没有缓存时页面显示加载动画,取回后再渲染。
点某一条右侧的“回滚”并确认后,插件用该提交的快照覆盖本机配置:本机原配置先备份到扩展运行目录,该提交清单里没有的扩展会在本机卸载,随后在远端当前最新提交之上追加一条“还原到 <短 hash>:…”的提交。远端已有历史不会被回退或改写,其他宿主的目录也不受影响。
在某一条上点右键可以新增标签或删除该提交上已有的标签。标签会推送到远端仓库,其他设备刷新历史后同样可见;新增时如果推送失败,本机那份标签会一并撤销,不会留下别处看不到的标签。删除标签会同时删除远端的引用,但不影响提交本身与配置内容。
同步开关关闭时也可以打开历史页面,并支持刷新、标签增删与还原,页面打开后同样会联网核对远端;前提是已填写仓库地址,且本机已有云端记录的缓存。没有缓存时需要先建立本地仓库,请先开启同步。读取本地缓存的列表与“加载更多”不占独占锁,其他窗口正在同步时也能先看到列表,只有联网刷新需要等锁,被占用时保留已显示的列表并提示云端记录暂未刷新。
还原与同步互斥,需要先取得跨窗口独占锁,任意窗口都可以发起。历史快照里有、本机没有的 Profile 不会写回(插件不新建 Profile),但仍随历史快照推上云端,下一轮同步会请你处理;本机独有的 Profile 原样保留。写回前发现本机配置被改动时放弃本轮,不会推送。备份模式同样可以还原,但还原会直接写回本机配置并装卸扩展。
以本机覆盖云端
命令面板与侧边栏标题栏溢出菜单(“…”)中的“以本机覆盖云端”,用本机当前配置整份替换仓库里本宿主的快照,并在远端当前最新提交之上追加一条“以本机覆盖云端”的提交,不使用 force push、不改写远端历史,被覆盖的内容仍可从云端提交历史还原。同步开关开启或关闭、同步模式或备份模式下都可以使用,执行前会弹出确认。
- 云端有、本机没有的 Profile 会从云端删除;扩展清单以本机为准,云端独有的扩展会被删除,其他机器下次同步时会卸载它们。本机采集不到扩展信息时保留云端清单。
- 云端其他平台的快捷键文件(仅限本机也有的 Profile)原样保留。
- 不写回本机配置、不装卸扩展;提交前仍执行凭据扫描,存在未保存的配置窗口时暂停;提交说明固定,不调用 AI。
- 覆盖成功后基准前移到本机快照,待处理的 Profile 差异与“采用云端”标记一并清除。
插件自身配置
仓库地址、分支、Git 提交身份、运行模式和同步间隔参数使用独立的版本化记录,不参与上述 Profile 文件冲突流程。只有一方更新时接受因果关系中较新的版本;多设备并发修改且内容不同时,以当前机器共享的插件配置为准,合并双方版本历史后写回宿主 Settings Sync。旧版本遗留的配置冲突和恢复记录会在启动时静默清理,不再显示恢复备份黄框。profileGitSync.* 设置项不会随 settings.json 提交到仓库,避免与版本化记录互相覆盖。
开发
npm install
npm run check
npm test
npm run package
在 VS Code 或 Cursor 中打开项目后按 F5,会先构建插件,再弹出选择框,可选 VS Code 或 Cursor 作为 Extension Development Host。也可在运行和调试下拉框中直接选「调试 VS Code」或「调试 Cursor」,之后 F5 会沿用该配置。三者都是复合配置:启动宿主的同时把调试器附加到扩展宿主(端口 9229),可以直接在源码上打断点。VS Code 使用隔离 User Data(.debug/vscode/);Cursor 复用本机已登录的 User Data,并打开名为「调试环境」的 Profile,避免弹出登录页、也不把调试写进默认 Profile。若可执行文件不在 PATH 中,可设置 VSCODE_EXECUTABLE 或 CURSOR_EXECUTABLE。需要在 activate 内部打断点时,给 scripts/launch-debug-host.mjs 加 --brk,宿主会等调试器附加后再启动扩展;同时调试两个宿主时用 --inspect-port 错开端口。调试实例会加载本机已安装的扩展,以便使用 Copilot 等扩展提供的默认 AI 模型。
需要验证多窗口时,可在已打开的调试宿主中执行“新建窗口”,并选择不同 Profile;这些窗口共享同一个隔离 User Data,适合观察 leader/follower 状态。
生成的 my-setting-sync-<版本号>.vsix 可通过 VS Code、Cursor 或其他 VS Code 兼容 IDE 的“从 VSIX 安装”功能安装。
使用
打开活动栏中的“配置同步”,填写配置同步仓库和分支。这个仓库固定克隆在扩展全局存储中,插件不会读取或修改当前工作区项目的 .git。Git 用户名和邮箱是可选项:留空时继承本机 Git 配置,填写时只覆盖配置同步仓库的提交身份;SSH 密钥或 HTTPS 凭据始终使用本机 Git 配置。提交信息优先使用 chat.utilitySmallModel 配置的模型;该设置为空或模型未向扩展开放时,回退到当前 IDE 暴露的默认模型。宿主没有开放模型或 AI 返回无效结果时,插件自动使用固定的提交信息并继续同步;配置内容的取舍与 AI 无关。提交信息前会统一加上 [设备名] 前缀(取自操作系统的主机名),便于在多台机器间区分改动来源。
插件配置在同一 User Data 下使用共享版本记录,因此默认 Profile、命名 Profile 和多个窗口会自动收敛到同一版本。跨设备自动恢复需要在各设备登录同一 VS Code 或 Cursor 账号并开启 Settings Sync;VS Code 与 Cursor 使用各自的同步账号和宿主目录,不保证跨宿主互通。仓库地址可以进入 Settings Sync,但包含用户名密码或 Token 的 URL 会被拒绝;SSH 密钥和 Credential Manager 凭据不会同步。建议 VS Code 在开启内置 Settings Sync 时保持备份模式,Cursor(或其他无内置同步的宿主)再切到同步模式,并分别使用不同仓库。
建议使用 SSH 或系统 Git Credential Manager 管理 Git 凭据,不要把凭据写进仓库 URL。插件会在 IDE 启动完成后自动激活,但仍需要应用到所有 Profiles;否则仅打开未安装该扩展的 Profile 时,不会有实例负责自动同步或参与多窗口安全检查。
同步边界
“全部配置”指可跨设备迁移的用户 Profile 配置。扩展不会同步登录凭据、SecretStorage、缓存、工作区存储、机器专属路径和远程开发环境状态;唯一额外进入宿主 Settings Sync 的扩展状态,是经过校验且不含凭据的版本化插件配置。VS Code 没有公开的“枚举并恢复所有 Profiles”扩展 API,因此本项目使用带格式校验的磁盘适配器;IDE 升级后应先在测试仓库验证兼容性。