mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
feat(desktop): detect and surface gone branches for cleanup
Add `gone` branch detection (upstream tracking ref deleted on remote) to the composer coding rail and the sidebar project tree, plus a bulk archive action for sessions on gone branches. Part 1 — composer "gone" indicator: - Add `_branch_gone()` to `web_git.py` (remote/REST path) and `branchGone()` to `git-review-ops.ts` (Electron local path), both using `git for-each-ref --format=%(upstream:track)`. - Add `gone: boolean` to `HermesRepoStatus` type. - Show amber "gone" badge in `CodingStatusRow` next to the branch name. - Rides existing repo-status refresh edges (cwd change, workspace change tick, busy→idle, window focus) — no new polling. Part 2a — session DB staleness fix: - Re-probe `git_branch`/`git_repo_root` at turn-complete (gateway `_run_prompt_submit` finally block) and on session resume (both deferred and eager paths), using the existing `_persist_session_git_meta` daemon-thread helper. Keeps the session DB's branch column fresh so the sidebar tree and gone-branch cleanup are accurate. Part 2b — sidebar gone-branch detection + cleanup UI: - Add `gone_branches()` to `git_probe.py` (one `for-each-ref` per repo). - Add `gone_fn` parameter to `project_tree.build_tree()` + `_annotate_gone()` helper that marks branch lanes with `gone: True`. - Wire `_gone_branches_for_repo` into the gateway's `_build_project_tree`. - Add `gone?: boolean` to `SidebarSessionGroup` (renderer type). - Show amber "gone" badge on sidebar branch lanes in `WorkspaceHeader`. - Add bulk "Archive sessions" action to `WorkspaceMenu` for gone lanes: confirms, optimistically tombstones, calls `setSessionArchived` per session, surfaces success/failure toasts. - i18n strings for all 4 locales (en, ja, zh, zh-hant). Tests: - `test_status_gone_after_remote_branch_deleted` — E2E with bare remote, push, delete, fetch --prune, verify gone=true. - `test_gone_fn_annotates_branch_lanes` — project tree annotation. - `test_gone_fn_absent_leaves_no_gone_field` — no spurious gone field. - Updated `sampleStatus` in coding-status.test.ts with `gone: false`.
This commit is contained in:
parent
b80b52aa46
commit
db5cbff884
18 changed files with 315 additions and 17 deletions
|
|
@ -54,6 +54,7 @@ def test_status_reports_branch_and_change_counts(client, repo):
|
|||
assert body["branch"] == body["defaultBranch"]
|
||||
assert body["branch"]
|
||||
assert body["detached"] is False
|
||||
assert body["gone"] is False
|
||||
# 1 tracked-modified + 1 untracked = 2 changed paths.
|
||||
assert body["changed"] == 2
|
||||
assert body["untracked"] == 1
|
||||
|
|
@ -69,6 +70,30 @@ def test_status_returns_null_outside_repo(client, tmp_path):
|
|||
assert client.get("/api/git/status", params={"path": str(plain)}).json() is None
|
||||
|
||||
|
||||
def test_status_gone_after_remote_branch_deleted(client, repo, tmp_path):
|
||||
"""A branch whose upstream was deleted on the remote reports ``gone: true``."""
|
||||
# Set up a bare remote and push a feature branch to it.
|
||||
remote = tmp_path / "remote.git"
|
||||
remote.mkdir()
|
||||
_git(remote, "init", "--bare", "-q")
|
||||
_git(repo, "remote", "add", "origin", str(remote))
|
||||
_git(repo, "checkout", "-q", "-b", "feature/merged")
|
||||
_git(repo, "push", "-q", "-u", "origin", "feature/merged")
|
||||
|
||||
# Branch is live on the remote — not gone.
|
||||
body = client.get("/api/git/status", params={"path": str(repo)}).json()
|
||||
assert body["branch"] == "feature/merged"
|
||||
assert body["gone"] is False
|
||||
|
||||
# Delete the remote branch; `git fetch --prune` updates the tracking ref.
|
||||
_git(repo, "push", "-q", "origin", "--delete", "feature/merged")
|
||||
_git(repo, "fetch", "-q", "--prune", "origin")
|
||||
|
||||
body = client.get("/api/git/status", params={"path": str(repo)}).json()
|
||||
assert body["branch"] == "feature/merged"
|
||||
assert body["gone"] is True
|
||||
|
||||
|
||||
def test_review_list_classifies_modified_and_untracked(client, repo):
|
||||
body = client.get("/api/git/review/list", params={"path": str(repo)}).json()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue