fix: solve #2516 — push/fetch respects branch tracking remote instead of hardcoding origin#2517
fix: solve #2516 — push/fetch respects branch tracking remote instead of hardcoding origin#2517github-actions[bot] wants to merge 1 commit into
Conversation
…ding origin (#2516) Push and fetch operations always targeted "origin", ignoring the branch's actual tracking remote. This broke fork PR review workflows where `gh pr checkout` sets the upstream to a contributor's fork remote. - Add `getTrackingRemote()` helper that reads `@{upstream}` and extracts the remote name via `parseUpstreamRef()` - Update `pushWithSetUpstream()` to accept optional remote, defaulting to the tracking remote - Update `fetchCurrentBranch()` to fetch from the tracking remote - Add reproduction tests verifying remote resolution for fork scenarios Closes #2516
There was a problem hiding this comment.
3 issues found across 2 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/desktop/src/lib/trpc/routers/changes/git-operations.test.ts">
<violation number="1" location="apps/desktop/src/lib/trpc/routers/changes/git-operations.test.ts:138">
P2: The fallback test does not assert that the resolved remote is "origin", so it cannot catch regressions in fallback behavior.</violation>
<violation number="2" location="apps/desktop/src/lib/trpc/routers/changes/git-operations.test.ts:156">
P2: These tests are tautological: they build expected push/fetch args inline instead of calling the actual git-operation helpers, so they don’t verify the bug fix path.</violation>
</file>
<file name="apps/desktop/src/lib/trpc/routers/changes/git-operations.ts">
<violation number="1" location="apps/desktop/src/lib/trpc/routers/changes/git-operations.ts:43">
P2: Do not swallow all errors when resolving tracking remote; unexpected git failures are silently converted to `origin`, masking real failures and risking pushes/fetches to the wrong remote.
(Based on your team's feedback about avoiding empty catch blocks that hide failures.) [FEEDBACK_USED]</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
| test("getTrackingRemote logic: falls back to origin when no upstream is set", () => { | ||
| // When parseUpstreamRef returns null (no upstream configured), | ||
| // getTrackingRemote should fall back to "origin" | ||
| const parsed = parseUpstreamRef(""); | ||
| expect(parsed).toBeNull(); | ||
| // Fallback behavior: when parsed is null, getTrackingRemote returns "origin" | ||
| }); |
There was a problem hiding this comment.
P2: The fallback test does not assert that the resolved remote is "origin", so it cannot catch regressions in fallback behavior.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/lib/trpc/routers/changes/git-operations.test.ts, line 138:
<comment>The fallback test does not assert that the resolved remote is "origin", so it cannot catch regressions in fallback behavior.</comment>
<file context>
@@ -91,3 +92,90 @@ describe("sync operation logic", () => {
+ expect(parsed?.remoteName).not.toBe("origin");
+ });
+
+ test("getTrackingRemote logic: falls back to origin when no upstream is set", () => {
+ // When parseUpstreamRef returns null (no upstream configured),
+ // getTrackingRemote should fall back to "origin"
</file context>
| test("getTrackingRemote logic: falls back to origin when no upstream is set", () => { | |
| // When parseUpstreamRef returns null (no upstream configured), | |
| // getTrackingRemote should fall back to "origin" | |
| const parsed = parseUpstreamRef(""); | |
| expect(parsed).toBeNull(); | |
| // Fallback behavior: when parsed is null, getTrackingRemote returns "origin" | |
| }); | |
| test("getTrackingRemote logic: falls back to origin when no upstream is set", () => { | |
| const upstreamRef = ""; | |
| const parsed = parseUpstreamRef(upstreamRef); | |
| const remote = parsed?.remoteName ?? "origin"; | |
| expect(remote).toBe("origin"); | |
| }); |
| const branch = "feature-branch"; | ||
|
|
||
| // The push command should use the tracking remote | ||
| const pushArgs = ["--set-upstream", remote, `HEAD:refs/heads/${branch}`]; |
There was a problem hiding this comment.
P2: These tests are tautological: they build expected push/fetch args inline instead of calling the actual git-operation helpers, so they don’t verify the bug fix path.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/lib/trpc/routers/changes/git-operations.test.ts, line 156:
<comment>These tests are tautological: they build expected push/fetch args inline instead of calling the actual git-operation helpers, so they don’t verify the bug fix path.</comment>
<file context>
@@ -91,3 +92,90 @@ describe("sync operation logic", () => {
+ const branch = "feature-branch";
+
+ // The push command should use the tracking remote
+ const pushArgs = ["--set-upstream", remote, `HEAD:refs/heads/${branch}`];
+
+ expect(pushArgs).toEqual([
</file context>
| if (parsed) { | ||
| return parsed.remoteName; | ||
| } | ||
| } catch { |
There was a problem hiding this comment.
P2: Do not swallow all errors when resolving tracking remote; unexpected git failures are silently converted to origin, masking real failures and risking pushes/fetches to the wrong remote.
(Based on your team's feedback about avoiding empty catch blocks that hide failures.)
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/lib/trpc/routers/changes/git-operations.ts, line 43:
<comment>Do not swallow all errors when resolving tracking remote; unexpected git failures are silently converted to `origin`, masking real failures and risking pushes/fetches to the wrong remote.
(Based on your team's feedback about avoiding empty catch blocks that hide failures.) </comment>
<file context>
@@ -31,15 +31,31 @@ async function hasUpstreamBranch(git: SimpleGit): Promise<boolean> {
+ if (parsed) {
+ return parsed.remoteName;
+ }
+ } catch {
+ // No upstream configured, fall back to origin
+ }
</file context>
|
Closing as stale: bot PR created 3+ weeks ago with no iteration since. Referenced issue remains open — re-attempt from a fresh branch if a fix is still wanted. Bulk audit 2026-05-06. |
Summary
pushWithSetUpstream()andfetchCurrentBranch()ingit-operations.tshardcoded"origin"as the remote for all push/fetch operations. When reviewing fork PRs viagh pr checkout, the branch tracks a fork remote (not origin), so pushes went to the wrong remote.getTrackingRemote()helper that reads the branch's@{upstream}ref and extracts the actual remote name using the existingparseUpstreamRef()utility, falling back to"origin"when no upstream is configured.pushWithSetUpstream()now accepts an optionalremoteparam, defaulting to the tracking remotefetchCurrentBranch()now fetches from the tracking remote instead of hardcoded originTest plan
git-operations.test.tsverifying:parseUpstreamRefcorrectly extracts fork remote nameschanges/router continue to passCloses #2516
Summary by cubic
Use the branch’s tracking remote for push and fetch instead of hardcoding
origin. Fixes fork PR checkouts (gh pr checkout) so commands target the contributor’s fork. Fixes #2516.getTrackingRemote()to read@{upstream}and parse viaparseUpstreamRef; falls back toorigin.pushWithSetUpstream()(optionalremote, defaults to tracking remote) andfetchCurrentBranch()to use the tracking remote.Written for commit e440579. Summary will update on new commits.