Skip to content

feat(grove): custom base branch per project#55

Merged
bang9 merged 21 commits intobang9:mainfrom
DongGukMon:dgmon-custom
Mar 30, 2026
Merged

feat(grove): custom base branch per project#55
bang9 merged 21 commits intobang9:mainfrom
DongGukMon:dgmon-custom

Conversation

@DongGukMon
Copy link
Copy Markdown
Contributor

@DongGukMon DongGukMon commented Mar 28, 2026

Summary

  • 프로젝트별 base branch를 설정할 수 있는 기능 추가
  • 설정된 base branch에서 새 worktree가 분기되도록 변경
  • sidebar에서 source 항목의 ⇄ 버튼으로 searchable branch dropdown을 열어 변경 가능
  • config.json에 영속 저장, 기존 worktree에는 영향 없음

Changes

Backend (Rust)

  • ProjectEntry/Projectbase_branch: Option<String>, resolved_default_branch: String 필드 추가
  • get_remote_branches, set_base_branch Tauri command 추가
  • add_worktree_impl에서 config base branch 우선 사용

Frontend (React/TypeScript)

  • BranchSelector searchable dropdown 컴포넌트 (portal 기반, overflow 안전)
  • DefaultBranchItem에 branch switch 버튼 통합 (SidebarLeafItem 패턴)
  • setBaseBranch Zustand store action + IPC wrapper
  • resolvedDefaultBranch는 항상 git remote default를 반환, baseBranch는 사용자 오버라이드
image

Adds baseBranch/resolvedDefaultBranch to Project TypeScript type,
IPC wrappers for getRemoteBranches and setBaseBranch, Zustand store
action, BranchSelector searchable dropdown component, and integrates
branch selection into DefaultBranchItem using main's SidebarLeafItem
architecture.
Use createPortal to render the dropdown at document.body with fixed
positioning based on the trigger element's bounding rect, so it is
not clipped by parent overflow containers in the sidebar.
- Show actual branch name in default option (e.g. "main (default)")
  instead of generic "Auto-detect (default)"
- Fix sidebar not updating immediately after changing base branch by
  also updating resolvedDefaultBranch in the store
- Add (source) label next to branch name in sidebar
resolvedDefaultBranch now ignores user-set baseBranch and always
reflects the actual git remote default. Sidebar displays
baseBranch ?? resolvedDefaultBranch. The dropdown default option
correctly shows the git default (e.g. "dev (default)") even when
the user has overridden the base branch to something else.
Replace clickable branch name with a dedicated ChevronDown button
placed between (source) label and the refresh button. Shows on
hover, positioned via the status slot in SidebarLeafItem.
Use ArrowLeftRight icon inline after "(source)" text instead of
in the status slot. Shows on hover, conveys branch switching intent.
Place ArrowLeftRight button in the action slot alongside the refresh
button. Add cursor-pointer to both buttons.
Copy link
Copy Markdown
Owner

@bang9 bang9 left a comment

Choose a reason for hiding this comment

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

Code Review

전반적으로 구조가 잘 잡혀 있고, 기존 패턴(SidebarLeafItem, Tauri command, Zustand store)을 잘 따르고 있습니다.
인라인 코멘트들 확인 부탁드려요.

주요 지적 사항

성능 (High)

  • remote_default_branch 이중 호출 — 프로젝트당 git subprocess 추가
  • git fetch origin throttle 미적용 — 기존 maybe_fetch_source_remote 패턴 우회

동작 안정성

  • stale base_branchadd_worktree_impl에서 fallback 없음

테스트

  • 새 동작에 대한 테스트가 0건입니다. 특히 아래 항목은 추가가 필요합니다:
    • set_base_branch_impl happy path / invalid branch 거부 / None 초기화
    • add_worktree_impl이 설정된 base_branch를 실제로 사용하는지 (PR 핵심 동작)
    • config round-trip (serde 영속성)
  • Rust 쪽에 TestHome, create_bare_remote 패턴이 이미 있으므로 작성이 수월할 것입니다.

Comment thread grove/grove-core/src/git_project.rs
Comment thread grove/grove-core/src/git_project.rs Outdated
Comment thread grove/grove-core/src/git_project.rs Outdated
Comment thread grove/src/components/sidebar/BranchSelector.tsx Outdated
Comment thread grove/src/components/sidebar/BranchSelector.tsx Outdated
Comment thread grove/src/components/sidebar/BranchSelector.tsx Outdated
@bang9
Copy link
Copy Markdown
Owner

bang9 commented Mar 29, 2026

Code Review Summary

전반적으로 구조가 잘 잡혀 있고, 기존 패턴(SidebarLeafItem, Tauri command, Zustand store)을 잘 따르고 있습니다.
아래에 개별 코멘트로 지적 사항들을 남깁니다.

Comment thread grove/src/lib/platform/tauri.ts
Comment thread grove/src/components/sidebar/BranchSelector.tsx
Performance:
- Deduplicate remote_default_branch() call in project_from_entry by
  passing the resolved value to check_source_behind_remote
- Use maybe_fetch_source_remote() throttle in get_remote_branches_impl
  instead of unconditional git fetch

Robustness:
- add_worktree_impl validates configured base branch exists on remote
  before use, falls back to auto-detect with warning if stale

Bug:
- Add getRemoteBranches/setBaseBranch stubs to electron.ts

Code quality:
- BranchSelector: unify fetchBranches into single function used by
  both initial load and retry
- Use onCloseRef pattern to avoid re-registering click-outside listener
- Add resize listener to reposition portal dropdown
- Filter resolvedDefaultBranch from branch list to avoid duplicate with
  the "(default)" option

Tests:
- set_base_branch_impl happy path, invalid branch rejection, None reset
- add_worktree_impl uses configured base branch (verifies commit from
  develop branch, not main)
- config round-trip preserves base_branch field (Some and None)
Copy link
Copy Markdown
Owner

@bang9 bang9 left a comment

Choose a reason for hiding this comment

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

Reviewed via roc-pr-review

Comment thread grove/src/components/sidebar/BranchSelector.tsx
Comment thread grove/src/components/sidebar/DefaultBranchItem.tsx
Comment thread grove/grove-core/src/git_project.rs
bang9 and others added 5 commits March 30, 2026 23:42
The mousedown outside-click handler was closing the dropdown before the
toggle button's onClick could fire, causing the selector to immediately
reopen. Adding anchorRef to the exclusion check lets the toggle button
properly close the dropdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Stale remote tracking refs for deleted branches were not being cleaned
up, causing show-ref --verify to succeed and preventing the
fallback-to-auto-detect logic from working correctly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…default)

Show "(base·default)" when using auto-detected default branch, "(base)"
when a custom base branch is set.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bang9 bang9 merged commit b95d19e into bang9:main Mar 30, 2026
1 check passed
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.

2 participants