From 802d8f1e8c1fa3ed2209eef4fbda6835cd294589 Mon Sep 17 00:00:00 2001 From: Alex Blank Date: Sun, 24 May 2026 10:25:01 +0000 Subject: [PATCH] fix: strip remote prefix from branch names in list_branches Git branch -a --format=%(refname:short) returns remote branches as 'origin/branch-name', not 'remotes/origin/branch-name'. The code was only filtering 'remotes/' prefix, causing clone to fail with branch names like 'origin/feat/foo'. Now properly detects remote names using 'git remote' and strips the remote prefix (e.g., 'origin/') from branch names. --- .stoneforge/sync/elements.jsonl | 3 +-- apps/api/src/utils/git_files.py | 34 +++++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/.stoneforge/sync/elements.jsonl b/.stoneforge/sync/elements.jsonl index cac5e97..2025236 100644 --- a/.stoneforge/sync/elements.jsonl +++ b/.stoneforge/sync/elements.jsonl @@ -1,2 +1 @@ -{"id":"el-7z8w","type":"entity","createdAt":"2026-05-24T09:44:33.965Z","updatedAt":"2026-05-24T10:09:33.794Z","createdBy":"el-0000","tags":[],"metadata":{"agent":{"agentRole":"worker","workerMode":"ephemeral","sessionStatus":"idle","provider":"opencode","model":"moonshotai/kimi-k2.6","channelId":"el-4uqv","lastActivityAt":"2026-05-24T10:09:33.793Z","sessionHistory":[{"id":"session-mpjm8gr8-0006-siku","providerSessionId":"ses_1a689e409ffea1AaKRRY2e7GYP","status":"terminated","workingDirectory":"/home/alex/projects/headquarter","startedAt":"2026-05-24T10:09:33.183Z","endedAt":"2026-05-24T10:09:33.794Z"},{"id":"session-mpjm82gt-0005-5mkq","providerSessionId":"ses_1a68a2c40ffevEmnFz7bp7IxCo","status":"terminated","workingDirectory":"/home/alex/projects/headquarter","startedAt":"2026-05-24T10:09:14.696Z","endedAt":"2026-05-24T10:09:15.313Z"},{"id":"session-mpjm3g7e-0004-65qz","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:05:38.734Z","endedAt":"2026-05-24T10:05:40.357Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjm3byo-0003-i7md","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:05:33.735Z","endedAt":"2026-05-24T10:05:37.855Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjm36ik-0002-0oqz","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:05:26.689Z","endedAt":"2026-05-24T10:05:30.342Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjlycat-0009-04ss","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:01:40.882Z","endedAt":"2026-05-24T10:01:44.511Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjly8fj-0008-vacl","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:01:35.851Z","endedAt":"2026-05-24T10:01:40.884Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjly4kq-0007-y15i","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:01:30.861Z","endedAt":"2026-05-24T10:01:35.493Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjll5q9-0006-51uj","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T09:51:25.805Z","endedAt":"2026-05-24T09:51:29.476Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjll1vs-0005-zvvm","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T09:51:20.806Z","endedAt":"2026-05-24T09:51:25.807Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjlky0l-0004-ou7e","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T09:51:15.818Z","endedAt":"2026-05-24T09:51:20.807Z","terminationReason":"Process no longer alive (PID check)"},{"id":"session-mpjlkqcm-0003-sv67","providerSessionId":"ses_1a69abe62ffe3VhShFnsV1mp1b","status":"terminated","workingDirectory":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","worktree":"/home/alex/projects/headquarter/.stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T09:51:08.709Z","endedAt":"2026-05-24T09:51:15.831Z","terminationReason":"Process no longer alive (PID check)"}],"sessionId":"ses_1a689e409ffea1AaKRRY2e7GYP"}},"name":"e-worker-2","entityType":"agent"} -{"id":"el-18lc","type":"task","createdAt":"2026-05-24T10:07:25.455Z","updatedAt":"2026-05-24T10:09:13.314Z","createdBy":"el-0000","tags":[],"metadata":{"orchestrator":{"assignedAgent":"el-7z8w","branch":"agent/e-worker-2/el-18lc-remove-tunnel-functionality-an","worktree":".stoneforge/.worktrees/e-worker-2-remove-tunnel-functionality-an","startedAt":"2026-05-24T10:09:13.314Z"}},"title":"Remove tunnel functionality and ui from terminal sessions","status":"open","priority":3,"complexity":3,"taskType":"task","assignee":"el-7z8w"} +{"id":"el-2jua","type":"entity","createdAt":"2026-05-24T09:44:24.375Z","updatedAt":"2026-05-24T10:16:57.542Z","createdBy":"el-0000","tags":[],"metadata":{"agent":{"agentRole":"director","sessionStatus":"running","provider":"opencode","model":"openai/gpt-5.5","channelId":"el-2vpd","lastActivityAt":"2026-05-24T10:16:57.540Z","sessionHistory":[{"id":"session-mpjlz79g-0001-9tz4","providerSessionId":"ses_1a689e409ffea1AaKRRY2e7GYP","status":"terminated","workingDirectory":"/home/alex/projects/headquarter","startedAt":"2026-05-24T10:02:20.170Z","endedAt":"2026-05-24T10:16:54.212Z"},{"id":"session-mpjlckjf-0001-cifg","status":"terminated","workingDirectory":"/home/alex/projects/headquarter","startedAt":"2026-05-24T09:44:44.286Z","endedAt":"2026-05-24T09:47:52.845Z"}]}},"name":"director","entityType":"agent"} diff --git a/apps/api/src/utils/git_files.py b/apps/api/src/utils/git_files.py index 147b655..a535d5e 100644 --- a/apps/api/src/utils/git_files.py +++ b/apps/api/src/utils/git_files.py @@ -289,19 +289,37 @@ def list_branches(repo_path: str) -> tuple[list[BranchInfo], str]: branches: list[BranchInfo] = [] default_branch = "main" + # Get list of remote names to properly filter remote tracking branches + try: + remote_output = _run_git_command(repo_path, "remote") + remote_names = {r.strip() for r in remote_output.strip().split("\n") if r.strip()} + except RuntimeError: + remote_names = set() + for line in output.strip().split("\n"): if not line: continue branch_name = line.strip() - # Skip remote tracking branches (they start with remotes/) - if branch_name.startswith("remotes/"): - # Extract just the branch name part - parts = branch_name.split("/", 2) - if len(parts) >= 3: - branch_name = parts[2] - else: - continue + + # Skip detached HEAD pointer + if branch_name == "HEAD": + continue + + # Skip remote tracking branches - they appear as "origin/branch-name" + # Check if first part is a remote name + if "/" in branch_name: + first_part = branch_name.split("/", 1)[0] + if first_part in remote_names: + # Extract just the branch name part (after "origin/") + branch_name = branch_name.split("/", 1)[1] + elif branch_name.startswith("remotes/"): + # Handle "remotes/origin/branch-name" format + parts = branch_name.split("/", 2) + if len(parts) >= 3: + branch_name = parts[2] + else: + continue # Skip duplicates if any(b.name == branch_name for b in branches):