Skip to content

fix(desktop): detect default branch changes from remote #514

Merged
AviPeltz merged 6 commits intomainfrom
check-updated-default-branch
Dec 28, 2025
Merged

fix(desktop): detect default branch changes from remote #514
AviPeltz merged 6 commits intomainfrom
check-updated-default-branch

Conversation

@AviPeltz
Copy link
Copy Markdown
Collaborator

@AviPeltz AviPeltz commented Dec 27, 2025

Description

Related Issues

Type of Change

  • Bug fix
  • New feature
  • Documentation
  • Refactor
  • Other (please describe):

Testing

Screenshots (if applicable)

Additional Notes

Summary by CodeRabbit

  • New Features

    • Added a mutation to explicitly refresh and synchronize a project's default branch with the remote.
  • Improvements

    • Workspace creation and Git status operations now return default branch info.
    • Default branch detection now prefers remote-derived values and updates stored project defaults when they differ.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 27, 2025

📝 Walkthrough

Walkthrough

Adds a git utility to refresh the remote default branch and integrates it into project and workspace routers; endpoints now fetch the remote default branch, update stored values when changed, and return the computed default branch to callers.

Changes

Cohort / File(s) Summary
Git Utilities
apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts
New exported `refreshDefaultBranch(mainRepoPath): Promise<string
Projects Router
apps/desktop/src/lib/trpc/routers/projects/projects.ts
Imported refreshDefaultBranch; updated branch listing flow to call it and reconcile project.defaultBranch (update DB if different); added new refreshDefaultBranch publicProcedure mutation returning { success, defaultBranch?, changed?, previousBranch? }.
Workspaces Router
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
Imported refreshDefaultBranch; create and refreshGitStatus mutations now compute/return defaultBranch (using remote value when available) and update project.defaultBranch when it changes.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Router as Projects/Workspaces Router
    participant GitUtil as Git Utility
    participant Remote as Remote Repo
    participant DB as Database

    Client->>Router: request refreshDefaultBranch(id)
    Router->>DB: load project by id
    Router->>GitUtil: refreshDefaultBranch(mainRepoPath)
    GitUtil->>Remote: git remote set-head origin --auto
    GitUtil->>Remote: read refs/remotes/origin/HEAD
    alt origin/HEAD available
        Remote-->>GitUtil: origin/HEAD -> origin/<branch>
        GitUtil-->>Router: remoteDefaultBranch
    else fallback to ls-remote
        GitUtil->>Remote: git ls-remote --symref origin HEAD
        Remote-->>GitUtil: symref output -> <branch>
        GitUtil-->>Router: remoteDefaultBranch (or null)
    end
    Router->>Router: compute effectiveDefaultBranch (remote ?? stored ?? local fallback)
    alt branch changed
        Router->>DB: update project.defaultBranch
        DB-->>Router: OK
        Router-->>Client: { success: true, defaultBranch, changed: true, previousBranch }
    else unchanged
        Router-->>Client: { success: true, defaultBranch, changed: false }
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • CharlieHelps

Poem

🐰 I hopped to the origin, nose full of clues,
Pulled HEAD from afar and followed the cues.
When remote and local at last are aligned,
I nudge the DB gently — peace of branch mind. ✨

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description is largely incomplete. While it marks the PR as a bug fix, all other required sections (Description, Related Issues, Testing, Additional Notes) remain as unfilled template placeholders with no substantive content provided. Fill in the Description section explaining what the bug fix addresses, add Related Issues links if applicable, describe testing steps performed, and include any additional context about the changes.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: detecting default branch changes from remote, which aligns perfectly with the implemented functionality.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch check-updated-default-branch

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29855d9 and e5ae2c6.

📒 Files selected for processing (1)
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@AviPeltz AviPeltz marked this pull request as ready for review December 27, 2025 23:51
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

1072-1078: Align with the more efficient pattern from create mutation.

The default branch resolution logic here differs from the create mutation and is less efficient. If remoteDefaultBranch is truthy but project.defaultBranch is falsy, this code calls getDefaultBranch only to immediately override it with remoteDefaultBranch.

🔎 Proposed refactor for consistency and efficiency
-		let defaultBranch = project.defaultBranch;
-		if (!defaultBranch) {
-			defaultBranch = await getDefaultBranch(project.mainRepoPath);
-		}
-		if (remoteDefaultBranch && remoteDefaultBranch !== defaultBranch) {
-			defaultBranch = remoteDefaultBranch;
-		}
+		const defaultBranch =
+			remoteDefaultBranch ||
+			project.defaultBranch ||
+			(await getDefaultBranch(project.mainRepoPath));

This aligns with the create mutation pattern (lines 76-79) and avoids the unnecessary getDefaultBranch call when remoteDefaultBranch is available.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13bad24 and 29855d9.

📒 Files selected for processing (3)
  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Avoid using any type in TypeScript - maintain type safety unless absolutely necessary

Files:

  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Run Biome for formatting, linting, import organization, and safe fixes at the root level using bun run lint:fix

Files:

  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc
Use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary.
For tRPC subscriptions with trpc-electron, ALWAYS use the observable pattern from @trpc/server/observable instead of async generators, as the library explicitly checks isObservable(result) and throws an error otherwise

Files:

  • apps/desktop/src/lib/trpc/routers/projects/projects.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts
  • apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts
🧬 Code graph analysis (1)
apps/desktop/src/lib/trpc/routers/projects/projects.ts (3)
apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts (2)
  • refreshDefaultBranch (331-366)
  • getDefaultBranch (251-313)
apps/desktop/src/main/lib/local-db/index.ts (1)
  • localDb (85-85)
packages/local-db/src/schema/schema.ts (1)
  • projects (15-40)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (3)
apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts (1)

325-366: LGTM! Well-designed implementation.

The function correctly handles default branch detection with appropriate fallbacks and clear documentation. The strategy of explicitly syncing origin/HEAD via git remote set-head origin --auto is the right approach, as the comments correctly note that git doesn't auto-update this on fetch.

apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (1)

71-87: LGTM! Efficient default branch resolution.

The pattern using short-circuit evaluation correctly prioritizes the remote default branch over cached values, and only falls back to getDefaultBranch when necessary. The DB update logic is also correct.

apps/desktop/src/lib/trpc/routers/projects/projects.ts (1)

260-276: LGTM! Consistent pattern with create mutation.

The default branch resolution logic correctly prioritizes remote over cached values and uses the efficient short-circuit evaluation pattern.

Comment thread apps/desktop/src/lib/trpc/routers/projects/projects.ts
@charliecreates
Copy link
Copy Markdown
Contributor

charliecreates Bot commented Dec 28, 2025

Expand this to see my work.
  • Inspected the createWorkspace mutation in apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts around the createWorktree(...) call to verify the returned shape (workspace, initialCommands, worktreePath, projectId) is unchanged by the new default-branch logic and that tracking via track("workspace_created", ...) is unaffected.
  • Compared refreshGitStatus in apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts on this branch with origin/main via git show to confirm that the PR’s main functional change is extracting default-branch detection/fetching into refreshDefaultBranch while preserving the existing lazy migration for project.defaultBranch and the checkNeedsRebase semantics.
  • Verified that refreshGitStatus previously called getDefaultBranch(project.mainRepoPath) and fetchDefaultBranch(project.mainRepoPath, defaultBranch) directly, and confirmed that the new implementation now routes through refreshDefaultBranch(mainRepoPath) plus fetchDefaultBranch(...), so behavior for projects with and without defaultBranch set should remain consistent aside from the added remote origin/HEAD detection.

@charliecreates
Copy link
Copy Markdown
Contributor

Overall this looks solid. The approach of explicitly syncing origin/HEAD via git remote set-head origin --auto is the right lever for detecting default-branch flips (e.g. mastermain), and I like the separation between:

  • getDefaultBranch() = local/best-effort detection
  • refreshDefaultBranch() = network-backed sync that can return null when offline

A few specific follow-ups that would make this tighter:

  • In apps/desktop/src/lib/trpc/routers/workspaces/workspaces.ts (refreshGitStatus), the default-branch resolution logic is a bit more work than necessary when remoteDefaultBranch is available. You can match the more direct “short-circuit” pattern used elsewhere to avoid calling getDefaultBranch() just to override it right after:

    const defaultBranch =
      remoteDefaultBranch ||
      project.defaultBranch ||
      (await getDefaultBranch(project.mainRepoPath));

    (This also keeps the behavior consistent across create / getBranches / refreshGitStatus.)

  • In apps/desktop/src/lib/trpc/routers/projects/projects.ts, the new tRPC procedure name refreshDefaultBranch reads like it might recurse because it shares the same identifier as the imported helper (refreshDefaultBranch(project.mainRepoPath)). It won’t actually recurse, but it’s a readability trap. I’d rename one side, e.g. import as refreshRemoteDefaultBranch or rename the procedure to syncDefaultBranch.

  • In apps/desktop/src/lib/trpc/routers/workspaces/utils/git.ts (refreshDefaultBranch), consider a timeout / bounded wait for the networked git calls (remote set-head, ls-remote). If the network is slow/hung, this can block user actions (branch picker, status refresh, workspace create). Even a conservative timeout + “return null and use cached value” fallback would preserve the UX you’re aiming for.

  • PR hygiene: the PR template’s Testing section is empty. Since this is a behavior change that depends on remote state, it’d help reviewers if you add a quick “how I tested” (even 2–3 bullets: repo with default branch changed, offline case, etc.).

@AviPeltz AviPeltz merged commit 436b5f1 into main Dec 28, 2025
5 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

🧹 Preview Cleanup Complete

The following preview resources have been cleaned up:

Service Status
Neon Database (Neon) ⚠️

Thank you for your contribution! 🎉


Preview resources have been processed for cleanup

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.

1 participant