Skip to content

Conversation

@jellydn
Copy link

@jellydn jellydn commented Aug 30, 2025

Add 'b' Key for Branch-Based Session Creation with Remote Sync

Addresses #88 (provides manual workaround for flexible branch naming)

What

This PR adds comprehensive branch-based session creation functionality via the 'b' key, implementing a three-step workflow that allows users to create sessions with custom git branches, now enhanced with remote branch sync detection and session name preservation.

Key Features Added:

  • 'b' key functionality: Create sessions with custom branch names
  • Three-step workflow: Session name → Branch name → Source branch
  • 🆕 Remote sync detection: Automatically check if source/target branches need sync with origin
  • 🆕 Session name preservation: Maintains user session names instead of overwriting with branch names
  • Smart defaults: Automatic detection of main/develop branches
  • Text input modals: Consistent UI across all input steps
  • Branch validation: Git-compliant branch name validation
  • No prefix interference: User-specified branch names used exactly as provided

Why

Problem Statement:

Users needed a way to create sessions with specific git branch names for feature development, but the existing 'n' key only supported auto-generated branch names with configured prefixes.

Issues Addressed:

  1. Missing Branch Control: No way to specify custom branch names like feat/user-auth or hotfix/critical-bug
  2. 🆕 Outdated Source Branches: Creating branches from stale local source branches that diverged from remote
  3. 🆕 Session Name Override: User session names being replaced with branch names
  4. Modal Display Problems: Text appeared vertically instead of horizontally in input fields
  5. Title Setting Errors: "Cannot change title of started instance" errors in branch workflow
  6. Branch Prefix Interference: User-specified branches were getting unwanted prefixes
  7. Linting Issues: Non-idiomatic if-else chains and unchecked errors
  8. Import Problems: Missing aliases causing build failures

How

Implementation Details:

1. Core Branch Workflow (app/app.go) - Enhanced

// Enhanced workflow with remote sync checks
case stateSourceBranch:
    // 🆕 Check source branch sync first
    sourceExists, sourceNeedsSync, err := session.CheckRemoteBranchStatic(".", sourceBranch)
    if sourceExists && sourceNeedsSync {
        // Show sync confirmation for source branch
        message := "Source branch 'main' is out of sync with remote. Sync before creating? (y/n)"
    }
    
    // 🆕 Then check target branch sync  
    exists, needsSync, err := session.CheckRemoteBranchStatic(".", targetBranch)
    if exists && needsSync {
        // Show sync confirmation for target branch
        message := "Target branch 'feature' has different commits. Sync before creating? (y/n)"
    }

2. 🆕 Remote Branch Sync System (session/git/worktree_ops.go)

// Static methods that work before instance initialization
func CheckRemoteBranchStatic(repoPath, branchName string) (exists bool, needsSync bool, err error)
func SyncWithRemoteBranchStatic(repoPath, branchName string) error

// Two-stage sync confirmation workflow
func (m *home) syncSourceThenCheckTarget(selected *session.Instance, sourceBranch string)
func (m *home) checkTargetBranchAndProceed(selected *session.Instance, sourceBranch string) 

3. 🆕 Session Name Preservation (app/app.go)

Before: Always overwrote session title with branch name

