Skip to content

feat(worktree): ✨ Fix branch tracking and support remote branch checkout - #157

Merged
jorben merged 3 commits into
masterfrom
feat/worktree-track-upstream
Apr 30, 2026
Merged

feat(worktree): ✨ Fix branch tracking and support remote branch checkout#157
jorben merged 3 commits into
masterfrom
feat/worktree-track-upstream

Conversation

@jorben

@jorben jorben commented Apr 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix new branch worktree accidentally tracking the base branch (causing push to wrong upstream)
  • Add --no-track when creating a new branch from a base ref, unless trackUpstream is explicitly true
  • Support checking out remote branches (without local counterpart) in the "existing branch" worktree mode, creating a local tracking branch automatically

Test Plan

  • Create worktree with new branch from base → verify no upstream tracking set
  • Create worktree selecting a remote-only branch → verify local branch tracks remote correctly
  • Push from new-branch worktree → verify it does NOT push to base branch
  • Push from remote-checkout worktree → verify it pushes to correct remote branch

🤖 Generated with TiyCode

…tracking

Add the ability to create a worktree from a remote branch by automatically creating a local tracking branch. Previously, users could only select local branches in the worktree dialog, limiting the ability to work on un-checked-out remote branches.

Key changes include:
- Expose a `trackUpstream` field in the worktree creation input model to control whether the new branch tracks the base ref as its upstream; defaults to `false` for feature branches
- Respect `trackUpstream` in the backend worktree add command by passing `--no-track` when the flag is `false`
- In the UI dialog, compute remote branches that have no local counterpart and display them in a dedicated section labeled "remote" alongside local branches
- When a remote branch is selected, construct a create-branch input with `trackUpstream: true` so the local branch automatically tracks the remote ref, enabling `git pull` to work out of the box

This allows developers to spin up a worktree from any remote branch (e.g., a PR branch) without needing to manually create a local branch beforehand.
@github-actions

github-actions Bot commented Apr 29, 2026

Copy link
Copy Markdown

AI Code Review Summary

PR: #157 (feat(worktree): ✨ Fix branch tracking and support remote branch checkout)
Preferred language: English

Overall Assessment

Detected 5 actionable findings, prioritize CRITICAL/HIGH before merge.

Major Findings by Severity

  • HIGH (1)
    • src/modules/workbench-shell/ui/new-worktree-dialog.tsx:165 - No test coverage for remote-branch selection and submission logic
  • MEDIUM (3)
    • src-tauri/src/core/worktree_manager.rs:570 - Missing tests for new track_upstream field and --no-track logic
    • src/modules/workbench-shell/ui/new-worktree-dialog.tsx:115 - Missing boundary test for remoteBranchesWithoutLocal filter
    • src/modules/workbench-shell/ui/new-worktree-dialog.tsx:120 - Remote branch name deduplication may incorrectly match similar names
  • LOW (1)
    • src-tauri/src/core/worktree_manager.rs:570 - track_upstream silently ignored when create_branch is false

Actionable Suggestions

  • Add a validation or log warning when track_upstream is true but create_branch is false.
  • Add coverage for new Git flag logic in integration tests.
  • Create a new integration test file or extend existing worktree tests to cover the four definite states of the track_upstream and --no-track logic.
  • Add a unit test in workspace model tests for the default deserialization of track_upstream.
  • Ensure CI runs these tests on all supported platforms to catch platform-specific Git behavior.
  • Refactor the remote-branch name extraction into a helper function and write unit tests for various branch name patterns (simple, nested, with multiple slashes).
  • Consolidate the 'is remote branch' determination into a single Set or selector shared between filter and submit logic.
  • Add a comment explaining why trackUpstream is unconditionally true, or make it configurable.
  • Write Vitest tests for NewWorktreeDialog covering: (a) selecting a remote branch submits createBranch=true with correct baseRef; (b) selecting a local branch submits createBranch=false; (c) remoteBranchesWithoutLocal filter handles branch names with multiple slashes; (d) empty-state renders when both local and remote lists are empty; (e) 'local' and 'remote' badges appear correctly.
  • Redirect test focus: consider mocking workspaceCreateWorktree and asserting the exact payload shape sent to the backend.
  • Verify backend integration tests include the trackUpstream flag and that it produces the expected git configuration (branch tracking).

