🤖HermesBlog
Hermes 官方教程 · 第4篇2026/8/9· Easy Understand Hermes Agent

更新与卸载,保持你的 Hermes 最新

Hermes Agent 官方教程第四篇:更新与卸载。升级不丢数据。

给 Hermes 做保养:更新与卸载仪表盘

更新与卸载,保持你的 Hermes 最新

嘿,朋友们!今天咱们来聊聊怎么让 Hermes 始终保持最新状态,以及哪天想卸载了该怎么办。别担心,这比想象中简单多了。

先选对更新方式

不同安装方式,更新方法也不一样,先对号入座:

安装方式 更新方法
托管源码 checkout hermes update,或源码构建桌面端的更新交接
Windows 侧载 MSIX 桌面端 Update 控件和 Windows App Installer
Microsoft Store 包 走 Microsoft Store 更新
macOS 打包应用 桌面端 Update 控件,通过 electron-updater
Docker 镜像 拉取所选镜像,用同样的数据挂载重建容器
Nix 更新 flake/profile 后重新构建
Termux APT pkg update,然后 pkg upgrade hermes-agent

注意:hermes update 不会重写由包管理器拥有的应用文件。PM 管的是依赖,不是应用分发——hermes pm update 是维护者用的 pin 更新命令,不是应用更新器的替代品。

一键更新,就是这么简单

老规矩,先上命令:

hermes update

就这么一行,Hermes 会自动帮你完成所有脏活累活。官方仓库的源码 checkout 现在默认跟踪 stable 通道:也就是最新的已发布 vX.Y.Z GitHub release(绝不包含 draft、prerelease 或 canary tag),并且检出到它确切的那个 commit。hermes update 和桌面端的更新按钮只会在一个 release 到下一个 release 之间移动,绝不会一个 commit 一个 commit 地跳。Fork 和镜像则继续跟踪它们自己的 main 分支。更新会通过 PM 准备依赖,并汇报配置变更和进程重启结果。

想换通道?三条命令搞定:

hermes update --set-channel main     # 改成跟踪 main 上的每个 commit
hermes update --set-channel stable   # 切回只跟 release
hermes update --channel main         # 只这一次跑 main;不保存设置

这个选择按安装保存在 config.yaml 的 update.installs 下。从没选过通道的安装只会向前走:如果一个 checkout 已经比最新 release 还新(比如在这个默认值之前一直跟 main 的),它会停在原地,直到有更新的 release 发布。跑 --set-channel stable 会把 checkout 钉到确切的 release commit 上,哪怕那个 commit 更旧;桌面端会把这次移动称为回滚到该 release,hermes update --check 则会说 checkout 比它新,而不是宣布有新更新。

安装器(install.sh、install.ps1 和 Hermes-Setup)也会把新安装放到最新的 stable release 上。在一个从没选过通道的安装上重跑安装器,只有当该 release 是它 checkout 的后代时才会移动过去;其他 checkout(跟过 main 的,或已经越过该 release 的)会停在原地,由 hermes update 决定这次移动:它会拒绝一个早于该 checkout 已在使用的 session 存储的 release。在一个选了 main 以外通道的安装上重跑,checkout 会留在原地:只有 hermes update 会移动它。想改为安装 main 的尖端,传 --channel main(install.ps1 用 -Channel main,或在 irm | iex 一行命令前设置 HERMES_INSTALL_CHANNEL=main);安装器会像 hermes update --set-channel main 那样保存这个选择。显式的 --commit 钉选仍然生效。Windows Store、MSIX 和打包桌面端安装不受影响,它们的通道是烤进包里的(见下文)。

它还会自动检测新增的配置选项并提示你设置。要是当时手滑跳过了配置提示,别慌,随时可以手动补救:

hermes config check    # 看看缺了哪些配置
hermes config migrate  # 交互式补全配置

关闭被动更新提示

如果你用的是固定版本,或者在非交互环境里跑 Hermes,可以关掉 CLI 的版本和横幅更新检查:

hermes config set updates.check false

这会同时屏蔽缓存的更新提示和被动的更新检查网络请求,默认值是 true。注意:手动执行 hermes update --check 和 hermes update 仍然照常工作,这个开关也不管桌面应用自己的更新器。

更新时到底发生了什么?

你可能会好奇,这行命令背后到底干了啥?其实 Hermes 做了八件事:

  1. 更新前快照:默认会保存一份轻量级状态快照(包括配对数据、定时任务、config.yaml、.env、auth.json 等运行时文件),单个超过 1GiB 的大文件会自动跳过,所以不用担心更新变慢。因为代码切换和网关重启会触及每个 profile,所以安装里的每个 profile 都会各存一份快照到自己的 state-snapshots/ 目录。由 updates.pre_update_backup 控制(默认 quick,full 会打包整个 HERMES_HOME 的 zip,off 关闭)。想要更全面的备份?用 --backup 参数开启完整模式。快照是尽力而为的:万一失败,更新会打印 ⚠ Pre-update snapshot FAILED 警告然后继续,不会卡住你。

  2. 拉取代码:应用配置好的源码分支或 stable release tag,并更新子模块。在 Linux 和 macOS 上,所有从这个安装跑起来的网关会在 checkout 第一次被改动之前立刻暂停(见下方“更新期间的网关停机”);如果这次更新没什么可应用的,或者在改动 checkout 之前就失败了,那什么都不会停。

  3. 语法校验 + 自动回滚:这是最贴心的设计!拉完代码后,Hermes 会立刻编译每次启动 hermes 都会导入的 9 个关键文件。万一发现语法错误(比如合并冲突残留、文件被意外截断),它会自动回滚,保证你的终端永远能用:把 checkout 重置回拉取前运行的那个 commit(git reset --hard <pre-pull-sha>);如果这次更新是从分离检出或停靠的功能分支切过来的,就用 git checkout --detach <sha> / git checkout <branch> 切回去(实在切不回去的分支,就以同一 commit 分离恢复)。等上游修好后再跑一次 hermes update 就行。通过校验后,更新器会在新拉下来的代码上重新执行自己(update.log 里会看到 === hermes update continued on the pulled code ===),所以后面的步骤不会新旧模块混着跑。要是你一瞬间看到两个 hermes update 进程,那就是它在交接班。

  4. 准备依赖:这一步现在由 PM 负责——它会按新的锁文件、原有 extras 和已启用插件声明的依赖,准备一套完整的 Python 环境,并在发布选定的环境之前先校验一遍。插件不会让更新失败:如果某个插件和新的核心不兼容(比如它要求的 Python 版本、插件清单版本,或依赖冲突装不上),更新会打印 ⚠ Disabled plugin '<name>' in <home>: <reason>,把它写进这次的更新回执里并继续跑,之后插件发了兼容版本再用 hermes plugins enable <name> 打开即可。只有核心自己构建不起来时,这一步才算失败。

  5. 配置迁移:检测新配置项并引导你设置。

  6. 桌面端重建(stage-and-swap):如果 Hermes 桌面应用是从这个 checkout 构建的,它会重新构建,让 GUI 和新代码保持一致。重建会先打包到 apps/desktop/release/ 旁边的临时暂存目录,验证通过后才重命名覆盖旧版本(Windows 上如果实时扫描器短暂占用 release/win-unpacked,会重试几次扛过去)。任何一步失败(Electron 下载损坏、依赖缺失、磁盘满)都会保留旧应用不动、仍可启动;更新会打印一行 ⚠,照常完成剩下的步骤(配置迁移、网关重启)并以 0 退出,回执里留一条 build 待办,下次启动、hermes update 或 hermes desktop --build-only --force-build 会重试重建。在 macOS 上,重建好的包还会用 ditto(保留签名)复制覆盖掉过期的 /Applications/Hermes.app 或 ~/Applications/Hermes.app,这样你从 Finder 和 Dock 点开的版本才和后端一致;如果那份已安装的副本正在运行,更新不会动它,只会提示你退出后再跑一次 hermes update。如果之前更新装好的副本后来被删了(包括拖进废纸篓),更新会按需重建、放回去并告诉你,让 Finder、Dock 和 Spotlight 重新找到 Hermes;hermes uninstall 才会彻底删掉它。在 Windows 上,如果更新是从桌面应用内部完成的(应用在启动时补完一次被中断的更新),重建会被跳过并给出提示:Windows 会锁住正在运行的应用文件,而停掉应用就等于停掉更新。其余步骤照常完成;退出 Hermes Desktop,从终端跑 hermes desktop,或用 Settings → About 里的 Update now,就能重建并重新打开它。

  7. 网关自动重启:在 Linux 和 macOS 上,为更新暂停的网关会在依赖准备好、启动器刷新之后立刻重新拉起,这发生在产品构建之前;Windows 上则在构建之后重启。其他正在运行的网关会在更新完成后刷新。系统服务(systemd/launchd)走服务管理器,手动启动的也会在能对应上 profile 时自动重新拉起。手动启动的 hermes serve / hermes dashboard 后端不一样:更新器会让它们继续跑,请它们的主人自己重启(见“手动后端重启提醒”)。桌面应用自己拉起的后端也归应用自己管。

  8. 多路复用迁移(多 profile 安装):当新代码验证通过后,如果一个安装有两个或更多 profile、且仍然每个 profile 各跑一个网关,在没有阻碍的情况下会被折叠成单个多路复用的默认网关(等同于 hermes gateway migrate --multiplex --yes);如果存在阻碍(比如两个 profile 共用一个 bot token,或某个次要 profile 绑定了没有 /p/<profile>/ 入口的端口),更新会打印阻碍项和修复方法,不做任何改动。单 profile 安装永远不会被触碰。

更新期间的网关停机

在 Linux 和 macOS 上,hermes update 会在第一次改动 checkout 之前停掉所有从这个安装跑起来的网关,等依赖准备好之后再用新代码把这一批原样拉起来(这发生在 Web UI、TUI 和桌面端构建之前,那些构建可能要花几分钟)。这段时间里你的 bot 是在线的:通常就是 git 更新加上依赖同步那一小段窗口。在这之前,网关会一边跑着旧代码,一边被 git 在底下重写文件,那个窗口里它懒加载的任何模块都可能来自新代码。

  • 更新会打印一行说明它暂停了什么(⏸ Paused for the update: hermes-gateway.service),恢复时再打印一行(▶ Restarted paused gateway(s): …)。
  • systemd unit 和 launchd agent 是通过 systemd/launchd 停和启的,所以服务管理器没法在更新中途用旧代码把它们拉起来。你手动启动的网关(hermes gateway run)会被排空,然后用同样的命令行和 Hermes home 在后台重新启动;它的输出会写到那个 home 里的 logs/gateway-update-resume.log,而不是你的终端。
  • 从聊天里发起的 /update 能扛过这次暂停:当更新跑在网关自己的 systemd unit 里时,它会先把自己挪进一个独立的 scope。网关暂停期间问的提示会立刻取默认值,因为没有网关能转发它。
  • 暂停的这批网关会在第一次停止之前记录到 Hermes home 里。如果更新被杀掉,下一条 hermes 命令(或 hermes update)会把这一批原样重新拉起。一个从没改动过 checkout 的失败更新会用旧代码把它们重启。如果 checkout 已经移动之后依赖同步失败,它们会在某次启动同步完依赖后重启。
  • 更新器没法通过它的监管者停掉的网关(s6 或自定义 systemd unit、--external-supervisor、启动了这次更新的 launchd job)会被留着继续跑,更新后再刷新,和以前一样。
  • --no-gateway-restart 什么都不停;网关归你自己管。
  • 暂停永远不会阻塞更新。如果它没法列出、记录或停掉网关,它会把已经停掉的重新拉起、说明情况,然后更新照旧继续,就像这个暂停不存在一样。

打包桌面端是怎么更新的

Windows 侧载应用会检查已注册的 App Installer 源。点 Apply 时,它会先下载 .appinstaller 描述文件,再停掉应用拥有的后端,打开这个本地文件,然后退出,交给 Windows 替换包。包版本变化后,一个分离的 waiter 会尝试自动重启;如果 waiter 注册失败,会给出一个手动重新打开的警告。

macOS 上,apply 会下载 ZIP 更新,并等 Squirrel.Mac 接受签名应用之后才停掉后端。只有这个 apply 流程才会请求安装和重启;普通退出不会安装已下载的更新。下载或校验失败时,后端会继续运行。

Store 包走 Store,而不是上面任一 sideload feed。更新检查损坏或不可用,绝不能被当成“已是最新”。应用和它自带的 base runtime 一起更新;用户数据留在包外。

Stable 和 canary 桌面包是两个独立应用。安装 canary 不会替换 stable,Windows MSIX 上也是如此。每个应用保留自己的桌面状态,并在其构建里烤进的通道内更新;换通道意味着安装另一个应用,而不是改一个设置。canary 图标是黄色背景(深色模式下为深黄),它的 CLI 命令是 hermes-canary。

一次性 commit 包与两个 release 通道以及其他 commit 包都相互独立。它们的红色图标显示构建的短 SHA,hermes-<short-sha> CLI 命令也用这个短 SHA。它们不检查也不安装更新,包括通过 hermes update 或 hermes update --check。它们会说明:

This build doesn’t get updates. Ask the developer who gave it to you for a new build.

独立应用仍然共享同一个 Hermes home 下的 profile、配置和会话。对同一个 profile 跑不同构建不是 schema 隔离:较新的构建可能改动旧构建读不了的存储数据。测试前请备份共享数据。当另一个活着的安装使用同一 profile 时,桌面端和独立 CLI 会给出警告;这是提示,不是锁。桌面端更新后通知按应用隔离,所以启动 canary 不会消耗 stable 的待处理通知。hermes:// URL scheme 仍然共享;最近注册它的应用处理链接。

更新前先看一眼计划

机器上跑了好几个 profile 或服务?更新前可以先跑:

hermes update --plan

它会只读地打印安装类型、各 profile 下正在运行的 Hermes 服务、它们的监管方式和实际运行的代码版本,以及每个服务会怎么重启。手动启动的 hermes serve / hermes dashboard 后端也会列出来(带记录的绑定地址),但重启交给它们的主人,更新器不会去停或重启。镜像或包管理器安装的会直接告诉你该用哪条外部更新命令。这个命令不改任何东西,在活着的集群上跑也安全。

另外,每次 hermes update 都会在 ~/.hermes/logs/update_receipts/ 写一份机器可读的回执(保留最近 20 份,latest.json 永远指向最新那份),记录更新前的集群计划、每一步做了什么、跳过了什么及原因、网关重启结果和最终的版本矩阵。重启阶段之后,更新器还会把每个活着的网关实际运行的代码和新代码对比,打印一份按 profile 的矩阵——还在跑旧代码的网关会被大声点名并给出确切的重启命令,更新也会以非零状态退出,这样自动化就不会把混版本的集群当成健康的。

为什么网关重启可能要等一会儿

重启是“先排空”的:运行中的网关会拒绝新的回合,然后等待进行中的工作(聊天回合、定时任务、API 运行)完成后再退出,上限由 agent.restart_after_turn_timeout 控制(默认 30 分钟),所以长时间运行的任务不会被中途切断。等待期间,更新器每 30 秒会打印网关还在等什么。想立刻停止等待,可以结束或杀掉列出的工作,或者在 config.yaml 里调低 agent.restart_after_turn_timeout(设为 0 会立即进入强制排空)。

不过,比网关活得更久的工作不会拖住重启:已经交给独立 systemd scope(systemd-run --user --scope,systemd 安装下的常见情况)里 worker 的 cron 任务,在网关停止后仍会继续跑,结果由下一个起来的网关从持久队列投递——所以重启照常推进,不用等满整个上限。拿不到自己 scope 的 worker(比如够不到用户 D-Bus 会话,见 cron.require_restart_safe_scope)仍留在网关的 cgroup 里,更新还是会等它,因为重启会把它拦腰砍断。

进阶玩法:源码通道与安装身份

默认跟踪 stable 通道,但如果你想体验测试版或候选版本:

hermes update --install-id
hermes update --set-channel stable
hermes update --channel stable --check
# 或者在这个源码安装里跟踪已发布的 canary commit:
hermes update --set-channel canary
hermes update

--install-id 打印安装身份和路径。--set-channel 只改这个安装的配置,然后退出,不应用更新。--channel 是一次性覆盖。对源码 checkout 来说,显式指定的 --branch 优先级更高。hermes update --check 会把 checkout 和当前通道做对比。

通道名注册在 Cloudflare R2 上的 release archive 里,而不是 Hermes 自带的固定列表。main 记录选择源码分支交付;已发布构建通道选择确切的 Git commit。自定义预览通道用同样的源码命令,比如 hermes update --set-channel pm-preview。发布者必须先创建该通道,更新才能解析它。不可用或无效的记录会报错,而不是回退到 main 或其他 release。切换源码通道不会安装桌面包。

每个安装的订阅保存在配置里的 update.installs 下,所以一个 checkout 的选择不会改变另一个安装的通道。源码构建的桌面端用同一份选择来做检查和更新交接;它不会用默认分支替换已选的 release 通道。

对跟踪分支的源码安装,桌面端会保留当前具名分支,除非存在显式的桌面分支覆盖。分离的 checkout 使用默认分支。没有源码通道探测的老 checkout 早于 release 通道,所以桌面端会通过 git 从 main 更新它们;那次更新会带来探测能力。

