scripts: add claude-start/stop worktree wrappers #19
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Create (or reuse) a git worktree for the homelab repo and launch Claude Code in it.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/claude-start.sh <name> [base-branch] [-- <extra claude args>]
|
||||
#
|
||||
# Creates a sibling worktree at <parent>/homelab-<name> on a new branch <name>
|
||||
# (branched from <base-branch>, default: master), then runs `claude` inside it.
|
||||
# If the worktree already exists it is reused. Clean up afterwards with
|
||||
# scripts/claude-stop.sh <name>.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MAIN_REPO="$(dirname "$(git -C "$SCRIPT_DIR" rev-parse --path-format=absolute --git-common-dir)")"
|
||||
PARENT="$(dirname "$MAIN_REPO")"
|
||||
PREFIX="$(basename "$MAIN_REPO")"
|
||||
|
||||
command -v claude >/dev/null || { echo "claude CLI not found in PATH"; exit 1; }
|
||||
|
||||
NAME="${1:-}"
|
||||
[ -n "$NAME" ] || { echo "usage: $(basename "$0") <name> [base-branch] [-- <claude args>]"; exit 1; }
|
||||
shift
|
||||
|
||||
BASE_BRANCH="master"
|
||||
if [ $# -gt 0 ] && [ "$1" != "--" ]; then
|
||||
BASE_BRANCH="$1"; shift
|
||||
fi
|
||||
[ "${1:-}" = "--" ] && shift # drop the separator; remaining args are passed to claude
|
||||
|
||||
WORKTREE="$PARENT/$PREFIX-$NAME"
|
||||
BRANCH="$NAME"
|
||||
|
||||
if [ -d "$WORKTREE" ]; then
|
||||
echo "Reusing existing worktree: $WORKTREE"
|
||||
else
|
||||
echo "Creating worktree: $WORKTREE (branch: $BRANCH, base: $BASE_BRANCH)"
|
||||
git -C "$MAIN_REPO" fetch --quiet origin "$BASE_BRANCH" 2>/dev/null || true
|
||||
if git -C "$MAIN_REPO" show-ref --verify --quiet "refs/heads/$BRANCH"; then
|
||||
git -C "$MAIN_REPO" worktree add "$WORKTREE" "$BRANCH"
|
||||
else
|
||||
git -C "$MAIN_REPO" worktree add -b "$BRANCH" "$WORKTREE" "$BASE_BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Launching claude in $WORKTREE"
|
||||
cd "$WORKTREE"
|
||||
exec claude "$@"
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Remove a homelab worktree created by scripts/claude-start.sh.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/claude-stop.sh <name> [--force] [--delete-branch]
|
||||
#
|
||||
# Removes the sibling worktree <parent>/homelab-<name>. Refuses if the worktree
|
||||
# has uncommitted/untracked changes unless --force is given. With --delete-branch
|
||||
# the local branch <name> is also deleted (only if fully merged; combine with
|
||||
# --force to hard-delete an unmerged branch).
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
MAIN_REPO="$(dirname "$(git -C "$SCRIPT_DIR" rev-parse --path-format=absolute --git-common-dir)")"
|
||||
PARENT="$(dirname "$MAIN_REPO")"
|
||||
PREFIX="$(basename "$MAIN_REPO")"
|
||||
|
||||
NAME="${1:-}"
|
||||
[ -n "$NAME" ] || { echo "usage: $(basename "$0") <name> [--force] [--delete-branch]"; exit 1; }
|
||||
shift
|
||||
|
||||
FORCE=""
|
||||
DELETE_BRANCH=""
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--force) FORCE="--force" ;;
|
||||
--delete-branch) DELETE_BRANCH=1 ;;
|
||||
*) echo "unknown option: $arg"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
WORKTREE="$PARENT/$PREFIX-$NAME"
|
||||
BRANCH="$NAME"
|
||||
|
||||
[ -d "$WORKTREE" ] || { echo "no such worktree: $WORKTREE"; exit 1; }
|
||||
|
||||
echo "Removing worktree: $WORKTREE"
|
||||
git -C "$MAIN_REPO" worktree remove ${FORCE:+$FORCE} "$WORKTREE"
|
||||
git -C "$MAIN_REPO" worktree prune
|
||||
|
||||
if [ -n "$DELETE_BRANCH" ]; then
|
||||
if [ -n "$FORCE" ]; then
|
||||
echo "Deleting branch (force): $BRANCH"
|
||||
git -C "$MAIN_REPO" branch -D "$BRANCH"
|
||||
else
|
||||
echo "Deleting branch (if merged): $BRANCH"
|
||||
git -C "$MAIN_REPO" branch -d "$BRANCH"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Done."
|
||||
Reference in New Issue
Block a user