@@ -18,6 +18,7 @@ Commands:
1818 remove <slug> Remove worktree
1919 exists <slug> Check if worktree exists (exit 0 if yes)
2020 get-path <slug> Get absolute path to worktree
21+ sync <slug> Rebase worktree branch onto latest main
2122 cleanup [--dry-run] Remove merged/stale worktrees
2223 link-memory <slug> Create symlinks to shared memory
2324
163164
164165 local worktree_path=" $type_dir /$slug "
165166
167+ # Fetch latest from origin to ensure we're up to date (v11.8.4)
168+ log_info " Fetching latest from origin..."
169+ git fetch origin --quiet 2> /dev/null || log_warn " Could not fetch from origin (working offline?)"
170+
171+ # Determine base branch (origin/main or origin/master)
172+ local base_branch=" origin/main"
173+ if ! git rev-parse --verify --quiet " $base_branch " > /dev/null 2>&1 ; then
174+ base_branch=" origin/master"
175+ if ! git rev-parse --verify --quiet " $base_branch " > /dev/null 2>&1 ; then
176+ base_branch=" HEAD" # Fallback to current HEAD if no remote
177+ log_warn " No origin/main or origin/master found, using HEAD"
178+ fi
179+ fi
180+
166181 # Create or checkout branch
167182 if branch_exists " $branch " ; then
168183 log_info " Branch '$branch ' already exists, will link to worktree"
169184 else
170- log_info " Creating new branch: $branch "
171- git branch " $branch " 2> /dev/null || log_warn " Branch creation skipped (may already exist)"
185+ log_info " Creating new branch: $branch (from $base_branch ) "
186+ git branch " $branch " " $base_branch " 2> /dev/null || log_warn " Branch creation skipped (may already exist)"
172187 fi
173188
174189 # Create worktree
@@ -369,6 +384,92 @@ cmd_get_path() {
369384 fi
370385}
371386
387+ # ============================================================================
388+ # Command: sync (v11.8.4)
389+ # ============================================================================
390+
391+ cmd_sync () {
392+ if [ $# -lt 1 ]; then
393+ log_error " Usage: worktree-manager.sh sync <slug>"
394+ exit 1
395+ fi
396+
397+ local slug=" $1 "
398+ ensure_git_repo
399+
400+ if ! worktree_exists " $slug " ; then
401+ log_error " Worktree not found: $slug "
402+ exit 1
403+ fi
404+
405+ local worktree_path
406+ worktree_path=$( get_worktree_path " $slug " )
407+
408+ # Fetch latest from origin
409+ log_info " Fetching latest from origin..."
410+ git fetch origin --quiet 2> /dev/null || log_warn " Could not fetch from origin"
411+
412+ # Determine base branch
413+ local base_branch=" origin/main"
414+ if ! git rev-parse --verify --quiet " $base_branch " > /dev/null 2>&1 ; then
415+ base_branch=" origin/master"
416+ if ! git rev-parse --verify --quiet " $base_branch " > /dev/null 2>&1 ; then
417+ log_error " No origin/main or origin/master found"
418+ exit 1
419+ fi
420+ fi
421+
422+ # Get current branch in worktree
423+ local current_branch
424+ current_branch=$( get_worktree_branch " $worktree_path " )
425+
426+ # Check if worktree is clean
427+ if ! is_worktree_clean " $worktree_path " ; then
428+ log_error " Worktree has uncommitted changes. Commit or stash first."
429+ exit 1
430+ fi
431+
432+ # Check how far behind we are
433+ local behind_count
434+ behind_count=$( cd " $worktree_path " && git rev-list --count HEAD.." $base_branch " 2> /dev/null || echo " 0" )
435+
436+ if [ " $behind_count " = " 0" ]; then
437+ log_success " Branch is already up to date with $base_branch "
438+ if $JSON_OUT ; then
439+ echo ' {"status": "up-to-date", "behind": 0}'
440+ fi
441+ return 0
442+ fi
443+
444+ log_info " Branch is $behind_count commits behind $base_branch "
445+
446+ if $DRY_RUN ; then
447+ log_info " [DRY-RUN] Would rebase $current_branch onto $base_branch "
448+ if $JSON_OUT ; then
449+ echo " {\" status\" : \" dry-run\" , \" behind\" : $behind_count , \" base\" : \" $base_branch \" }"
450+ fi
451+ return 0
452+ fi
453+
454+ # Perform rebase
455+ log_info " Rebasing $current_branch onto $base_branch ..."
456+ cd " $worktree_path " || exit 1
457+
458+ if git rebase " $base_branch " 2> /dev/null; then
459+ log_success " Successfully rebased onto $base_branch "
460+ if $JSON_OUT ; then
461+ echo " {\" status\" : \" rebased\" , \" behind\" : 0, \" base\" : \" $base_branch \" }"
462+ fi
463+ else
464+ log_error " Rebase failed. Resolve conflicts in $worktree_path then run 'git rebase --continue'"
465+ git rebase --abort 2> /dev/null || true
466+ if $JSON_OUT ; then
467+ echo " {\" status\" : \" conflict\" , \" behind\" : $behind_count , \" base\" : \" $base_branch \" }"
468+ fi
469+ exit 1
470+ fi
471+ }
472+
372473# ============================================================================
373474# Command: cleanup
374475# ============================================================================
@@ -531,6 +632,9 @@ case "$COMMAND" in
531632 get-path)
532633 cmd_get_path " $@ "
533634 ;;
635+ sync)
636+ cmd_sync " $@ "
637+ ;;
534638 cleanup)
535639 cmd_cleanup " $@ "
536640 ;;
0 commit comments