打包桌面端的 feed 通道来自它们的构建 tag 和包所有者。切换源码通道不是 MSIX 或 Store 通道切换。Canary 构建可能推进存储数据格式;切回去不是 schema 回滚。切换 release 通道前请先备份数据。

如果你的本地 checkout 停在别的分支,Hermes 会自动暂存未提交的改动、切换到目标分支再拉取。分支不存在?会自动从 origin 创建跟踪。失败也会干净退出,不会把你晾在半路。非 main 分支上会自动跳过 main 专属的 fork-upstream 同步逻辑。

停在功能分支怎么办?

有时候你可能不小心把 checkout 停在了某个功能分支。Hermes 会智能处理:

  • 分支已完全合并:自动切回 main,并告诉你一声。
  • 分支有未合并提交但工作区干净:照样切回 main 继续更新(桌面端更新按钮、网关 /update、定时任务都依赖这个行为),你的提交一个都不会丢,更新后会打印提示和找回命令。
  • 工作区有未提交改动:Hermes 不会碰它,更新标记为 SKIPPED 并给出警告和解决命令。

如果你故意维护自定义分支,可以在 config.yaml 里设置:

updates:
  parked_branch_strategy: update_in_place

这样更新会直接把 origin/main 合并进你的分支,而不是切走。冲突时干净停止,不会搞乱你的代码。想临时改回切换路径,可以用 hermes update --switch-branch。另外,设置 updates.auto_switch_parked_branch: false 可以完全关掉自动切换(跳过警告还是会照常出现)。

非交互更新时的本地改动

在终端里跑 hermes update 时,Hermes 会暂存未提交的源码改动、拉取,然后询问是否恢复——和以前一样,交互式更新没有任何变化。

自动暂存只管源码树里的改动。在扁平安装(git checkout 根目录同时也是 $HERMES_HOME,比如用 HERMES_INSTALL_DIR=$HERMES_HOME 装的,或者老安装器建的)里,profile 的运行时状态(state.db 及其 WAL/SHM 文件、state-snapshots/、backups/、sessions/、cron/jobs.json、cron/*.db、config.yaml、auth.json、memories/、锁和 pid 文件等)都是 checkout 里的未跟踪文件。这些路径被 git 忽略,所以自动暂存不会碰它们,网关更新期间数据库安然无恙。如果你在扁平安装的根目录放了别的未跟踪文件,最好挪出去或加进 .git/info/exclude;任何未跟踪又没被忽略的文件都会被当成源码改动卷进暂存。

但当更新没有终端时(比如桌面/聊天应用的“更新”按钮,或网关触发的更新),没有提示可回答。这时由 updates.non_interactive_local_changes 决定暂存的改动怎么处理:

# ~/.hermes/config.yaml
updates:
  non_interactive_local_changes: stash   # 默认:保留并自动恢复
  # non_interactive_local_changes: discard  # 丢弃本地源码改动
  • stash(默认)——自动暂存、拉取,然后自动把你的改动恢复到更新后的代码上。不会丢失;如果恢复时冲突,会保留在 git stash 里供手动恢复。
  • discard——自动暂存并在拉取后丢弃 stash,让更新总是落在干净的工作区上。只在你从不打算保留 Hermes 源码本地改动的机器上使用。它用的是 stash-drop(不是 git reset --hard + git clean -fd),所以 node_modules、venv、构建产物等被忽略的路径永远不会被碰。

在桌面应用里,这个选项位于 Settings → Advanced → In-App Update Local Changes。

桌面端更新从不自动恢复。 桌面更新器调用的是 hermes update --keep-stash:本地源码改动仍会被暂存以便更新进行,但之后不会重新应用——它们留在 git stash 里,更新日志会打印出恢复用的 git stash apply <ref> 命令。

更新报错怎么办?

拉取时报 not a git repository:当安装的 .git 文件夹还在、但 git 已经不认它时(HEAD 丢失或为空,或 .git 文件指向一个已不存在的文件夹),hermes update 会停下并提示 “This Hermes checkout’s git data is damaged”。更新被杀掉、写入中途崩溃,或同步/杀毒工具动了 .git,都可能造成这种状态。这样的 checkout 上任何更新都没法拉取。因为什么都没写入,更新暂停的网关会用未改动的代码重新拉起。

重跑安装器即可修复:它会把损坏的 checkout 挪到一边,命名为 hermes-agent.broken-<timestamp>(不会删除任何东西),然后重新克隆;你的配置、会话和其他数据都在 checkout 之外,会被保留。报错信息会打印适合你 checkout 的确切命令。默认位置是:

  • Linux / macOS / WSL2:curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash
  • Windows(PowerShell):iex (irm https://hermes-agent.nousresearch.com/install.ps1)

装在别处的 checkout 需要再次传入它的目录(Linux/macOS 用 bash -s -- --dir <path>,Windows 用 -InstallDir <path>),就像打印出来的命令那样;不传的话安装器会去修默认位置。Hermes 恢复正常后,就可以删掉那个 .broken-* 文件夹了。

拉取时报 should_include_obj should only be called on existing objects:Git 2.53 及更新版本在往部分克隆里拉取时,如果某些 pack 文件缺少 .promisor 标记,就可能崩掉。这通常发生在一次过滤拉取把完整或浅克隆变成了部分克隆,或者标记丢了的时候。hermes update 会给这些 pack 补上标记并重试一次拉取,安装器重跑时也会在拉取前补标记。但如果你的安装自带的更新器早于这个修复,就没法拉到修复本身:重跑安装器,或者(关掉 Hermes 后)手动补标记再更新。checkout 位于 Hermes home 下的 hermes-agent(~/.hermes,设置了 HERMES_HOME 就用它;Windows 上是 %LOCALAPPDATA%\hermes,除非设了 HERMES_HOME)。

# macOS / Linux
repo="${HERMES_HOME:-$HOME/.hermes}/hermes-agent"
for p in "$repo"/.git/objects/pack/pack-*.pack; do [ -e "${p%.pack}.promisor" ] || : > "${p%.pack}.promisor"; done
# Windows
$repo = Join-Path ($(if ($env:HERMES_HOME) { $env:HERMES_HOME } else { "$env:LOCALAPPDATA\hermes" })) 'hermes-agent'
Get-ChildItem "$repo\.git\objects\pack\pack-*.pack" | ForEach-Object {
  $m = [IO.Path]::ChangeExtension($_.FullName, '.promisor')
  if (-not (Test-Path -LiteralPath $m)) { New-Item -ItemType File -Path $m | Out-Null }
}

checkout 仍然是部分克隆。别为了绕过崩溃去删 remote.origin.promisor / partialclonefilter:那些只有 release tag 或更新备份才够得到的对象从来没被下载过,非部分克隆随后会在 git gc 时报 bad tree object。如果你已经删了,先把缺失对象拉回来、确认一个不剩,再打开自动清理:

git -C "$repo" rev-list --objects --missing=print --all | grep '^?' | cut -c2- | git -C "$repo" fetch -q --no-tags --stdin origin
git -C "$repo" rev-list --objects --missing=error --all >/dev/null && echo complete
git -C $repo rev-list --objects --missing=print --all | Where-Object { $_.StartsWith('?') } | ForEach-Object { $_.Substring(1) } | git -C $repo fetch -q --no-tags --stdin origin
git -C $repo rev-list --objects --missing=error --all | Out-Null; $LASTEXITCODE   # 0 = complete

部分克隆里 .git 一直变大:安装器的 checkout 是部分克隆,git 按需下载 tree 和 blob,每次按需下载都会写成一个小 pack。hermes update 和 hermes update --check 会用 git gc --auto 把它们合并回去(走 git 自己的 gc.autoPackLimit,默认 50),所以健康的 checkout 基本是空跑。它们还会在那个 checkout 里把 maintenance.commit-graph.enabled、gc.writeCommitGraph、fetch.writeCommitGraph 设为 false,因为对还没见过的 commit 写 commit-graph 会把它们的 tree 全下载一遍。别动这些设置,gc.auto 也保持默认:gc.auto=0 会停掉合并。一个堆了几千个 pack 的 checkout 第一次合并是完整 repack,可能要几分钟;更新开始前会提示,如果超过 20 分钟会停下并打印下面这条命令。想手动合并(关掉 Hermes):

git -C "$repo" -c gc.writeCommitGraph=false gc --auto

卸载

(注:官方文档暂未提供卸载章节,建议直接删除安装目录和 HERMES_HOME 下的配置即可,后续文档更新会补充详细步骤。)


保持更新,让 Hermes 始终跑在最新状态,享受最好的体验!有问题随时回来翻翻文档,咱们下期见!🚀

📖 官方文档

本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › getting-started/updating