Potential Risks

  • Silent upstream tracking misconfiguration if --no-track is not applied when expected, potentially causing push accidents.
  • Async blocking task wrapper adds complexity that is not being tested under load or concurrency, but this pre-dates this change and is not specific to the new field.
  • If the backend does not yet handle the optional trackUpstream field, worktree creation for remote branches could fail or behave unexpectedly. Confirm backend alignment.
  • The remote-branch submission path is completely untested, increasing the chance of a regression where remote branches are not created correctly.
  • The filter's use of first '/' to split may misclassify branches with '/' in their name, but without tests we'll only discover this in production.
  • The backend might not implement trackUpstream, making the frontend feature silently non-functional.

Test Suggestions

  • Verify --no-track presence and absence in various flag combinations.
  • Test that the new field defaults to false when omitted from JSON deserialization.
  • Test run_git_worktree_add argument construction in isolation to avoid overhead of real Git worktree creation.
  • Test the full Tauri command pipeline using a test Git repo to confirm end-to-end behavior with track_upstream both false and true.
  • Use a mock/spy approach to assert the exact git CLI arguments without actually creating worktrees, speeding up fast unit-style tests.
  • Add unit tests for remoteBranchesWithoutLocal with branches: ['main', 'origin/main', 'feature/a/b', 'origin/feature/a/b', 'upstream/feature-x'] and local branches: ['main'].
  • Test submit handler with a remote branch selected to ensure createBranch: true and correct baseRef are passed.
  • Verify empty/loading states render correctly when remote and local branch lists are empty.
  • Unit/integration test for NewWorktreeDialog remote-branch selection and submission.
  • Unit test for remoteBranchesWithoutLocal filter with complex branch names.
  • Snapshot or rendering test verifying the presence of 'local'/'remote' badges and the empty state message.
  • Backend integration test for WorktreeCreateInput with trackUpstream=true.

File-Level Coverage Notes

  • src-tauri/src/core/worktree_manager.rs: The new track_upstream feature is wired correctly but entirely untested. The conditional --no-track logic (lines R566–R572) has no unit or integration coverage. (No existing test modifications were included in the diff; diff only adds functionality and zero test code.)
  • src-tauri/src/model/workspace.rs: The struct addition is straightforward and low-risk, but lacks unit test verification for serde defaults. (This is a data model change, typically safe, but test should exist to prevent regression.)
  • src/modules/workbench-shell/ui/new-worktree-dialog.tsx: This file introduces significant new logic (remote branch filtering and a dual-path submit) without any corresponding test file. The risk of regressions in branch selection and creation is high. (The remoteBranchesWithoutLocal computation and the submit branching are functionally sensible but deserve test coverage commensurate with their complexity.)
  • src/shared/types/api.ts: The type change is minimal and safe; adding trackUpstream is backwards-compatible. The risk comes from the backend not yet tested for this new flag.
  • src-tauri/tests/worktree.rs: ok (All changes are mechanical additions of the track_upstream field to existing struct-literals. No logic changes, no new test cases, and no risk of regression introduced here.)

Inline Downgraded Items (processed but not inline)

  • None

Coverage Status

  • Target files: 5
  • Covered files: 5
  • Uncovered files: 0
  • No-patch/binary covered as file-level: 0
  • Findings with unknown confidence (N/A): 0

Uncovered list:

  • None

No-patch covered list:

  • None

Runtime/Budget

  • Rounds used: 1/4
  • Planned batches: 3
  • Executed batches: 3
  • Sub-agent runs: 5
  • Planner calls: 1
  • Reviewer calls: 5
  • Model calls: 6/64
  • Structured-output summary-only degradation: NO

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated PR review completed.

  • Findings kept: 2
  • Findings with unknown confidence: 0
  • Inline comments attempted: 2
  • Target files: 4
  • Covered files: 4
  • Uncovered files: 0
    See the summary comment for detailed analysis and coverage details.

branch: &str,
create_branch: bool,
base_ref: Option<&str>,
track_upstream: bool,

This comment was marked as outdated.

branch,
baseBranch,
selectedExistingBranch,
remoteBranchesWithoutLocal,

