mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
fix(update): widen the remote refspec so --branch can resolve
On a single-branch checkout the scoped fetch updates FETCH_HEAD but not origin/<branch>, so `hermes update --branch <other>` died on the follow-up checkout with "does not exist locally or on origin", and `--check --branch <other>` reported the branch missing from a remote that has it. Widening here means existing installs self-heal on the next update instead of needing a reinstall.
This commit is contained in:
parent
4c602f2e05
commit
50b700c56d
2 changed files with 41 additions and 0 deletions
|
|
@ -10741,6 +10741,27 @@ def _resolve_update_branch(args) -> str:
|
|||
return (getattr(args, "branch", None) or "main").strip() or "main"
|
||||
|
||||
|
||||
def _widen_remote_branches(git_cmd: list) -> None:
|
||||
"""Let the checkout resolve branches other than the one it was cloned on.
|
||||
|
||||
Installer checkouts come from ``git clone --depth 1 --branch main``, which
|
||||
implies ``--single-branch`` and pins ``remote.origin.fetch`` to main. Our
|
||||
scoped ``git fetch origin <branch>`` then updates FETCH_HEAD but never
|
||||
creates ``origin/<branch>``, so ``--branch <other>`` reports the branch as
|
||||
missing from a remote that plainly has it.
|
||||
|
||||
Restoring the wildcard costs no bandwidth — every fetch we issue names its
|
||||
branch, and git only walks the full refspec on a bare ``git fetch``.
|
||||
Best-effort: a failure here just leaves the checkout as it was.
|
||||
"""
|
||||
subprocess.run(
|
||||
git_cmd + ["remote", "set-branches", "origin", "*"],
|
||||
cwd=PROJECT_ROOT,
|
||||
capture_output=True,
|
||||
text=True, encoding="utf-8", errors="replace",
|
||||
)
|
||||
|
||||
|
||||
def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False):
|
||||
"""Implement ``hermes update --check``: fetch and report without installing.
|
||||
|
||||
|
|
@ -10797,6 +10818,7 @@ def _cmd_update_check(branch: str = "main", *, branch_explicit: bool = False):
|
|||
== "true"
|
||||
)
|
||||
depth_args = ["--depth", "1"] if is_shallow else []
|
||||
_widen_remote_branches(git_cmd)
|
||||
|
||||
if branch == "main":
|
||||
print("→ Fetching from upstream...")
|
||||
|
|
@ -12052,6 +12074,7 @@ def _cmd_update_impl(args, gateway_mode: bool):
|
|||
# minutes on a non-single-branch checkout. Fetch only what we update
|
||||
# against.
|
||||
branch = _resolve_update_branch(args)
|
||||
_widen_remote_branches(git_cmd)
|
||||
|
||||
print("→ Fetching updates...")
|
||||
fetch_result = subprocess.run(
|
||||
|
|
|
|||
|
|
@ -852,6 +852,24 @@ def test_cmd_update_fetch_is_scoped_to_target_branch(monkeypatch, tmp_path):
|
|||
assert ["git", "fetch", "origin"] not in recorded
|
||||
|
||||
|
||||
def test_cmd_update_widens_remote_branches_before_fetching(monkeypatch, tmp_path):
|
||||
"""Installer checkouts are single-branch, so a scoped `git fetch origin
|
||||
<branch>` never creates origin/<branch> and `--branch <other>` fails the
|
||||
checkout as missing. Widen the refspec first — free, since the fetch that
|
||||
follows still names its branch."""
|
||||
_setup_update_mocks(monkeypatch, tmp_path)
|
||||
monkeypatch.setattr("shutil.which", lambda name: "/usr/bin/uv" if name == "uv" else None)
|
||||
|
||||
side_effect, recorded = _make_update_side_effect()
|
||||
monkeypatch.setattr(hermes_main.subprocess, "run", side_effect)
|
||||
|
||||
hermes_main.cmd_update(SimpleNamespace())
|
||||
|
||||
widen = ["git", "remote", "set-branches", "origin", "*"]
|
||||
assert widen in recorded
|
||||
assert recorded.index(widen) < recorded.index(["git", "fetch", "origin", "main"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Fetch failure — friendly error messages
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue