@@ -21,6 +21,61 @@ set -euo pipefail
2121
2222SCAN_DIR=" ${HOME} /src"
2323TARGET_BRANCH=" "
24+ UPDATE_CHECK_FILE=" /tmp/git-wt-update-check-$$ "
25+
26+ # Background update check - runs asynchronously
27+ check_for_updates () {
28+ local current_version=" $1 "
29+ # Strip leading 'v' if present for comparison
30+ current_version=" ${current_version# v} "
31+
32+ # Skip if current version is 'dev' or empty
33+ if [[ -z " $current_version " ]] || [[ " $current_version " == " dev" ]]; then
34+ return
35+ fi
36+
37+ # Check GitHub API for latest release (timeout after 2 seconds)
38+ local latest_info
39+ if latest_info=$( curl -sf --max-time 2 " https://api.github.com/repos/nsheaps/git-wt/releases/latest" 2> /dev/null) ; then
40+ local latest_version
41+ latest_version=$( echo " $latest_info " | grep -o ' "tag_name": *"[^"]*"' | head -1 | sed ' s/.*"tag_name": *"v\{0,1\}\([^"]*\)".*/\1/' )
42+
43+ if [[ -n " $latest_version " ]] && [[ " $latest_version " != " $current_version " ]]; then
44+ # Simple version comparison - check if latest is newer
45+ # This works for semver: compare as strings after normalizing
46+ if [[ " $( printf ' %s\n%s' " $current_version " " $latest_version " | sort -V | tail -1) " == " $latest_version " ]] && \
47+ [[ " $current_version " != " $latest_version " ]]; then
48+ echo " UPDATE_AVAILABLE=$latest_version " > " $UPDATE_CHECK_FILE "
49+ fi
50+ fi
51+ fi
52+ }
53+
54+ # Start background update check
55+ CURRENT_VERSION=$( git describe --tags --always 2> /dev/null || echo ' dev' )
56+ check_for_updates " $CURRENT_VERSION " &
57+ UPDATE_CHECK_PID=$!
58+
59+ # Cleanup and show update notification on exit
60+ show_update_notification () {
61+ # Wait briefly for background check (non-blocking if already done)
62+ wait " $UPDATE_CHECK_PID " 2> /dev/null || true
63+
64+ # Check if update is available
65+ if [[ -f " $UPDATE_CHECK_FILE " ]]; then
66+ local update_info
67+ update_info=$( cat " $UPDATE_CHECK_FILE " 2> /dev/null || true)
68+ rm -f " $UPDATE_CHECK_FILE " 2> /dev/null || true
69+
70+ if [[ " $update_info " == UPDATE_AVAILABLE= * ]]; then
71+ local new_version=" ${update_info# UPDATE_AVAILABLE=} "
72+ echo " "
73+ gum style --foreground 214 " A new release of git-wt is available: ${CURRENT_VERSION# v} → $new_version "
74+ echo " To upgrade, run: npm update -g git-wt"
75+ fi
76+ fi
77+ }
78+ trap show_update_notification EXIT
2479
2580show_help () {
2681 sed -n ' 2,17p' " $0 " | sed ' s/^# //' | sed ' s/^#//'
@@ -224,21 +279,27 @@ echo ""
224279gum style --bold " Git Worktree Selector"
225280echo " "
226281
227- # Get existing worktrees (excluding main)
282+ # Get existing worktrees (excluding main) and track their branches
228283WORKTREES=()
284+ declare -A WORKTREE_BRANCHES
229285while IFS= read -r line; do
230286 # Skip the main worktree
231287 if [[ " $line " != " $GIT_ROOT " ]]; then
232288 WORKTREES+=(" $line " )
289+ # Track which branch this worktree is on for deduplication
290+ local_branch=$( git -C " $line " branch --show-current 2> /dev/null || echo " " )
291+ if [[ -n " $local_branch " ]]; then
292+ WORKTREE_BRANCHES[" $local_branch " ]=1
293+ fi
233294 fi
234295done < <( git -C " $GIT_ROOT " worktree list --porcelain | grep " ^worktree " | cut -d' ' -f2-)
235296
236- # Build branch list from local branches only
297+ # Build branch list from local branches only (excluding branches with existing worktrees)
237298declare -A BRANCHES
238299
239300# Get local branches
240301while IFS= read -r branch; do
241- if [[ -n " $branch " ]]; then
302+ if [[ -n " $branch " ]] && [[ -z " ${WORKTREE_BRANCHES[$branch] :- } " ]] ; then
242303 BRANCHES[" $branch " ]=1
243304 fi
244305done < <( git -C " $GIT_ROOT " branch --format=' %(refname:short)' 2> /dev/null || echo " " )
261322# Add option to switch repo (step "up")
262323MENU_OPTIONS+=(" 🔄 (switch repository)" )
263324
264- # Show selection menu
265- SELECTED=$( printf ' %s\n' " ${MENU_OPTIONS[@]} " | gum filter --placeholder " Select or create worktree..." )
325+ # Show selection menu (--no-sort keeps existing worktrees at top while filtering)
326+ SELECTED=$( printf ' %s\n' " ${MENU_OPTIONS[@]} " | gum filter --no-sort -- placeholder " Select or create worktree..." )
266327
267328if [[ -z " $SELECTED " ]]; then
268329 echo " Cancelled"
0 commit comments