This comment was marked as outdated.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Automated PR review completed.

  • Findings kept: 5
  • Findings with unknown confidence: 0
  • Inline comments attempted: 5
  • Target files: 5
  • Covered files: 5
  • Uncovered files: 0
    See the summary comment for detailed analysis and coverage details.

createBranch: false,
path: path.trim() || undefined,
};
// Check if the selected branch is a remote ref.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[HIGH] No test coverage for remote-branch selection and submission logic

The remote-branch submit path and filtering logic have no automated test coverage, so regressions in branch creation from remote refs are likely to slip through.

Suggestion: Add Vitest tests that mock branches, workspaceCreateWorktree, and onClose/onCreated. Cover: (1) selecting a remote branch and submitting—verify the input includes createBranch:true and correct baseRef; (2) selecting a local branch and submitting—verify createBranch:false with no baseRef; (3) edge cases where branch name has multiple slashes; (4) when both local and remote lists are empty, the empty state message renders.

Risk: Untested remote-branch workflow may silently send incorrect git commands, causing silent failures or wrong branch creation on the filesystem.

Confidence: 0.92

[From SubAgent: testing]

// the base ref so that `git push` won't accidentally target the base
// branch's upstream. When track_upstream is true (e.g. checking out a
// remote branch locally), we let Git set up tracking normally.
if base_ref.is_some() && !track_upstream {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] Missing tests for new track_upstream field and --no-track logic

The new track_upstream field and its conditional --no-track argument have no corresponding tests in the existing test suite, leaving the feature uncovered.

Suggestion: Add integration tests in src-tauri/tests/ (e.g., worktree_manager.rs) for: (1) track_upstream=false with base_ref → expects --no-track in args; (2) track_upstream=true with base_ref → omits --no-track; (3) create_branch=false → ignores track_upstream; (4) base_ref=None with track_upstream=false → no --no-track.

Risk: Without tests, future refactors could silently break upstream tracking behavior, affecting worktree-based branching workflows.

Confidence: 0.85

[From SubAgent: testing]

);

// Remote branches that don't already have a local counterpart.
const remoteBranchesWithoutLocal = useMemo(() => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] Missing boundary test for remoteBranchesWithoutLocal filter

Edge cases in the remote-branch dedup filter (names with slashes, fully remote repos) are not covered by tests.

Suggestion: Add unit tests for the filter logic (or component tests) with branches like 'origin/feature/my/branch' when a local 'feature/my/branch' also exists, and when only remote branches exist.

Risk: Branch names with multiple slashes could be incorrectly classified as having a local counterpart, hiding remote branches from the selector.

Confidence: 0.85

[From SubAgent: testing]

return branches.filter((b) => {
if (!b.isRemote) return false;
// Strip the remote prefix (e.g. "origin/feature-x" → "feature-x")
const slashIdx = b.name.indexOf("/");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[MEDIUM] Remote branch name deduplication may incorrectly match similar names

Using b.name.slice(slashIdx + 1) strips only the first path component (the remote name). For remotes with nested branch names (e.g., origin/feature/sub-feature), the resulting local name guess may be wrong, leading to false positives or negatives in the 'without local' filter.

Suggestion: Consider using b.name.replace(/^[^/]+\//, '') to strip exactly the remote prefix, or better, compare against the branch's ref or use the Git API to determine the true local tracking branch name derived from branches data if available.

Risk: May incorrectly hide or show remote branches that have slashes in their names, potentially causing confusion or duplicate branch entries.

Confidence: 0.85

[From SubAgent: general]

// the base ref so that `git push` won't accidentally target the base
// branch's upstream. When track_upstream is true (e.g. checking out a
// remote branch locally), we let Git set up tracking normally.
if base_ref.is_some() && !track_upstream {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

[LOW] track_upstream silently ignored when create_branch is false

If someone sets track_upstream=true while create_branch=false, the flag has no effect and no diagnostic is given, which might lead to confusion.

Suggestion: Consider adding a warning log or returning a validation error when track_upstream is set but create_branch is false.

Risk: Users may expect track_upstream=true to set upstream tracking even without branch creation and be surprised when it does nothing. No data corruption, but it's a minor UX trap.

Confidence: 0.85

[From SubAgent: general]

@jorben
jorben merged commit 3c2d9a2 into master Apr 30, 2026
4 checks passed
@jorben
jorben deleted the feat/worktree-track-upstream branch April 30, 2026 04:35
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