随笔
人机搭档,稳稳完成一次 Mac 搬家
一套面向长期工作环境的三层迁移方法:保住历史数据与账号、延续 AI Agent 状态,用精选清单重建 ARM 工具链。
从 Intel Mac 换到 M 系列 Mac,我要完整带走个人数据、账号状态,以及多年沉淀下来的工作环境。Codex、Claude Code、Gemini 这些常用 AI Agent,也不能从头配置。
换 Mac 很容易陷入两个极端。
一个极端是“全部迁移”。旧机上有什么,就让迁移工具原样搬到新机。它最省眼前的时间,却可能把 Intel Homebrew、旧驱动、临时装过的命令、失效后台服务和多套互相抢 PATH 的运行时一起带过去。
另一个极端是“全部重装”。新机从零开始,环境最干净;代价是历史任务、浏览器状态、Office 数据、AI Agent 配置和已经稳定使用的账号体系都可能重新折腾一遍。
我不想二选一:有价值的状态尽量原样带走,容易重建的环境在新机上重新装,拿不准的先隔离。具体拆成三层:
| 迁移层 | 真正要保住的内容 | 处理原则 |
|---|---|---|
| 状态层 | 个人数据、项目、账号、密码、用户配置 | 最小变更迁移,逐项验证 |
| Agent 层 | Codex、Claude Code、Gemini 的历史、配置、登录状态 | 保留状态,重装程序和 ARM 运行时 |
| 工具层 | Homebrew、Node、Python、Go、Docker 和日常 CLI | 迁移清单,不迁移旧二进制和缓存 |
这三层分开后,换机才从“一次不可控的大搬家”,变成了三个可以分别验收、分别回退的小任务。
第一层最重要:迁移的不是文件,而是可继续工作的状态
普通文件最好理解:文档、照片、视频和资料,只要完整复制并校验即可。
真正容易漏掉的是那些“不像文件,却决定工作能不能继续”的状态。
比如这台工作台里的个人项目,不只有 Git 仓库里的代码,还包括:
- 尚未提交的修改和本地新增文件;
- 没有进入仓库的素材、构建输入和发布记录;
- 项目之间的交接文档和操作记录;
- 浏览器中的后台入口、账号状态和密码管理;
- 部署需要的凭据体系,以及凭据由谁保管、如何恢复。
只重新 clone 仓库,并不能恢复完整工作现场。反过来,把整个用户目录不加区分地复制过去,也可能把缓存、旧运行时和无效路径一起带走。
所以我先做的不是复制,而是给每类状态指定恢复来源:
| 内容 | 首选恢复方式 | 验收方式 |
|---|---|---|
| 已入库代码 | 从 Git 远端恢复 | 检查分支、远端和构建 |
| 未提交修改 | 单独备份并与仓库状态核对 | 比较修改文件和新增文件 |
| 文档与媒体素材 | 文件级迁移或云盘同步 | 抽查数量、大小和关键文件 |
| 浏览器数据 | 浏览器同步和系统加密迁移 | 打开书签、扩展和常用服务 |
| Office/邮件状态 | 保留用户容器并让应用重新识别 | 检查许可证、邮件、规则和签名 |
| 密码与密钥 | 使用钥匙串或密码管理器的安全通道 | 只验证能否使用,不导出明文 |
这里有一个很重要的边界:验证账号可用,不等于把密码和令牌抄出来。
迁移过程中,我只记录“登录是否有效”“SSH 是否能连接”“应用是否识别原账号”,不把密码、OAuth 凭据、API Key 或私钥内容写进迁移文档,也不让它们出现在命令输出里。
对金融工具和长期账号来说,安全迁移的目标不是得到一份明文秘密清单,而是保证原有的安全保管方式在新机上仍然有效。如果某个账号确实需要重新认证,就把它作为单独的人工步骤,而不是为了追求“完全免登录”降低凭据安全。
我把旧 Intel Mac 留了下来
最小变更迁移必须有回退点。
因此我决定至少半年不清空旧 Mac。旧机不是一份理论上的备份,而是一套仍然可以开机、登录、核对文件和继续工作的完整环境。
新机上的不确定内容也不直接删除,而是移动到按日期命名的隔离区:
记录原路径
记录隔离后的路径
记录处理原因
记录验证结果
保留恢复办法这样做的价值,是把很多“现在必须决定能不能删”的问题推迟到证据足够的时候。先让旧组件退出默认运行链,观察一段时间;如果工作不受影响,再决定永久删除。
真正的永久清理,要等三个条件同时满足:
- 新机已经有独立的完整备份;
- 核心账号和业务流程已经实际跑通;
- 隔离内容经过稳定观察,没有发现依赖。
第二层:AI Agent 要迁移历史和身份,不要迁移 Intel 运行时
Codex、Claude Code、Gemini 这类 AI Agent 比普通软件更难迁移。
它们身上混合了几类完全不同的东西:
- 应用或 CLI 程序;
- Node、Python 等执行环境;
- 本地配置和权限规则;
- 历史会话、任务和项目上下文;
- OAuth 或其他登录状态;
- 缓存、日志和下载的运行时。
如果全部重装,程序很干净,但历史和配置可能断掉;如果全部复制,x64 runtime、旧 npm 全局包和缓存也会进入新机。
我的处理标准是:
| AI Agent 内容 | 是否迁移 | 原因 |
|---|---|---|
| 历史会话与任务状态 | 迁移 | 这是持续工作的上下文 |
| 用户配置、权限和项目映射 | 迁移后复核 | 能减少重新配置,但要排除旧路径 |
| 现有登录状态 | 优先保留并验证 | 尽量避免重复登录,不手工导出令牌 |
| App/CLI 本体 | 安装 ARM/Universal 版本 | 避免继续运行 Intel 二进制 |
| 捆绑 Node、Python 和原生依赖 | 重新安装或让新版本生成 | 必须匹配 Apple Silicon |
| 缓存、日志、旧下载 runtime | 不作为迁移目标 | 可重建,也最容易夹带旧架构 |
这次迁移中,Codex 的历史任务和必要配置被保留下来,但工作区捆绑 runtime 重新核对为 ARM64,旧 x64 runtime 移入隔离区。Claude Code 和 Gemini CLI 也重新落在 ARM Node 工具链上,再检查原有认证状态是否仍然有效。
最后,Codex 和 Claude Code 的登录可以继续使用,Gemini 的运行链也恢复正常,没有因为“环境重建”就把所有 Agent 当成新用户重新配置。
能否免登录,取决于服务端令牌有效期、钥匙串、设备绑定和组织安全策略。我的处理顺序是:
- 迁移受保护的用户状态;
- 安装新架构程序;
- 先验证原登录是否有效;
- 只有认证确实失效时,才走官方重新登录流程。
这个顺序兼顾了便利和安全,也避免为了保存一次登录,去手工复制不该暴露的凭据。
第三层:工具集合应该迁移“清单”,而不是迁移“安装目录”
我的旧 Mac 上积累了很多工具。
有些每天使用,有些只服务过一个项目,有些是排障时临时安装,还有些已经被新工具替代。它们共同混在 Homebrew、npm 全局目录、nvm、pyenv、系统应用目录和各种 Shell 配置里。
如果逐个回忆再安装,成本很高;如果整个目录复制,新系统又会继承过去的混乱。
相对标准、可重复的办法,是把工具环境分成两部分:
工具清单可以迁移,安装结果重新生成。
迁移前先做只读盘点:
brew leaves
brew list --cask
npm list -g --depth=0
which -a node python3 go docker codex如果还使用其他管理器,再补充对应清单,例如 uv、pipx、nvm、pyenv 或容器镜像。这个盘点的目的不是生成一份“全部重装”的命令,而是建立候选集合。
随后把候选工具分成三个优先级:
- P0:每天工作必需,例如 Git、Node、Python、Docker、常用 AI CLI;
- P1:由当前项目明确需要,例如 ffmpeg、Poppler、特定 JDK;
- P2:历史工具、临时工具和用途不明确的应用,先不装。
对于长期稳定使用的 Homebrew 工具,可以整理一份经过人工筛选的 Brewfile;但不应该把旧机的所有 formula 和 cask 原样 dump 后直接恢复。否则“声明式安装”只是把历史垃圾自动化地重装了一遍。
项目依赖则优先交给项目自己的清单:
- Node 项目看
package.json和锁文件; - Python 项目看
pyproject.toml、锁文件或 requirements; - Go 项目看
go.mod; - 容器任务看 Dockerfile 和 Compose 配置。
不迁移 Homebrew Cellar、全局 node_modules、Python 虚拟环境和编译产物。它们看起来能节省下载时间,实际上最容易带入架构不匹配和失效绝对路径。
这套方法还有一个额外好处:新机没有立即重装的工具,往往正是已经不再需要的工具。让真实项目在后续使用中提出需求,比迁移当天凭记忆安装全部软件更准确。
非必须,不启用 Rosetta
遇到旧 Intel 程序无法运行时,最方便的做法是安装 Rosetta。
我没有一开始就这样做,因为兼容层可能把一个应该暴露的环境问题重新变成“勉强能跑”。
如果旧命令因为 PATH 抢占被调用,Rosetta 会让它继续工作,却不会提醒我新机还在使用 x86 工具链。于是我的处理顺序变成:
- 优先安装 ARM64 或 Universal 版本;
- 让
/opt/homebrew和新的版本管理器进入默认 PATH; - 隔离失效的 Intel 入口;
- 只有业务必需且没有原生版本时,再单独评估 Rosetta。
迁移后,旧 /usr/local 中仍残留 Node、Python、Go 和部分 CLI。它们没有立刻造成故障,只是因为 ARM 工具排在前面。
我也没有直接删除整个 /usr/local。其中少量入口仍可能链接到有效的新程序,粗暴清空反而会误伤 Docker 或 kubectl。正确做法是先建立入口所有者清单,再逐项隔离确认无依赖的 x86 内容。
记得做运行态验收
新机迁移完成后,Chrome 一度出现异常高 CPU。
最初很容易怀疑它还在运行 Intel 版本。检查后却发现,Chrome 本身已经包含 ARM64,真正的问题是迁移来的设置关闭了硬件加速。
恢复硬件加速并重启后,CPU 占用回到正常范围。
这件事让我意识到:架构正确,只能证明程序装对了;真实工作正常,才能证明迁移完成了。
因此最终验收不只看版本和二进制架构,还要检查:
- 常用项目能否构建、预览并继续原来的工作流程;
- Codex、Claude Code、Gemini 能否接上历史任务和账号;
- Office、浏览器、IDE 的账号、插件和数据是否完整;
- Docker Client 与 Server 是否为 ARM64;
- Chrome 是否真正启用 GPU;
- Ollama 实际推理是否使用 Apple Silicon 加速;
- 打印机是否真的打印出测试页,而不只是网络可达。
一条命令返回成功,不等于业务已经恢复。应用包含 arm64,也不等于账号、插件和历史数据已经可用。
最后形成的最小变更迁移顺序
回头看,这套方案可以压缩成六个动作。
先在旧机建立可回退现场
- 完成独立备份;
- 保留旧机,不立即抹除;
- 记录项目、账号、Agent 和工具清单;
- 单独保存未提交修改和不在仓库中的素材;
- 标记所有需要人工验证的账号与设备。
再迁移不可重建的状态
- 用户数据、个人项目和工作素材;
- 浏览器、Office 和应用用户容器;
- AI Agent 历史、配置与受保护登录状态;
- 钥匙串或密码管理器中的凭据体系。
在新机重建 ARM 执行环境
- Apple Silicon Homebrew;
- ARM Node、Python、Go、Java 和 Docker;
- ARM/Universal 桌面应用;
- 新架构的 AI CLI 与捆绑 runtime。
用项目和精选清单恢复工具
- P0 工具先装;
- P1 工具由项目依赖触发;
- P2 工具暂缓;
- 不复制 Cellar、全局依赖目录、虚拟环境和缓存。
逐项做真实业务验收
- 数据是否完整;
- 账号是否仍然有效;
- Agent 是否接得上历史;
- 项目和工作环境是否能正常使用;
- 性能、GPU、容器和外设是否正常。
最后才清理
- 不确定内容先隔离;
- 保留原路径和恢复记录;
- 完整备份与稳定期之前不永久删除;
- 旧机至少保留到所有关键任务通过。
换机真正值得迁移的,是工作连续性
这次迁移之后,我不再把换 Mac 理解成“把旧电脑复制到新电脑”。
真正值得迁移的是三样东西:
不可重建的数据,已经形成的账号与 Agent 状态,以及一份能够重新生成工具环境的清晰清单。
程序本体、运行时和缓存反而不应该被过度珍惜。它们越能被重新生成,新机器的环境就越清楚,下一次迁移也越轻松。
最终我留下的一句话是:
迁移状态,重建环境,隔离不确定项,再用真实工作验证结果。
它既避免了从零配置所有账号和 AI Agent,也没有把 Intel 时代多年积累的路径漂移、临时工具和旧依赖完整带进新系统。
这才是我理解的安全、低成本、最小变更迁移。