Skip to content

Commit d08efb7

Browse files
nsheapsclaude
andcommitted
feat: add background update check with notification
Checks GitHub API asynchronously on startup (2s timeout) and displays update notification on exit if a newer version is available, similar to gh CLI's update notice. Co-Authored-By: Claude Code (User Settings, in: ${CLAUDE_PROJECT_DIR}) <noreply@anthropic.com>
1 parent 0880ac1 commit d08efb7

1 file changed

Lines changed: 66 additions & 5 deletions

File tree

bin/git-wt

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,61 @@ set -euo pipefail
2121

2222
SCAN_DIR="${HOME}/src"
2323
TARGET_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

2580
show_help() {
2681
sed -n '2,17p' "$0" | sed 's/^# //' | sed 's/^#//'
@@ -224,21 +279,27 @@ echo ""
224279
gum style --bold "Git Worktree Selector"
225280
echo ""
226281

227-
# Get existing worktrees (excluding main)
282+
# Get existing worktrees (excluding main) and track their branches
228283
WORKTREES=()
284+
declare -A WORKTREE_BRANCHES
229285
while 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
234295
done < <(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)
237298
declare -A BRANCHES
238299

239300
# Get local branches
240301
while 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
244305
done < <(git -C "$GIT_ROOT" branch --format='%(refname:short)' 2>/dev/null || echo "")
@@ -261,8 +322,8 @@ done
261322
# Add option to switch repo (step "up")
262323
MENU_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

267328
if [[ -z "$SELECTED" ]]; then
268329
echo "Cancelled"

0 commit comments

Comments
 (0)