// WRONG: Always overwrote user's session name
if err := selected.SetTitle(m.pendingBranchName); err != nil {

After: Preserves user session names

// CORRECT: Only set branch name as title if no title exists
if selected.Title == "" {
    if err := selected.SetTitle(m.pendingBranchName); err != nil {

4. Instance Lifecycle Fix

Before: Instance started immediately after naming, preventing title updates

// BROKEN: Started too early
case tea.KeyEnter:
    instance.Start(true) // ❌ Makes title immutable

After: Instance starts only after complete configuration

// FIXED: Start timing based on workflow needs
if !m.branchAfterName && !m.promptAfterName {
    instance.Start(true) // ✅ Start when ready
}

5. UI Component Improvement (ui/overlay/textInput.go)

Before: Used textarea.Model (multi-line) causing vertical text display

textarea      textarea.Model  // ❌ Wrong component

After: Switched to textinput.Model (single-line) for proper display

textInput     textinput.Model  // ✅ Correct component

🆕 Enhanced User Experience Flow:

Before:

1. Press 'b' → Enter session name → Enter branch → Session renamed to branch name
2. No remote sync checking → potential outdated branches

After:

1. Press 'b' → Enter session name "my-feature" → Enter branch name "feat/auth"
2. Check source branch sync → "Source branch 'main' is out of sync. Sync? (y/n)"
3. Check target branch sync → "Target branch 'feat/auth' has different commits. Sync? (y/n)"  
4. Create session named "my-feature" with up-to-date branch "feat/auth"

Testing & Validation:

  • ✅ All existing tests pass (no regressions)
  • ✅ 🆕 Comprehensive test coverage for sync functionality (app/branch_sync_test.go)
  • ✅ 🆕 Session name preservation tests (TestSessionTitlePreservation)
  • ✅ 🆕 Remote branch sync tests (TestSourceBranchSyncCheck)
  • ✅ Build succeeds with zero linting issues
  • ✅ Both 'n' and 'b' key workflows working correctly

Workflow Comparison:

Feature 'n' Key (Auto) 'b' Key (Custom)
Session Name ✅ User types ✅ User types (🆕 preserved)
Branch Name ❌ Auto-generated ✅ User specifies
Source Branch ❌ Default only ✅ User selects
🆕 Source Sync Check ❌ No ✅ Yes
🆕 Target Sync Check ❌ No ✅ Yes
Branch Prefix ✅ Applied ❌ Not applied
Use Case Quick sessions Feature branches

Examples

🆕 Enhanced 'b' Key Workflow:

  1. Press b → Enter session name: auth-feature-work
  2. Enter branch name: feat/user-authentication
  3. Enter source branch: develop
  4. 🆕 Source sync check: "Source branch 'develop' is out of sync with remote. Sync before creating? (y/n)"
  5. 🆕 Target sync check: "Target branch 'feat/user-authentication' has different commits. Sync before creating? (y/n)"
  6. Result: Session named auth-feature-work with synced branch feat/user-authentication from updated develop

Addresses Issue #88 - Flexible Branch Naming:

While this PR doesn't implement template-based automatic branch naming, it provides a manual solution that supports all the patterns requested in #88:

  • fix/issue-123-auth-bug - User can type exactly this
  • feature/456/user-dashboard - User can type exactly this
  • {user}/issue-789 - User can manually enter their username
  • ✅ Any custom pattern - Complete flexibility through manual input

This gives users immediate access to flexible branch naming while a future PR could add template automation.

Backwards Compatibility:

  • 'n' key: Works exactly as before with prefix
  • 'p' key: Unchanged functionality
  • All existing configurations and workflows preserved

🆕 Files Changed (Latest):

Core Enhancements:

  • app/app.go - Enhanced workflow with remote sync detection and session name preservation
  • app/branch_sync_test.go - NEW: Comprehensive tests for sync functionality
  • session/git/worktree_ops.go - Added static remote branch checking methods
  • session/git/util_test.go - NEW: Tests for remote branch operations
  • session/instance.go - Added wrapper functions for static git operations

Previous Changes:

  • keys/keys.go - Key binding for 'b'
  • ui/overlay/textInput.go - UI component fix
  • config/config_test.go - Error handling fixes
  • session/tmux/tmux.go - Error handling fixes
  • Multiple files - Import and linting fixes

This comprehensive implementation provides users with full control over branch-based development workflows with intelligent remote sync management while maintaining all existing functionality.

Add comprehensive branch workflow with three-step process:
1. Session name input (same as 'n' key)
2. Branch name input (e.g., feat/new-feature)
3. Source branch selection (with smart defaults)

Key improvements:
- Fix modal display issues by switching from textarea to textinput
- Fix title setting timing to prevent "cannot change title" errors
- Remove branch prefix for user-specified names (respect exact input)
- Convert if-else chains to tagged switches for better linting
- Fix all import issues and errcheck warnings

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@github-actions
Copy link

github-actions bot commented Aug 30, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@jellydn
Copy link
Author

jellydn commented Aug 30, 2025

I have read the CLA Document and I hereby sign the CLA

@jellydn jellydn marked this pull request as ready for review August 30, 2025 06:15
jellydn and others added 2 commits September 6, 2025 11:15
…rvation

This commit implements two major enhancements to the branch creation workflow:

## 1. Remote Branch Sync Detection and Confirmation

### Source Branch Sync Check
- Check if source branch (the "from" branch) needs sync with remote origin
- Prompt user: "Source branch 'main' is out of sync with remote. Sync before creating? (y/n)"
- Prevents creating branches from outdated local source branches

### Target Branch Sync Check
- Check if target branch name already exists on remote with different commits
- Prompt user: "Target branch 'feature' has different commits. Sync before creating? (y/n)"
- Ensures branch creation uses most up-to-date remote state

### Implementation Details
- Added `CheckRemoteBranchStatic()` and `SyncWithRemoteBranchStatic()` static methods
- Enhanced `stateSourceBranch` workflow with two-stage sync confirmation
- Added new helper methods: `syncSourceThenCheckTarget()`, `checkTargetBranchAndProceed()`
- Uses `stateSyncConfirm` state with contextual confirmation overlays

## 2. Session Name Preservation

### Problem Fixed
- 'b' key workflow was overwriting user session names with branch names
- User enters session name "my-auth-session" but gets "feat/auth-flow" instead

### Solution
- Modified `finalizeBranchCreation()` to only set branch name as title when no title exists
- Preserves user-entered session names from 'b' key workflow
- Maintains backward compatibility for direct branch creation

## Key Files Changed

### Core Logic
- `app/app.go`: Enhanced branch creation workflow with remote sync checks
- `session/git/worktree_ops.go`: Added static remote branch checking methods
- `session/instance.go`: Added wrapper functions for static git operations

### Tests Added
- `app/branch_sync_test.go`: Comprehensive tests for sync functionality and session preservation
- `session/git/util_test.go`: Tests for remote branch detection and sync operations

## User Experience Flow

**Before**:
```
1. Press 'b' → Enter session name → Enter branch → Session renamed to branch name
2. No remote sync checking → potential outdated branches
```

**After**:
```
1. Press 'b' → Enter session name → Enter branch name
2. Check source branch sync → Optional sync source
3. Check target branch sync → Optional sync target
4. Create session with preserved name and up-to-date branches
```

This enhancement ensures branch creation workflows are more reliable and user-friendly by preventing common git sync issues and respecting user session naming choices.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@jellydn
Copy link
Author

jellydn commented Sep 6, 2025

🚀 Major Updates Since Last Week

Hey team! I've made significant enhancements to the branch creation workflow based on testing and user feedback. Here's what's new in the latest commit:

🔄 Remote Branch Sync Detection & Management

Problem Solved: Users were creating branches from outdated local source branches that had diverged from remote origin, leading to merge conflicts and lost commits.

Solution: Added intelligent 2-stage sync detection:

1. Source Branch Sync Check

  • Before creating any branch, check if the source branch (e.g., main, develop) needs sync
  • User prompt: "Source branch 'main' is out of sync with remote. Sync before creating new branch? (y/n)"
  • Prevents branches from being created off stale local commits

2. Target Branch Sync Check

  • Check if target branch name already exists on remote with different commits
  • User prompt: "Target branch 'feat/auth' has different commits. Sync before creating? (y/n)"
  • Handles cases where remote branch was updated by teammates

💾 Session Name Preservation

Problem Solved: The 'b' key workflow was overwriting user session names with branch names.

Before: User enters session name "my-auth-work" → gets session named "feat/auth-flow" ❌
After: User enters session name "my-auth-work" → keeps session named "my-auth-work" ✅

This maintains clear separation between session organization and git branch naming.

🛠️ Technical Implementation

New Static Methods (session/git/worktree_ops.go):

func CheckRemoteBranchStatic(repoPath, branchName string) (exists bool, needsSync bool, err error)
func SyncWithRemoteBranchStatic(repoPath, branchName string) error

Enhanced State Machine (app/app.go):

  • Added syncSourceThenCheckTarget() and checkTargetBranchAndProceed() methods
  • Two-stage confirmation workflow using stateSyncConfirm
  • Contextual overlay messages for different sync scenarios

Session Title Logic:

// Only overwrite title if none provided (preserves 'b' key user input)
if selected.Title == "" {
    selected.SetTitle(m.pendingBranchName)
}

🧪 Comprehensive Testing

New Test Suite (app/branch_sync_test.go):

  • TestSyncConfirmationStateTransitions - State management
  • TestSyncConfirmationKeyHandling - User input handling
  • TestSessionTitlePreservation - Session name preservation
  • TestSourceBranchSyncCheck - Remote sync detection
  • TestSyncConfirmationFlow - End-to-end workflows

All tests pass - zero regressions, full backward compatibility maintained.

📈 Impact on User Experience

Before:

Press 'b' → name session → name branch → create (possibly from stale source)
Result: Session named after branch, potential git conflicts

After:

Press 'b' → name session → name branch → sync source? → sync target? → create
Result: Custom session name preserved, branches always up-to-date

🔧 Why These Changes Matter

  1. Prevents Git Conflicts: No more surprises from outdated source branches
  2. Better Organization: Session names reflect user intent, not technical details
  3. Safer Workflows: Users make informed decisions about remote sync
  4. Team Collaboration: Handles scenarios where teammates updated remote branches

This brings the branch creation workflow up to production-ready standards for team development!

Ready for review - all functionality tested and working seamlessly with existing workflows.

jellydn and others added 4 commits September 6, 2025 13:41
This commit fixes an issue where using the same branch name for both source
and target in branch creation workflow would cause problems.

## Problem
When a user enters the same branch name for both "from branch" and "new branch":
- System tried to create a "new" branch with existing name
- Showed confusing sync confirmation for non-existent new branch
- Could fail or create unexpected behavior
- Session would be empty/broken after sync confirmation

## Solution
Added intelligent detection for same-branch scenario:

### Edge Case Detection
```go
if sourceBranch == m.pendingBranchName {
    // This is existing branch checkout, not new branch creation
    return m.handleSameBranchCheckout(selected, sourceBranch)
}
```

### New Workflow for Same Branch Names
1. **`handleSameBranchCheckout()`** - Detects this is existing branch operation
2. **Single sync check** - Only check if the existing branch needs sync
3. **`finalizeExistingBranchCheckout()`** - Sets up session with existing branch
4. **Clear messaging** - "Branch 'main' is out of sync. Sync before checkout? (y/n)"

### Key Differences from New Branch Creation
- **No new branch creation** - Uses existing branch directly
- **Single sync check** - Only one confirmation instead of two
- **Checkout vs Create** - Language reflects the actual operation
- **Source = Target** - Both CustomBranch and SourceBranch set to same value

## Implementation Details

### Methods Added
- `handleSameBranchCheckout()` - Entry point for same-branch scenario
- `finalizeSameBranchCheckout()` - Handles sync then checkout
- `finalizeExistingBranchCheckout()` - Final session setup for existing branch

### User Experience
**Before (broken)**:
```
Enter branch: "main" → Enter source: "main"
→ "Target branch 'main' has different commits. Sync? (y/n)"
→ Empty/broken session
```

**After (fixed)**:
```
Enter branch: "main" → Enter source: "main"
→ "Branch 'main' is out of sync with remote. Sync before checkout? (y/n)"
→ Working session with branch "main"
```

### Tests Added
- `TestSameBranchEdgeCase` - Comprehensive testing of same-branch scenario
- Verifies no panics, correct branch setup, and session title preservation
- Ensures both CustomBranch and SourceBranch are set to same value

This fix ensures the branch creation workflow handles all valid user inputs
gracefully, including the edge case of checking out existing branches.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
…origins

**Problem:**
- After creating branches via 'b' workflow from remote origins, branches lacked proper upstream tracking
- `git pull` would fail with "There is no tracking information for the current branch"
- Users had to manually run `git branch --set-upstream-to=origin/<branch>`

**Root Cause:**
- `setupFromExistingBranch()` created worktrees from remote branches but didn't set upstream tracking
- Both paths (remote-only and local+remote scenarios) missed explicit upstream configuration

**Solution:**
- Added explicit `git branch --set-upstream-to=origin/<branch>` calls in both scenarios:
  1. When local branch doesn't exist but remote does (line 84-87)
  2. When both local and remote exist (line 95-100)
- Added warning logging for tracking setup failures (non-fatal)
- Preserves existing functionality while ensuring proper git pull/push behavior

**Testing:**
- All existing git tests pass (session/git package)
- Fix handles both new and existing branch scenarios
- Graceful degradation with warnings if upstream setup fails

**Files Modified:**
- session/git/worktree_ops.go: Added upstream tracking setup
- .github/ISSUE_TEMPLATE/ux_enhancement.md: Created template for future UX issues

This resolves the git pull tracking issue reported in auth-flow worktree scenario.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
Applied gofmt formatting to session/git/worktree_ops.go to resolve
make lint-basic errors. No functional changes.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
**Enhanced User Experience:**
- Added comprehensive guidance messages when upstream tracking setup fails
- Provides exact command for users to run manually: `git branch --set-upstream-to=origin/<branch> <branch>`
- Created reusable helper function `showUpstreamTrackingMessage()` for consistent messaging
- Improved error messages in worktree setup with actionable instructions

**Key Improvements:**
1. **Helpful Error Messages**: Replace generic warnings with specific guidance
2. **User Empowerment**: Show exact commands to fix tracking issues manually
3. **Edge Case Support**: Especially beneficial for same-name branch scenarios
4. **Consistent UX**: Standardized messaging across different failure modes

**User Journey Enhancement:**
```
Before: "Warning: failed to set upstream tracking for branch feature: exit status 128"
After:  "Warning: Unable to automatically set upstream tracking for branch 'feature'.
        To enable git pull/push, run this command in your worktree:
          git branch --set-upstream-to=origin/feature feature"
```

**Files Modified:**
- session/git/worktree_ops.go: Enhanced error messages with actionable guidance
- app/app.go: Added helper function for consistent upstream tracking messages

This addresses user feedback about needing manual upstream tracking setup,
especially after sync confirmations and in same-name branch edge cases.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@matthew-petty
Copy link

I submitted a PR #211 with a substantially similar goal. I chose a simpler approach with no upstream checking and no option to use an arbitrary branch. I did not intend to duplicate functionality across to PRs. #211 is a solution I implemented for my personal workflows.

@jellydn jellydn closed this Sep 18, 2025
@github-actions github-actions bot locked and limited conversation to collaborators Sep 18, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants