Skip to content

fix: invalidate update check cache when HEAD moves (e.g. git pull) - #9670

Closed
kshitijk4poor wants to merge 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/update-check-head-aware-cache
Closed

kshitijk4poor wants to merge 1 commit into
NousResearch:mainfrom
kshitijk4poor:fix/update-check-head-aware-cache

Conversation

@kshitijk4poor

Copy link
Copy Markdown
Contributor

Problem

check_for_updates() cached the "commits behind" count in ~/.hermes/.update_check with a 6-hour TTL based purely on timestamp. When a user ran git pull manually, HEAD moved forward but the banner still showed the stale "X updates available" count until the 6-hour cache expired.

hermes update worked correctly because it explicitly deletes the cache file via _invalidate_update_cache(). But any manual git operation that moved HEAD (pull, checkout, rebase) left the stale cache in place.

Fix

Store the local HEAD commit hash in the .update_check cache file alongside the existing timestamp and behind count. On each call to check_for_updates():

  1. Run git rev-parse HEAD (~5ms, cheap) to get current HEAD
  2. Compare against cached HEAD hash
  3. If they differ → treat cache as stale, re-fetch and recount
  4. If they match and timestamp is fresh → return cached value (fast path)

Cache logic after fix:

Condition Behavior Subprocess calls
Fresh timestamp + HEAD matches Cache hit 1 (rev-parse)
Expired timestamp OR HEAD changed Re-fetch + recount 3 (rev-parse + fetch + rev-list)
rev-parse fails Falls back to time-only caching 0 on cache hit

Backward compatibility:

Old cache files without the head key get a one-time invalidation and rewrite with the HEAD hash on first launch after this update.

Changes

  • hermes_cli/banner.py — HEAD-aware cache invalidation in check_for_updates()
  • tests/hermes_cli/test_update_check.py — Updated existing tests + added test_check_for_updates_head_changed_invalidates_cache

Test plan

  • python -m pytest tests/hermes_cli/test_update_check.py -v — 10 tests pass
  • E2E verified: old cache without head key → invalidated and rewritten; same HEAD → cache hit in 8ms; simulated HEAD change → re-fetched correctly

The update check cached the 'commits behind' count with a 6-hour TTL
based purely on timestamp. When a user ran git pull manually, HEAD
moved forward but the banner still showed the stale count until the
cache expired. hermes update worked because it explicitly deleted the
cache file.

Fix: store the local HEAD hash in the .update_check cache. On each
check, compare current HEAD against the cached value. If they differ
(git pull, checkout, rebase, etc.), treat the cache as stale and
re-fetch. The rev-parse call is ~5ms so the fast path (cache hit)
remains fast.

Backward compat: old cache files without the head key get a one-time
invalidation and rewrite with the HEAD hash.
@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have comp/cli CLI entry point, hermes_cli/, setup wizard labels Apr 26, 2026
@alt-glitch

Copy link
Copy Markdown

Likely duplicate of #11210 — same fix: invalidate 6h update-check cache when HEAD hash changes after external git pull. Also related to #5359, #11327, #11007.

@teknium1 teknium1 added the area/install-update Installer, updater, packaging, wheels, doctor label Jul 19, 2026
@kshitijk4poor
kshitijk4poor deleted the fix/update-check-head-aware-cache branch August 5, 2026 07:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/cli CLI entry point, hermes_cli/, setup wizard P3 Low — cosmetic, nice to have type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants