Skip to content

fix: use current branch upstream for update checks instead of default branch - #201

Merged
nesquena-hermes merged 2 commits into
nesquena:masterfrom
iRonin:fix/update-checker-branch-aware
Apr 10, 2026
Merged

fix: use current branch upstream for update checks instead of default branch#201
nesquena-hermes merged 2 commits into
nesquena:masterfrom
iRonin:fix/update-checker-branch-aware

Conversation

@iRonin

@iRonin iRonin commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Problem

When the hermes-agent repo is on a feature branch (e.g. feat/terminal-image-preview), the update checker compares HEAD against origin/master:

branch = _detect_default_branch(path)  # always returns "master" or "main"
behind = git rev-list --count HEAD..origin/{branch}

This counts all commits merged into master since the feature branch was created, not actual missing updates. Users on feature branches see inflated "74 updates available" alerts even though their branch is fully up-to-date with its own remote.

Fix

Replaces the hardcoded default branch lookup with the current branch's upstream tracking branch:

upstream, ok = _run_git(["rev-parse", "--abbrev-ref", "@{upstream}"], path)
if ok and upstream:
    compare_ref = upstream  # e.g. "origin/feat/terminal-image-preview"
else:
    compare_ref = f"origin/{_detect_default_branch(path)}"  # fallback

Applied to both:

  1. _check_repo() — the behind-count for the UI badge
  2. _apply_update_inner() — the git pull --ff-only used by the "Apply update" button

Behavior Matrix

Scenario Old New
On main tracking origin/main Compares to origin/main Compares to origin/main (same)
On feat/foo tracking origin/feat/foo Compares to origin/main (wrong) Compares to origin/feat/foo (correct)
New local branch, no upstream Compares to origin/main Compares to origin/main (fallback, same)

Testing

Verified manually against the hermes-agent checkout on a feature branch:

  • Before: 74 updates available (HEAD vs origin/master)
  • After: 0 updates available (HEAD vs origin/feat/terminal-image-preview, fully synced)

Fixes #200

iRonin added 2 commits April 9, 2026 12:05
Add optional HTTPS support controlled by two env vars:
  HERMES_WEBUI_TLS_CERT=/path/to/cert.pem
  HERMES_WEBUI_TLS_KEY=/path/to/key.pem

- Wraps server socket with ssl.SSLContext (min TLSv1.2)
- Dynamic scheme detection for startup messages (http:// vs https://)
- Graceful fallback to HTTP if cert loading fails — server never crashes
  due to bad TLS config, just prints a warning and continues
- Auth cookie Secure flag already set when HTTPS is detected via getpeercert
- 6 end-to-end tests: config flags, HTTPS handshake, HTTP still works,
  fallback on bad paths

Addresses nesquena#191 (HTTPS support issue).
…branch

The update checker in api/updates.py always compared HEAD against
origin/master (or origin/main), which produced false 'N updates
available' alerts when the user is on a feature branch and master has
moved forward with unrelated commits.

Now uses git rev-parse --abbrev-ref @{upstream} to get the current
branch's tracking branch for both the behind-count check and the
apply-update pull command. Falls back to the default branch if no
upstream is set (brand-new local branch with no tracking config).

Fixes nesquena#200.
@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Confirmed valid and the fix is correct.

What the bug is

_detect_default_branch() always returns "master" or "main" regardless of what branch is currently checked out. So HEAD..origin/master counts all commits merged into master since the feature branch was created — not commits the user is actually missing. A user on a week-old feature branch where master has moved 74 commits sees "74 updates available" even if their branch is fully in sync with its own remote.

Fix assessment

Using git rev-parse --abbrev-ref @{upstream} to get the current branch's tracking ref is the right approach. A few things that look good:

  • The fallback to _detect_default_branch() when no upstream is set handles brand-new local branches correctly
  • The fix is applied to both _check_repo() (the behind-count display) and _apply_update_inner() (the pull command) — important that both are updated together, otherwise an "apply update" on a branch-tracked repo would pull from the wrong ref
  • The behavior matrix in the PR description covers the key scenarios accurately

One edge case to consider: if the upstream ref no longer exists on the remote (e.g., a remote feature branch that was deleted after merge), git rev-list HEAD..origin/deleted-branch will error. The existing ok check handles this — it falls back cleanly. Worth noting that the error is logged (or silently caught) so users don't see a confusing failure.

The manual verification (74 → 0 updates) against a real checkout is the most convincing test. Fixes #200. Ready for maintainer review.

@nesquena

nesquena commented Apr 9, 2026

Copy link
Copy Markdown
Owner

Full Review: PR #201 — branch-aware update checker

Thanks @iRonin! Valid bug, correct fix.

Security Audit

Clean. Changes are limited to git command arguments in api/updates.py. No new endpoints, no user-facing input handling changes.

Code Review

The fix is correct — git rev-parse --abbrev-ref @{upstream} returns the tracking branch (e.g. origin/feat/foo) which is then used for both the behind-count and the git pull --ff-only. Falls back to origin/{default_branch} when no upstream is set.

Applied consistently to both _check_repo() (UI badge) and _apply_update_inner() (apply button).

One note on the pull command: The new code does git pull --ff-only <compare_ref> where compare_ref is like origin/feat/foo. The old code did git pull --ff-only origin <branch>. The new form (git pull --ff-only origin/feat/foo) is technically a refspec shorthand that should work, but the canonical form is git pull --ff-only origin feat/foo (remote + branch separately). In practice git handles both, but worth noting.

Stacked Branch Issue

This PR includes the full TLS support from PR #199 (config.py changes, server.py changes, test_tls_support.py). The diff shows 260 additions but only ~30 are the actual update checker fix. This means:

Test Results

512 passed, 0 failed, 41 skipped. No regressions.

Verdict

The update checker fix itself is approved. But please rebase this onto master after PR #199 is merged to avoid shipping bundled changes. The actual fix is only ~30 lines in api/updates.py.

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Rebased onto current master (post #196, #197, #198, #199 merges) and fixed a bug in the _apply_update_inner path.

Bug fixed in the rebase: The original PR passed compare_ref (e.g. origin/feat/foo) directly to git pull --ff-only, but git pull requires the remote and refspec as separate arguments — git pull --ff-only origin feat/foo. Passing origin/feat/foo as a single argument causes git to interpret the whole string as a remote name and fails with "does not appear to be a git repository".

Fix: split upstream.split('/', 1)remote='origin', ref='feat/foo' then call ['pull', '--ff-only', remote, ref]. The _check_repo() path using rev-list and rev-parse is unaffected — those work fine with the origin/branch ref form.

All 561 tests passing. Ready to merge.

@nesquena-hermes
nesquena-hermes merged commit f90be60 into nesquena:master Apr 10, 2026
JKJameson pushed a commit to JKJameson/hermes-webui that referenced this pull request Apr 25, 2026
… branch (nesquena#201)

* feat: optional HTTPS/TLS support via cert and key env vars

Add optional HTTPS support controlled by two env vars:
  HERMES_WEBUI_TLS_CERT=/path/to/cert.pem
  HERMES_WEBUI_TLS_KEY=/path/to/key.pem

- Wraps server socket with ssl.SSLContext (min TLSv1.2)
- Dynamic scheme detection for startup messages (http:// vs https://)
- Graceful fallback to HTTP if cert loading fails — server never crashes
  due to bad TLS config, just prints a warning and continues
- Auth cookie Secure flag already set when HTTPS is detected via getpeercert
- 6 end-to-end tests: config flags, HTTPS handshake, HTTP still works,
  fallback on bad paths

Addresses nesquena#191 (HTTPS support issue).

* fix: use current branch upstream for update checks, not repo default branch

The update checker in api/updates.py always compared HEAD against
origin/master (or origin/main), which produced false 'N updates
available' alerts when the user is on a feature branch and master has
moved forward with unrelated commits.

Now uses git rev-parse --abbrev-ref @{upstream} to get the current
branch's tracking branch for both the behind-count check and the
apply-update pull command. Falls back to the default branch if no
upstream is set (brand-new local branch with no tracking config).

Fixes nesquena#200.
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
… branch (nesquena#201)

* feat: optional HTTPS/TLS support via cert and key env vars

Add optional HTTPS support controlled by two env vars:
  HERMES_WEBUI_TLS_CERT=/path/to/cert.pem
  HERMES_WEBUI_TLS_KEY=/path/to/key.pem

- Wraps server socket with ssl.SSLContext (min TLSv1.2)
- Dynamic scheme detection for startup messages (http:// vs https://)
- Graceful fallback to HTTP if cert loading fails — server never crashes
  due to bad TLS config, just prints a warning and continues
- Auth cookie Secure flag already set when HTTPS is detected via getpeercert
- 6 end-to-end tests: config flags, HTTPS handshake, HTTP still works,
  fallback on bad paths

Addresses nesquena#191 (HTTPS support issue).

* fix: use current branch upstream for update checks, not repo default branch

The update checker in api/updates.py always compared HEAD against
origin/master (or origin/main), which produced false 'N updates
available' alerts when the user is on a feature branch and master has
moved forward with unrelated commits.

Now uses git rev-parse --abbrev-ref @{upstream} to get the current
branch's tracking branch for both the behind-count check and the
apply-update pull command. Falls back to the default branch if no
upstream is set (brand-new local branch with no tracking config).

Fixes nesquena#200.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI: False 'updates available' alert when agent repo is on a feature branch

3 participants